3
0
Fork 0
mirror of https://github.com/lubosz/overte.git synced 2025-04-27 13:55:26 +02:00

Merge pull request from birarda/master

make LibOVR (for oculus) an external dependency
This commit is contained in:
ZappoMan 2014-03-06 22:43:32 -08:00
commit 92d39b3c47
59 changed files with 48 additions and 15455 deletions

20
.gitignore vendored
View file

@ -28,22 +28,18 @@ DerivedData
*.hmap
#Ignore Leap, but not the stubs
interface/external/Leap/docs/
interface/external/Leap/include/
interface/external/Leap/lib/
interface/external/Leap/samples/
interface/external/Leap/util/
# ignore oculus
interface/external/oculus/*
!interface/external/oculus/readme.txt
# Ignore Sixense
interface/external/Sixense/include/
interface/external/Sixense/lib/
interface/external/Sixense/*
!interface/external/Sixense/readme.txt
# Ignore Visage
interface/external/visage/dependencies/
interface/external/visage/include/
interface/external/visage/lib/
interface/external/visage/*
!interface/external/visage/readme.txt
interface/resources/visage/
# Ignore interfaceCache for Linux users
interface/interfaceCache/
interface/interfaceCache/

View file

@ -16,19 +16,44 @@ if (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)
# in cache already
set(LIBOVR_FOUND TRUE)
else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS)
find_path(LIBOVR_INCLUDE_DIRS OVR.h ${LIBOVR_ROOT_DIR}/Include)
find_path(LIBOVR_INCLUDE_DIRS OVR.h "${LIBOVR_ROOT_DIR}/Include")
if (APPLE)
find_library(LIBOVR_LIBRARIES libovr.a ${LIBOVR_ROOT_DIR}/Lib/MacOS/)
find_library(LIBOVR_LIBRARIES libovr.a "${LIBOVR_ROOT_DIR}/Lib/MacOS/${CMAKE_BUILD_TYPE}/")
elseif (UNIX)
find_library(UDEV_LIBRARY libudev.a /usr/lib/x86_64-linux-gnu/)
find_library(XINERAMA_LIBRARY libXinerama.a /usr/lib/x86_64-linux-gnu/)
find_library(OVR_LIBRARY libovr.a ${LIBOVR_ROOT_DIR}/Lib/UNIX/)
if (CMAKE_CL_64)
set(LINUX_ARCH_DIR "i386")
else()
set(LINUX_ARCH_DIR "x86_64")
endif()
find_library(OVR_LIBRARY libovr.a "${LIBOVR_ROOT_DIR}/Lib/Linux/${CMAKE_BUILD_TYPE}/${LINUX_ARCH_DIR}/")
if (UDEV_LIBRARY AND XINERAMA_LIBRARY AND OVR_LIBRARY)
set(LIBOVR_LIBRARIES "${OVR_LIBRARY};${UDEV_LIBRARY};${XINERAMA_LIBRARY}" CACHE INTERNAL "Oculus libraries")
endif (UDEV_LIBRARY AND XINERAMA_LIBRARY AND OVR_LIBRARY)
elseif (WIN32)
find_library(LIBOVR_LIBRARIES libovr.lib ${LIBOVR_ROOT_DIR}/Lib/Win32/)
if (CMAKE_CL_64)
set(WINDOWS_ARCH_DIR "Win32")
if (CMAKE_BUILD_TYPE MATCHES DEBUG)
set(WINDOWS_LIBOVR_NAME "libovrd.lib")
else()
set(WINDOWS_LIBOVR_NAME "libovr.lib")
endif()
else()
set(WINDOWS_ARCH_DIR "x64")
if (CMAKE_BUILD_TYPE MATCHES DEBUG)
set(WINDOWS_LIBOVR_NAME "libovr64d.lib")
else()
set(WINDOWS_LIBOVR_NAME "libovr64.lib")
endif()
endif()
find_library(LIBOVR_LIBRARIES ${LIBOVR_NAME} "${LIBOVR_ROOT_DIR}/Lib/${WINDOWS_ARCH_DIR}/")
endif ()
if (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARIES)

View file

@ -9,7 +9,7 @@ project(${TARGET_NAME})
# setup for find modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/")
set(FACESHIFT_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/faceshift")
set(LIBOVR_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/LibOVR")
set(LIBOVR_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/oculus")
set(SIXENSE_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/Sixense")
set(VISAGE_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/visage")

View file

@ -1,33 +0,0 @@
/************************************************************************************
Filename : OVR.h
Content : This contains references to all OVR-specific headers in Src folder.
Should be generated automatically based on PublicHeader tags.
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_h
#define OVR_h
#include "../Src/Kernel/OVR_Allocator.h"
#include "../Src/Kernel/OVR_Log.h"
#include "../Src/Kernel/OVR_Math.h"
#include "../Src/Kernel/OVR_System.h"
#include "../Src/Kernel/OVR_Types.h"
#include "../Src/OVR_Device.h"
#include "../Src/OVR_DeviceConstants.h"
#include "../Src/OVR_DeviceHandle.h"
#include "../Src/OVR_DeviceMessages.h"
#include "../Src/OVR_SensorFusion.h"
#include "../Src/OVR_Profile.h"
#include "../Src/Util/Util_LatencyTest.h"
#include "../Src/Util/Util_Render_Stereo.h"
#endif

View file

@ -1,22 +0,0 @@
/************************************************************************************
Filename : OVRVersion.h
Content :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef _OVR_VERSION_H
#define _OVR_VERSION_H
#define OVR_MAJOR_VERSION 0
#define OVR_MINOR_VERSION 2
#define OVR_BUILD_VERSION 5
#define OVR_VERSION_STRING "0.2.5"
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,953 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_Alg.h
Content : Simple general purpose algorithms: Sort, Binary Search, etc.
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Alg_h
#define OVR_Alg_h
#include "OVR_Types.h"
#include <string.h>
namespace OVR { namespace Alg {
//-----------------------------------------------------------------------------------
// ***** Operator extensions
template <typename T> OVR_FORCE_INLINE void Swap(T &a, T &b)
{ T temp(a); a = b; b = temp; }
// ***** min/max are not implemented in Visual Studio 6 standard STL
template <typename T> OVR_FORCE_INLINE const T Min(const T a, const T b)
{ return (a < b) ? a : b; }
template <typename T> OVR_FORCE_INLINE const T Max(const T a, const T b)
{ return (b < a) ? a : b; }
template <typename T> OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal)
{ return Max<T>(minVal, Min<T>(v, maxVal)); }
template <typename T> OVR_FORCE_INLINE int Chop(T f)
{ return (int)f; }
template <typename T> OVR_FORCE_INLINE T Lerp(T a, T b, T f)
{ return (b - a) * f + a; }
// These functions stand to fix a stupid VC++ warning (with /Wp64 on):
// "warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned', possible loss of data"
// Use these functions instead of gmin/gmax if the argument has size
// of the pointer to avoid the warning. Though, functionally they are
// absolutelly the same as regular gmin/gmax.
template <typename T> OVR_FORCE_INLINE const T PMin(const T a, const T b)
{
OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt));
return (a < b) ? a : b;
}
template <typename T> OVR_FORCE_INLINE const T PMax(const T a, const T b)
{
OVR_COMPILER_ASSERT(sizeof(T) == sizeof(UPInt));
return (b < a) ? a : b;
}
template <typename T> OVR_FORCE_INLINE const T Abs(const T v)
{ return (v>=0) ? v : -v; }
//-----------------------------------------------------------------------------------
// ***** OperatorLess
//
template<class T> struct OperatorLess
{
static bool Compare(const T& a, const T& b)
{
return a < b;
}
};
//-----------------------------------------------------------------------------------
// ***** QuickSortSliced
//
// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
// The range is specified with start, end, where "end" is exclusive!
// The comparison predicate must be specified.
template<class Array, class Less>
void QuickSortSliced(Array& arr, UPInt start, UPInt end, Less less)
{
enum
{
Threshold = 9
};
if(end - start < 2) return;
SPInt stack[80];
SPInt* top = stack;
SPInt base = (SPInt)start;
SPInt limit = (SPInt)end;
for(;;)
{
SPInt len = limit - base;
SPInt i, j, pivot;
if(len > Threshold)
{
// we use base + len/2 as the pivot
pivot = base + len / 2;
Swap(arr[base], arr[pivot]);
i = base + 1;
j = limit - 1;
// now ensure that *i <= *base <= *j
if(less(arr[j], arr[i])) Swap(arr[j], arr[i]);
if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
for(;;)
{
do i++; while( less(arr[i], arr[base]) );
do j--; while( less(arr[base], arr[j]) );
if( i > j )
{
break;
}
Swap(arr[i], arr[j]);
}
Swap(arr[base], arr[j]);
// now, push the largest sub-array
if(j - base > limit - i)
{
top[0] = base;
top[1] = j;
base = i;
}
else
{
top[0] = i;
top[1] = limit;
limit = j;
}
top += 2;
}
else
{
// the sub-array is small, perform insertion sort
j = base;
i = j + 1;
for(; i < limit; j = i, i++)
{
for(; less(arr[j + 1], arr[j]); j--)
{
Swap(arr[j + 1], arr[j]);
if(j == base)
{
break;
}
}
}
if(top > stack)
{
top -= 2;
base = top[0];
limit = top[1];
}
else
{
break;
}
}
}
}
//-----------------------------------------------------------------------------------
// ***** QuickSortSliced
//
// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
// The range is specified with start, end, where "end" is exclusive!
// The data type must have a defined "<" operator.
template<class Array>
void QuickSortSliced(Array& arr, UPInt start, UPInt end)
{
typedef typename Array::ValueType ValueType;
QuickSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
}
// Same as corresponding G_QuickSortSliced but with checking array limits to avoid
// crash in the case of wrong comparator functor.
template<class Array, class Less>
bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end, Less less)
{
enum
{
Threshold = 9
};
if(end - start < 2) return true;
SPInt stack[80];
SPInt* top = stack;
SPInt base = (SPInt)start;
SPInt limit = (SPInt)end;
for(;;)
{
SPInt len = limit - base;
SPInt i, j, pivot;
if(len > Threshold)
{
// we use base + len/2 as the pivot
pivot = base + len / 2;
Swap(arr[base], arr[pivot]);
i = base + 1;
j = limit - 1;
// now ensure that *i <= *base <= *j
if(less(arr[j], arr[i])) Swap(arr[j], arr[i]);
if(less(arr[base], arr[i])) Swap(arr[base], arr[i]);
if(less(arr[j], arr[base])) Swap(arr[j], arr[base]);
for(;;)
{
do
{
i++;
if (i >= limit)
return false;
} while( less(arr[i], arr[base]) );
do
{
j--;
if (j < 0)
return false;
} while( less(arr[base], arr[j]) );
if( i > j )
{
break;
}
Swap(arr[i], arr[j]);
}
Swap(arr[base], arr[j]);
// now, push the largest sub-array
if(j - base > limit - i)
{
top[0] = base;
top[1] = j;
base = i;
}
else
{
top[0] = i;
top[1] = limit;
limit = j;
}
top += 2;
}
else
{
// the sub-array is small, perform insertion sort
j = base;
i = j + 1;
for(; i < limit; j = i, i++)
{
for(; less(arr[j + 1], arr[j]); j--)
{
Swap(arr[j + 1], arr[j]);
if(j == base)
{
break;
}
}
}
if(top > stack)
{
top -= 2;
base = top[0];
limit = top[1];
}
else
{
break;
}
}
}
return true;
}
template<class Array>
bool QuickSortSlicedSafe(Array& arr, UPInt start, UPInt end)
{
typedef typename Array::ValueType ValueType;
return QuickSortSlicedSafe(arr, start, end, OperatorLess<ValueType>::Compare);
}
//-----------------------------------------------------------------------------------
// ***** QuickSort
//
// Sort an array Array, ArrayPaged, ArrayUnsafe.
// The array must have GetSize() function.
// The comparison predicate must be specified.
template<class Array, class Less>
void QuickSort(Array& arr, Less less)
{
QuickSortSliced(arr, 0, arr.GetSize(), less);
}
// checks for boundaries
template<class Array, class Less>
bool QuickSortSafe(Array& arr, Less less)
{
return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less);
}
//-----------------------------------------------------------------------------------
// ***** QuickSort
//
// Sort an array Array, ArrayPaged, ArrayUnsafe.
// The array must have GetSize() function.
// The data type must have a defined "<" operator.
template<class Array>
void QuickSort(Array& arr)
{
typedef typename Array::ValueType ValueType;
QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
}
template<class Array>
bool QuickSortSafe(Array& arr)
{
typedef typename Array::ValueType ValueType;
return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
}
//-----------------------------------------------------------------------------------
// ***** InsertionSortSliced
//
// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
// The range is specified with start, end, where "end" is exclusive!
// The comparison predicate must be specified.
// Unlike Quick Sort, the Insertion Sort works much slower in average,
// but may be much faster on almost sorted arrays. Besides, it guarantees
// that the elements will not be swapped if not necessary. For example,
// an array with all equal elements will remain "untouched", while
// Quick Sort will considerably shuffle the elements in this case.
template<class Array, class Less>
void InsertionSortSliced(Array& arr, UPInt start, UPInt end, Less less)
{
UPInt j = start;
UPInt i = j + 1;
UPInt limit = end;
for(; i < limit; j = i, i++)
{
for(; less(arr[j + 1], arr[j]); j--)
{
Swap(arr[j + 1], arr[j]);
if(j <= start)
{
break;
}
}
}
}
//-----------------------------------------------------------------------------------
// ***** InsertionSortSliced
//
// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe.
// The range is specified with start, end, where "end" is exclusive!
// The data type must have a defined "<" operator.
template<class Array>
void InsertionSortSliced(Array& arr, UPInt start, UPInt end)
{
typedef typename Array::ValueType ValueType;
InsertionSortSliced(arr, start, end, OperatorLess<ValueType>::Compare);
}
//-----------------------------------------------------------------------------------
// ***** InsertionSort
//
// Sort an array Array, ArrayPaged, ArrayUnsafe.
// The array must have GetSize() function.
// The comparison predicate must be specified.
template<class Array, class Less>
void InsertionSort(Array& arr, Less less)
{
InsertionSortSliced(arr, 0, arr.GetSize(), less);
}
//-----------------------------------------------------------------------------------
// ***** InsertionSort
//
// Sort an array Array, ArrayPaged, ArrayUnsafe.
// The array must have GetSize() function.
// The data type must have a defined "<" operator.
template<class Array>
void InsertionSort(Array& arr)
{
typedef typename Array::ValueType ValueType;
InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
}
//-----------------------------------------------------------------------------------
// ***** LowerBoundSliced
//
template<class Array, class Value, class Less>
UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less)
{
SPInt first = (SPInt)start;
SPInt len = (SPInt)(end - start);
SPInt half;
SPInt middle;
while(len > 0)
{
half = len >> 1;
middle = first + half;
if(less(arr[middle], val))
{
first = middle + 1;
len = len - half - 1;
}
else
{
len = half;
}
}
return (UPInt)first;
}
//-----------------------------------------------------------------------------------
// ***** LowerBoundSliced
//
template<class Array, class Value>
UPInt LowerBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val)
{
return LowerBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
}
//-----------------------------------------------------------------------------------
// ***** LowerBoundSized
//
template<class Array, class Value>
UPInt LowerBoundSized(const Array& arr, UPInt size, const Value& val)
{
return LowerBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
}
//-----------------------------------------------------------------------------------
// ***** LowerBound
//
template<class Array, class Value, class Less>
UPInt LowerBound(const Array& arr, const Value& val, Less less)
{
return LowerBoundSliced(arr, 0, arr.GetSize(), val, less);
}
//-----------------------------------------------------------------------------------
// ***** LowerBound
//
template<class Array, class Value>
UPInt LowerBound(const Array& arr, const Value& val)
{
return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
}
//-----------------------------------------------------------------------------------
// ***** UpperBoundSliced
//
template<class Array, class Value, class Less>
UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val, Less less)
{
SPInt first = (SPInt)start;
SPInt len = (SPInt)(end - start);
SPInt half;
SPInt middle;
while(len > 0)
{
half = len >> 1;
middle = first + half;
if(less(val, arr[middle]))
{
len = half;
}
else
{
first = middle + 1;
len = len - half - 1;
}
}
return (UPInt)first;
}
//-----------------------------------------------------------------------------------
// ***** UpperBoundSliced
//
template<class Array, class Value>
UPInt UpperBoundSliced(const Array& arr, UPInt start, UPInt end, const Value& val)
{
return UpperBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare);
}
//-----------------------------------------------------------------------------------
// ***** UpperBoundSized
//
template<class Array, class Value>
UPInt UpperBoundSized(const Array& arr, UPInt size, const Value& val)
{
return UpperBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare);
}
//-----------------------------------------------------------------------------------
// ***** UpperBound
//
template<class Array, class Value, class Less>
UPInt UpperBound(const Array& arr, const Value& val, Less less)
{
return UpperBoundSliced(arr, 0, arr.GetSize(), val, less);
}
//-----------------------------------------------------------------------------------
// ***** UpperBound
//
template<class Array, class Value>
UPInt UpperBound(const Array& arr, const Value& val)
{
return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare);
}
//-----------------------------------------------------------------------------------
// ***** ReverseArray
//
template<class Array> void ReverseArray(Array& arr)
{
SPInt from = 0;
SPInt to = arr.GetSize() - 1;
while(from < to)
{
Swap(arr[from], arr[to]);
++from;
--to;
}
}
// ***** AppendArray
//
template<class CDst, class CSrc>
void AppendArray(CDst& dst, const CSrc& src)
{
UPInt i;
for(i = 0; i < src.GetSize(); i++)
dst.PushBack(src[i]);
}
//-----------------------------------------------------------------------------------
// ***** ArrayAdaptor
//
// A simple adapter that provides the GetSize() method and overloads
// operator []. Used to wrap plain arrays in QuickSort and such.
template<class T> class ArrayAdaptor
{
public:
typedef T ValueType;
ArrayAdaptor() : Data(0), Size(0) {}
ArrayAdaptor(T* ptr, UPInt size) : Data(ptr), Size(size) {}
UPInt GetSize() const { return Size; }
const T& operator [] (UPInt i) const { return Data[i]; }
T& operator [] (UPInt i) { return Data[i]; }
private:
T* Data;
UPInt Size;
};
//-----------------------------------------------------------------------------------
// ***** GConstArrayAdaptor
//
// A simple const adapter that provides the GetSize() method and overloads
// operator []. Used to wrap plain arrays in LowerBound and such.
template<class T> class ConstArrayAdaptor
{
public:
typedef T ValueType;
ConstArrayAdaptor() : Data(0), Size(0) {}
ConstArrayAdaptor(const T* ptr, UPInt size) : Data(ptr), Size(size) {}
UPInt GetSize() const { return Size; }
const T& operator [] (UPInt i) const { return Data[i]; }
private:
const T* Data;
UPInt Size;
};
//-----------------------------------------------------------------------------------
extern const UByte UpperBitTable[256];
extern const UByte LowerBitTable[256];
//-----------------------------------------------------------------------------------
inline UByte UpperBit(UPInt val)
{
#ifndef OVR_64BIT_POINTERS
if (val & 0xFFFF0000)
{
return (val & 0xFF000000) ?
UpperBitTable[(val >> 24) ] + 24:
UpperBitTable[(val >> 16) & 0xFF] + 16;
}
return (val & 0xFF00) ?
UpperBitTable[(val >> 8) & 0xFF] + 8:
UpperBitTable[(val ) & 0xFF];
#else
if (val & 0xFFFFFFFF00000000)
{
if (val & 0xFFFF000000000000)
{
return (val & 0xFF00000000000000) ?
UpperBitTable[(val >> 56) ] + 56:
UpperBitTable[(val >> 48) & 0xFF] + 48;
}
return (val & 0xFF0000000000) ?
UpperBitTable[(val >> 40) & 0xFF] + 40:
UpperBitTable[(val >> 32) & 0xFF] + 32;
}
else
{
if (val & 0xFFFF0000)
{
return (val & 0xFF000000) ?
UpperBitTable[(val >> 24) ] + 24:
UpperBitTable[(val >> 16) & 0xFF] + 16;
}
return (val & 0xFF00) ?
UpperBitTable[(val >> 8) & 0xFF] + 8:
UpperBitTable[(val ) & 0xFF];
}
#endif
}
//-----------------------------------------------------------------------------------
inline UByte LowerBit(UPInt val)
{
#ifndef OVR_64BIT_POINTERS
if (val & 0xFFFF)
{
return (val & 0xFF) ?
LowerBitTable[ val & 0xFF]:
LowerBitTable[(val >> 8) & 0xFF] + 8;
}
return (val & 0xFF0000) ?
LowerBitTable[(val >> 16) & 0xFF] + 16:
LowerBitTable[(val >> 24) & 0xFF] + 24;
#else
if (val & 0xFFFFFFFF)
{
if (val & 0xFFFF)
{
return (val & 0xFF) ?
LowerBitTable[ val & 0xFF]:
LowerBitTable[(val >> 8) & 0xFF] + 8;
}
return (val & 0xFF0000) ?
LowerBitTable[(val >> 16) & 0xFF] + 16:
LowerBitTable[(val >> 24) & 0xFF] + 24;
}
else
{
if (val & 0xFFFF00000000)
{
return (val & 0xFF00000000) ?
LowerBitTable[(val >> 32) & 0xFF] + 32:
LowerBitTable[(val >> 40) & 0xFF] + 40;
}
return (val & 0xFF000000000000) ?
LowerBitTable[(val >> 48) & 0xFF] + 48:
LowerBitTable[(val >> 56) & 0xFF] + 56;
}
#endif
}
// ******* Special (optimized) memory routines
// Note: null (bad) pointer is not tested
class MemUtil
{
public:
// Memory compare
static int Cmp (const void* p1, const void* p2, UPInt byteCount) { return memcmp(p1, p2, byteCount); }
static int Cmp16(const void* p1, const void* p2, UPInt int16Count);
static int Cmp32(const void* p1, const void* p2, UPInt int32Count);
static int Cmp64(const void* p1, const void* p2, UPInt int64Count);
};
// ** Inline Implementation
inline int MemUtil::Cmp16(const void* p1, const void* p2, UPInt int16Count)
{
SInt16* pa = (SInt16*)p1;
SInt16* pb = (SInt16*)p2;
unsigned ic = 0;
if (int16Count == 0)
return 0;
while (pa[ic] == pb[ic])
if (++ic==int16Count)
return 0;
return pa[ic] > pb[ic] ? 1 : -1;
}
inline int MemUtil::Cmp32(const void* p1, const void* p2, UPInt int32Count)
{
SInt32* pa = (SInt32*)p1;
SInt32* pb = (SInt32*)p2;
unsigned ic = 0;
if (int32Count == 0)
return 0;
while (pa[ic] == pb[ic])
if (++ic==int32Count)
return 0;
return pa[ic] > pb[ic] ? 1 : -1;
}
inline int MemUtil::Cmp64(const void* p1, const void* p2, UPInt int64Count)
{
SInt64* pa = (SInt64*)p1;
SInt64* pb = (SInt64*)p2;
unsigned ic = 0;
if (int64Count == 0)
return 0;
while (pa[ic] == pb[ic])
if (++ic==int64Count)
return 0;
return pa[ic] > pb[ic] ? 1 : -1;
}
// ** End Inline Implementation
//-----------------------------------------------------------------------------------
// ******* Byte Order Conversions
namespace ByteUtil {
// *** Swap Byte Order
// Swap the byte order of a byte array
inline void SwapOrder(void* pv, int size)
{
UByte* pb = (UByte*)pv;
UByte temp;
for (int i = 0; i < size>>1; i++)
{
temp = pb[size-1-i];
pb[size-1-i] = pb[i];
pb[i] = temp;
}
}
// Swap the byte order of primitive types
inline UByte SwapOrder(UByte v) { return v; }
inline SByte SwapOrder(SByte v) { return v; }
inline UInt16 SwapOrder(UInt16 v) { return UInt16(v>>8)|UInt16(v<<8); }
inline SInt16 SwapOrder(SInt16 v) { return SInt16((UInt16(v)>>8)|(v<<8)); }
inline UInt32 SwapOrder(UInt32 v) { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); }
inline SInt32 SwapOrder(SInt32 p) { return (SInt32)SwapOrder(UInt32(p)); }
inline UInt64 SwapOrder(UInt64 v)
{
return (v>>56) |
((v&UInt64(0x00FF000000000000))>>40) |
((v&UInt64(0x0000FF0000000000))>>24) |
((v&UInt64(0x000000FF00000000))>>8) |
((v&UInt64(0x00000000FF000000))<<8) |
((v&UInt64(0x0000000000FF0000))<<24) |
((v&UInt64(0x000000000000FF00))<<40) |
(v<<56);
}
inline SInt64 SwapOrder(SInt64 v) { return (SInt64)SwapOrder(UInt64(v)); }
inline float SwapOrder(float p)
{
union {
float p;
UInt32 v;
} u;
u.p = p;
u.v = SwapOrder(u.v);
return u.p;
}
inline double SwapOrder(double p)
{
union {
double p;
UInt64 v;
} u;
u.p = p;
u.v = SwapOrder(u.v);
return u.p;
}
// *** Byte-order conversion
#if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN)
// Little Endian to System (LE)
inline UByte LEToSystem(UByte v) { return v; }
inline SByte LEToSystem(SByte v) { return v; }
inline UInt16 LEToSystem(UInt16 v) { return v; }
inline SInt16 LEToSystem(SInt16 v) { return v; }
inline UInt32 LEToSystem(UInt32 v) { return v; }
inline SInt32 LEToSystem(SInt32 v) { return v; }
inline UInt64 LEToSystem(UInt64 v) { return v; }
inline SInt64 LEToSystem(SInt64 v) { return v; }
inline float LEToSystem(float v) { return v; }
inline double LEToSystem(double v) { return v; }
// Big Endian to System (LE)
inline UByte BEToSystem(UByte v) { return SwapOrder(v); }
inline SByte BEToSystem(SByte v) { return SwapOrder(v); }
inline UInt16 BEToSystem(UInt16 v) { return SwapOrder(v); }
inline SInt16 BEToSystem(SInt16 v) { return SwapOrder(v); }
inline UInt32 BEToSystem(UInt32 v) { return SwapOrder(v); }
inline SInt32 BEToSystem(SInt32 v) { return SwapOrder(v); }
inline UInt64 BEToSystem(UInt64 v) { return SwapOrder(v); }
inline SInt64 BEToSystem(SInt64 v) { return SwapOrder(v); }
inline float BEToSystem(float v) { return SwapOrder(v); }
inline double BEToSystem(double v) { return SwapOrder(v); }
// System (LE) to Little Endian
inline UByte SystemToLE(UByte v) { return v; }
inline SByte SystemToLE(SByte v) { return v; }
inline UInt16 SystemToLE(UInt16 v) { return v; }
inline SInt16 SystemToLE(SInt16 v) { return v; }
inline UInt32 SystemToLE(UInt32 v) { return v; }
inline SInt32 SystemToLE(SInt32 v) { return v; }
inline UInt64 SystemToLE(UInt64 v) { return v; }
inline SInt64 SystemToLE(SInt64 v) { return v; }
inline float SystemToLE(float v) { return v; }
inline double SystemToLE(double v) { return v; }
// System (LE) to Big Endian
inline UByte SystemToBE(UByte v) { return SwapOrder(v); }
inline SByte SystemToBE(SByte v) { return SwapOrder(v); }
inline UInt16 SystemToBE(UInt16 v) { return SwapOrder(v); }
inline SInt16 SystemToBE(SInt16 v) { return SwapOrder(v); }
inline UInt32 SystemToBE(UInt32 v) { return SwapOrder(v); }
inline SInt32 SystemToBE(SInt32 v) { return SwapOrder(v); }
inline UInt64 SystemToBE(UInt64 v) { return SwapOrder(v); }
inline SInt64 SystemToBE(SInt64 v) { return SwapOrder(v); }
inline float SystemToBE(float v) { return SwapOrder(v); }
inline double SystemToBE(double v) { return SwapOrder(v); }
#elif (OVR_BYTE_ORDER == OVR_BIG_ENDIAN)
// Little Endian to System (BE)
inline UByte LEToSystem(UByte v) { return SwapOrder(v); }
inline SByte LEToSystem(SByte v) { return SwapOrder(v); }
inline UInt16 LEToSystem(UInt16 v) { return SwapOrder(v); }
inline SInt16 LEToSystem(SInt16 v) { return SwapOrder(v); }
inline UInt32 LEToSystem(UInt32 v) { return SwapOrder(v); }
inline SInt32 LEToSystem(SInt32 v) { return SwapOrder(v); }
inline UInt64 LEToSystem(UInt64 v) { return SwapOrder(v); }
inline SInt64 LEToSystem(SInt64 v) { return SwapOrder(v); }
inline float LEToSystem(float v) { return SwapOrder(v); }
inline double LEToSystem(double v) { return SwapOrder(v); }
// Big Endian to System (BE)
inline UByte BEToSystem(UByte v) { return v; }
inline SByte BEToSystem(SByte v) { return v; }
inline UInt16 BEToSystem(UInt16 v) { return v; }
inline SInt16 BEToSystem(SInt16 v) { return v; }
inline UInt32 BEToSystem(UInt32 v) { return v; }
inline SInt32 BEToSystem(SInt32 v) { return v; }
inline UInt64 BEToSystem(UInt64 v) { return v; }
inline SInt64 BEToSystem(SInt64 v) { return v; }
inline float BEToSystem(float v) { return v; }
inline double BEToSystem(double v) { return v; }
// System (BE) to Little Endian
inline UByte SystemToLE(UByte v) { return SwapOrder(v); }
inline SByte SystemToLE(SByte v) { return SwapOrder(v); }
inline UInt16 SystemToLE(UInt16 v) { return SwapOrder(v); }
inline SInt16 SystemToLE(SInt16 v) { return SwapOrder(v); }
inline UInt32 SystemToLE(UInt32 v) { return SwapOrder(v); }
inline SInt32 SystemToLE(SInt32 v) { return SwapOrder(v); }
inline UInt64 SystemToLE(UInt64 v) { return SwapOrder(v); }
inline SInt64 SystemToLE(SInt64 v) { return SwapOrder(v); }
inline float SystemToLE(float v) { return SwapOrder(v); }
inline double SystemToLE(double v) { return SwapOrder(v); }
// System (BE) to Big Endian
inline UByte SystemToBE(UByte v) { return v; }
inline SByte SystemToBE(SByte v) { return v; }
inline UInt16 SystemToBE(UInt16 v) { return v; }
inline SInt16 SystemToBE(SInt16 v) { return v; }
inline UInt32 SystemToBE(UInt32 v) { return v; }
inline SInt32 SystemToBE(SInt32 v) { return v; }
inline UInt64 SystemToBE(UInt64 v) { return v; }
inline SInt64 SystemToBE(SInt64 v) { return v; }
inline float SystemToBE(float v) { return v; }
inline double SystemToBE(double v) { return v; }
#else
#error "OVR_BYTE_ORDER must be defined to OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN"
#endif
} // namespace ByteUtil
}} // OVR::Alg
#endif

View file

@ -1,336 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_Allocator.h
Content : Installable memory allocator
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Allocator_h
#define OVR_Allocator_h
#include "OVR_Types.h"
//-----------------------------------------------------------------------------------
// ***** Disable template-unfriendly MS VC++ warnings
#if defined(OVR_CC_MSVC)
// Pragma to prevent long name warnings in in VC++
#pragma warning(disable : 4503)
#pragma warning(disable : 4786)
// In MSVC 7.1, warning about placement new POD default initializer
#pragma warning(disable : 4345)
#endif
// Un-define new so that placement constructors work
#undef new
//-----------------------------------------------------------------------------------
// ***** Placement new overrides
// Calls constructor on own memory created with "new(ptr) type"
#ifndef __PLACEMENT_NEW_INLINE
#define __PLACEMENT_NEW_INLINE
# if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU)
# include <new>
# else
// Useful on MSVC
OVR_FORCE_INLINE void* operator new (OVR::UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; }
OVR_FORCE_INLINE void operator delete (void *, void *) { }
# endif
#endif // __PLACEMENT_NEW_INLINE
//------------------------------------------------------------------------
// ***** Macros to redefine class new/delete operators
// Types specifically declared to allow disambiguation of address in
// class member operator new.
#define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete) \
void* operator new(UPInt sz) \
{ void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; } \
void* operator new(UPInt sz, const char* file, int line) \
{ void* p = OVR_ALLOC_DEBUG(sz, file, line); OVR_UNUSED2(file, line); return p; } \
void operator delete(void *p) \
{ check_delete(class_name, p); OVR_FREE(p); } \
void operator delete(void *p, const char*, int) \
{ check_delete(class_name, p); OVR_FREE(p); }
#define OVR_MEMORY_DEFINE_PLACEMENT_NEW \
void* operator new (UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; } \
void operator delete (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); }
#define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p)
// Redefined all delete/new operators in a class without custom memory initialization
#define OVR_MEMORY_REDEFINE_NEW(class_name) \
OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE)
namespace OVR {
//-----------------------------------------------------------------------------------
// ***** Construct / Destruct
// Construct/Destruct functions are useful when new is redefined, as they can
// be called instead of placement new constructors.
template <class T>
OVR_FORCE_INLINE T* Construct(void *p)
{
return ::new(p) T;
}
template <class T>
OVR_FORCE_INLINE T* Construct(void *p, const T& source)
{
return ::new(p) T(source);
}
// Same as above, but allows for a different type of constructor.
template <class T, class S>
OVR_FORCE_INLINE T* ConstructAlt(void *p, const S& source)
{
return ::new(p) T(source);
}
template <class T, class S1, class S2>
OVR_FORCE_INLINE T* ConstructAlt(void *p, const S1& src1, const S2& src2)
{
return ::new(p) T(src1, src2);
}
template <class T>
OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count)
{
UByte *pdata = (UByte*)p;
for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
{
Construct<T>(pdata);
}
}
template <class T>
OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count, const T& source)
{
UByte *pdata = (UByte*)p;
for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
{
Construct<T>(pdata, source);
}
}
template <class T>
OVR_FORCE_INLINE void Destruct(T *pobj)
{
pobj->~T();
OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning.
}
template <class T>
OVR_FORCE_INLINE void DestructArray(T *pobj, UPInt count)
{
for (UPInt i=0; i<count; ++i, ++pobj)
pobj->~T();
}
//-----------------------------------------------------------------------------------
// ***** Allocator
// Allocator defines a memory allocation interface that developers can override
// to to provide memory for OVR; an instance of this class is typically created on
// application startup and passed into System or OVR::System constructor.
//
//
// Users implementing this interface must provide three functions: Alloc, Free,
// and Realloc. Implementations of these functions must honor the requested alignment.
// Although arbitrary alignment requests are possible, requested alignment will
// typically be small, such as 16 bytes or less.
class Allocator
{
friend class System;
public:
// *** Standard Alignment Alloc/Free
// Allocate memory of specified size with default alignment.
// Alloc of size==0 will allocate a tiny block & return a valid pointer;
// this makes it suitable for new operator.
virtual void* Alloc(UPInt size) = 0;
// Same as Alloc, but provides an option of passing debug data.
virtual void* AllocDebug(UPInt size, const char* file, unsigned line)
{ OVR_UNUSED2(file, line); return Alloc(size); }
// Reallocate memory block to a new size, copying data if necessary. Returns the pointer to
// new memory block, which may be the same as original pointer. Will return 0 if reallocation
// failed, in which case previous memory is still valid.
// Realloc to decrease size will never fail.
// Realloc of pointer == 0 is equivalent to Alloc
// Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free().
virtual void* Realloc(void* p, UPInt newSize) = 0;
// Frees memory allocated by Alloc/Realloc.
// Free of null pointer is valid and will do nothing.
virtual void Free(void *p) = 0;
// *** Standard Alignment Alloc/Free
// Allocate memory of specified alignment.
// Memory allocated with AllocAligned MUST be freed with FreeAligned.
// Default implementation will delegate to Alloc/Free after doing rounding.
virtual void* AllocAligned(UPInt size, UPInt align);
// Frees memory allocated with AllocAligned.
virtual void FreeAligned(void* p);
// Returns the pointer to the current globally installed Allocator instance.
// This pointer is used for most of the memory allocations.
static Allocator* GetInstance() { return pInstance; }
protected:
// onSystemShutdown is called on the allocator during System::Shutdown.
// At this point, all allocations should've been freed.
virtual void onSystemShutdown() { }
public:
static void setInstance(Allocator* palloc)
{
OVR_ASSERT((pInstance == 0) || (palloc == 0));
pInstance = palloc;
}
private:
static Allocator* pInstance;
};
//------------------------------------------------------------------------
// ***** Allocator_SingletonSupport
// Allocator_SingletonSupport is a Allocator wrapper class that implements
// the InitSystemSingleton static function, used to create a global singleton
// used for the OVR::System default argument initialization.
//
// End users implementing custom Allocator interface don't need to make use of this base
// class; they can just create an instance of their own class on stack and pass it to System.
template<class D>
class Allocator_SingletonSupport : public Allocator
{
struct AllocContainer
{
UPInt Data[(sizeof(D) + sizeof(UPInt)-1) / sizeof(UPInt)];
bool Initialized;
AllocContainer() : Initialized(0) { }
};
AllocContainer* pContainer;
public:
Allocator_SingletonSupport() : pContainer(0) { }
// Creates a singleton instance of this Allocator class used
// on OVR_DEFAULT_ALLOCATOR during System initialization.
static D* InitSystemSingleton()
{
static AllocContainer Container;
OVR_ASSERT(Container.Initialized == false);
Allocator_SingletonSupport<D> *presult = Construct<D>((void*)Container.Data);
presult->pContainer = &Container;
Container.Initialized = true;
return (D*)presult;
}
protected:
virtual void onSystemShutdown()
{
Allocator::onSystemShutdown();
if (pContainer)
{
pContainer->Initialized = false;
Destruct((D*)this);
pContainer = 0;
}
}
};
//------------------------------------------------------------------------
// ***** Default Allocator
// This allocator is created and used if no other allocator is installed.
// Default allocator delegates to system malloc.
class DefaultAllocator : public Allocator_SingletonSupport<DefaultAllocator>
{
public:
virtual void* Alloc(UPInt size);
virtual void* AllocDebug(UPInt size, const char* file, unsigned line);
virtual void* Realloc(void* p, UPInt newSize);
virtual void Free(void *p);
};
//------------------------------------------------------------------------
// ***** Memory Allocation Macros
// These macros should be used for global allocation. In the future, these
// macros will allows allocation to be extended with debug file/line information
// if necessary.
#define OVR_REALLOC(p,s) OVR::Allocator::GetInstance()->Realloc((p),(s))
#define OVR_FREE(p) OVR::Allocator::GetInstance()->Free((p))
#define OVR_ALLOC_ALIGNED(s,a) OVR::Allocator::GetInstance()->AllocAligned((s),(a))
#define OVR_FREE_ALIGNED(p) OVR::Allocator::GetInstance()->FreeAligned((p))
#ifdef OVR_BUILD_DEBUG
#define OVR_ALLOC(s) OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__)
#define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->AllocDebug((s), f, l)
#else
#define OVR_ALLOC(s) OVR::Allocator::GetInstance()->Alloc((s))
#define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->Alloc((s))
#endif
//------------------------------------------------------------------------
// Base class that overrides the new and delete operators.
// Deriving from this class, even as a multiple base, incurs no space overhead.
class NewOverrideBase
{
public:
// Redefine all new & delete operators.
OVR_MEMORY_REDEFINE_NEW(NewOverrideBase)
};
} // OVR
// Redefine operator 'new' if necessary.
#if defined(OVR_DEFINE_NEW)
#define new OVR_DEFINE_NEW
#endif
#endif // OVR_Memory

View file

@ -1,793 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_Array.h
Content : Template implementation for Array
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Array_h
#define OVR_Array_h
#include "OVR_ContainerAllocator.h"
namespace OVR {
//-----------------------------------------------------------------------------------
// ***** ArrayDefaultPolicy
//
// Default resize behavior. No minimal capacity, Granularity=4,
// Shrinking as needed. ArrayConstPolicy actually is the same as
// ArrayDefaultPolicy, but parametrized with constants.
// This struct is used only in order to reduce the template "matroska".
struct ArrayDefaultPolicy
{
ArrayDefaultPolicy() : Capacity(0) {}
ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {}
UPInt GetMinCapacity() const { return 0; }
UPInt GetGranularity() const { return 4; }
bool NeverShrinking() const { return 0; }
UPInt GetCapacity() const { return Capacity; }
void SetCapacity(UPInt capacity) { Capacity = capacity; }
private:
UPInt Capacity;
};
//-----------------------------------------------------------------------------------
// ***** ArrayConstPolicy
//
// Statically parametrized resizing behavior:
// MinCapacity, Granularity, and Shrinking flag.
template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false>
struct ArrayConstPolicy
{
typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType;
ArrayConstPolicy() : Capacity(0) {}
ArrayConstPolicy(const SelfType&) : Capacity(0) {}
UPInt GetMinCapacity() const { return MinCapacity; }
UPInt GetGranularity() const { return Granularity; }
bool NeverShrinking() const { return NeverShrink; }
UPInt GetCapacity() const { return Capacity; }
void SetCapacity(UPInt capacity) { Capacity = capacity; }
private:
UPInt Capacity;
};
//-----------------------------------------------------------------------------------
// ***** ArrayDataBase
//
// Basic operations with array data: Reserve, Resize, Free, ArrayPolicy.
// For internal use only: ArrayData,ArrayDataCC and others.
template<class T, class Allocator, class SizePolicy>
struct ArrayDataBase
{
typedef T ValueType;
typedef Allocator AllocatorType;
typedef SizePolicy SizePolicyType;
typedef ArrayDataBase<T, Allocator, SizePolicy> SelfType;
ArrayDataBase()
: Data(0), Size(0), Policy() {}
ArrayDataBase(const SizePolicy& p)
: Data(0), Size(0), Policy(p) {}
~ArrayDataBase()
{
Allocator::DestructArray(Data, Size);
Allocator::Free(Data);
}
UPInt GetCapacity() const
{
return Policy.GetCapacity();
}
void ClearAndRelease()
{
Allocator::DestructArray(Data, Size);
Allocator::Free(Data);
Data = 0;
Size = 0;
Policy.SetCapacity(0);
}
void Reserve(UPInt newCapacity)
{
if (Policy.NeverShrinking() && newCapacity < GetCapacity())
return;
if (newCapacity < Policy.GetMinCapacity())
newCapacity = Policy.GetMinCapacity();
// Resize the buffer.
if (newCapacity == 0)
{
if (Data)
{
Allocator::Free(Data);
Data = 0;
}
Policy.SetCapacity(0);
}
else
{
UPInt gran = Policy.GetGranularity();
newCapacity = (newCapacity + gran - 1) / gran * gran;
if (Data)
{
if (Allocator::IsMovable())
{
Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity);
}
else
{
T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
UPInt i, s;
s = (Size < newCapacity) ? Size : newCapacity;
for (i = 0; i < s; ++i)
{
Allocator::Construct(&newData[i], Data[i]);
Allocator::Destruct(&Data[i]);
}
for (i = s; i < Size; ++i)
{
Allocator::Destruct(&Data[i]);
}
Allocator::Free(Data);
Data = newData;
}
}
else
{
Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
//memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this?
}
Policy.SetCapacity(newCapacity);
// OVR_ASSERT(Data); // need to throw (or something) on alloc failure!
}
}
// This version of Resize DOES NOT construct the elements.
// It's done to optimize PushBack, which uses a copy constructor
// instead of the default constructor and assignment
void ResizeNoConstruct(UPInt newSize)
{
UPInt oldSize = Size;
if (newSize < oldSize)
{
Allocator::DestructArray(Data + newSize, oldSize - newSize);
if (newSize < (Policy.GetCapacity() >> 1))
{
Reserve(newSize);
}
}
else if(newSize >= Policy.GetCapacity())
{
Reserve(newSize + (newSize >> 2));
}
//! IMPORTANT to modify Size only after Reserve completes, because garbage collectable
// array may use this array and may traverse it during Reserve (in the case, if
// collection occurs because of heap limit exceeded).
Size = newSize;
}
ValueType* Data;
UPInt Size;
SizePolicy Policy;
};
//-----------------------------------------------------------------------------------
// ***** ArrayData
//
// General purpose array data.
// For internal use only in Array, ArrayLH, ArrayPOD and so on.
template<class T, class Allocator, class SizePolicy>
struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy>
{
typedef T ValueType;
typedef Allocator AllocatorType;
typedef SizePolicy SizePolicyType;
typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType;
typedef ArrayData <T, Allocator, SizePolicy> SelfType;
ArrayData()
: BaseType() { }
ArrayData(int size)
: BaseType() { Resize(size); }
ArrayData(const SelfType& a)
: BaseType(a.Policy) { Append(a.Data, a.Size); }
void Resize(UPInt newSize)
{
UPInt oldSize = this->Size;
BaseType::ResizeNoConstruct(newSize);
if(newSize > oldSize)
Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize);
}
void PushBack(const ValueType& val)
{
BaseType::ResizeNoConstruct(this->Size + 1);
Allocator::Construct(this->Data + this->Size - 1, val);
}
template<class S>
void PushBackAlt(const S& val)
{
BaseType::ResizeNoConstruct(this->Size + 1);
Allocator::ConstructAlt(this->Data + this->Size - 1, val);
}
// Append the given data to the array.
void Append(const ValueType other[], UPInt count)
{
if (count)
{
UPInt oldSize = this->Size;
BaseType::ResizeNoConstruct(this->Size + count);
Allocator::ConstructArray(this->Data + oldSize, count, other);
}
}
};
//-----------------------------------------------------------------------------------
// ***** ArrayDataCC
//
// A modification of ArrayData that always copy-constructs new elements
// using a specified DefaultValue. For internal use only in ArrayCC.
template<class T, class Allocator, class SizePolicy>
struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy>
{
typedef T ValueType;
typedef Allocator AllocatorType;
typedef SizePolicy SizePolicyType;
typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType;
typedef ArrayDataCC <T, Allocator, SizePolicy> SelfType;
ArrayDataCC(const ValueType& defval)
: BaseType(), DefaultValue(defval) { }
ArrayDataCC(const ValueType& defval, int size)
: BaseType(), DefaultValue(defval) { Resize(size); }
ArrayDataCC(const SelfType& a)
: BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); }
void Resize(UPInt newSize)
{
UPInt oldSize = this->Size;
BaseType::ResizeNoConstruct(newSize);
if(newSize > oldSize)
Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue);
}
void PushBack(const ValueType& val)
{
BaseType::ResizeNoConstruct(this->Size + 1);
Allocator::Construct(this->Data + this->Size - 1, val);
}
template<class S>
void PushBackAlt(const S& val)
{
BaseType::ResizeNoConstruct(this->Size + 1);
Allocator::ConstructAlt(this->Data + this->Size - 1, val);
}
// Append the given data to the array.
void Append(const ValueType other[], UPInt count)
{
if (count)
{
UPInt oldSize = this->Size;
BaseType::ResizeNoConstruct(this->Size + count);
Allocator::ConstructArray(this->Data + oldSize, count, other);
}
}
ValueType DefaultValue;
};
//-----------------------------------------------------------------------------------
// ***** ArrayBase
//
// Resizable array. The behavior can be POD (suffix _POD) and
// Movable (no suffix) depending on the allocator policy.
// In case of _POD the constructors and destructors are not called.
//
// Arrays can't handle non-movable objects! Don't put anything in here
// that can't be moved around by bitwise copy.
//
// The addresses of elements are not persistent! Don't keep the address
// of an element; the array contents will move around as it gets resized.
template<class ArrayData>
class ArrayBase
{
public:
typedef typename ArrayData::ValueType ValueType;
typedef typename ArrayData::AllocatorType AllocatorType;
typedef typename ArrayData::SizePolicyType SizePolicyType;
typedef ArrayBase<ArrayData> SelfType;
#undef new
OVR_MEMORY_REDEFINE_NEW(ArrayBase)
// Redefine operator 'new' if necessary.
#if defined(OVR_DEFINE_NEW)
#define new OVR_DEFINE_NEW
#endif
ArrayBase()
: Data() {}
ArrayBase(int size)
: Data(size) {}
ArrayBase(const SelfType& a)
: Data(a.Data) {}
ArrayBase(const ValueType& defval)
: Data(defval) {}
ArrayBase(const ValueType& defval, int size)
: Data(defval, size) {}
SizePolicyType* GetSizePolicy() const { return Data.Policy; }
void SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; }
bool NeverShrinking()const { return Data.Policy.NeverShrinking(); }
UPInt GetSize() const { return Data.Size; }
bool IsEmpty() const { return Data.Size == 0; }
UPInt GetCapacity() const { return Data.GetCapacity(); }
UPInt GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); }
void ClearAndRelease() { Data.ClearAndRelease(); }
void Clear() { Data.Resize(0); }
void Resize(UPInt newSize) { Data.Resize(newSize); }
// Reserve can only increase the capacity
void Reserve(UPInt newCapacity)
{
if (newCapacity > Data.GetCapacity())
Data.Reserve(newCapacity);
}
// Basic access.
ValueType& At(UPInt index)
{
OVR_ASSERT(index < Data.Size);
return Data.Data[index];
}
const ValueType& At(UPInt index) const
{
OVR_ASSERT(index < Data.Size);
return Data.Data[index];
}
ValueType ValueAt(UPInt index) const
{
OVR_ASSERT(index < Data.Size);
return Data.Data[index];
}
// Basic access.
ValueType& operator [] (UPInt index)
{
OVR_ASSERT(index < Data.Size);
return Data.Data[index];
}
const ValueType& operator [] (UPInt index) const
{
OVR_ASSERT(index < Data.Size);
return Data.Data[index];
}
// Raw pointer to the data. Use with caution!
const ValueType* GetDataPtr() const { return Data.Data; }
ValueType* GetDataPtr() { return Data.Data; }
// Insert the given element at the end of the array.
void PushBack(const ValueType& val)
{
// DO NOT pass elements of your own vector into
// push_back()! Since we're using references,
// resize() may munge the element storage!
// OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]);
Data.PushBack(val);
}
template<class S>
void PushBackAlt(const S& val)
{
Data.PushBackAlt(val);
}
// Remove the last element.
void PopBack(UPInt count = 1)
{
OVR_ASSERT(Data.Size >= count);
Data.Resize(Data.Size - count);
}
ValueType& PushDefault()
{
Data.PushBack(ValueType());
return Back();
}
ValueType Pop()
{
ValueType t = Back();
PopBack();
return t;
}
// Access the first element.
ValueType& Front() { return At(0); }
const ValueType& Front() const { return At(0); }
// Access the last element.
ValueType& Back() { return At(Data.Size - 1); }
const ValueType& Back() const { return At(Data.Size - 1); }
// Array copy. Copies the contents of a into this array.
const SelfType& operator = (const SelfType& a)
{
Resize(a.GetSize());
for (UPInt i = 0; i < Data.Size; i++) {
*(Data.Data + i) = a[i];
}
return *this;
}
// Removing multiple elements from the array.
void RemoveMultipleAt(UPInt index, UPInt num)
{
OVR_ASSERT(index + num <= Data.Size);
if (Data.Size == num)
{
Clear();
}
else
{
AllocatorType::DestructArray(Data.Data + index, num);
AllocatorType::CopyArrayForward(
Data.Data + index,
Data.Data + index + num,
Data.Size - num - index);
Data.Size -= num;
}
}
// Removing an element from the array is an expensive operation!
// It compacts only after removing the last element.
void RemoveAt(UPInt index)
{
OVR_ASSERT(index < Data.Size);
if (Data.Size == 1)
{
Clear();
}
else
{
AllocatorType::Destruct(Data.Data + index);
AllocatorType::CopyArrayForward(
Data.Data + index,
Data.Data + index + 1,
Data.Size - 1 - index);
--Data.Size;
}
}
// Insert the given object at the given index shifting all the elements up.
void InsertAt(UPInt index, const ValueType& val = ValueType())
{
OVR_ASSERT(index <= Data.Size);
Data.Resize(Data.Size + 1);
if (index < Data.Size - 1)
{
AllocatorType::CopyArrayBackward(
Data.Data + index + 1,
Data.Data + index,
Data.Size - 1 - index);
}
AllocatorType::Construct(Data.Data + index, val);
}
// Insert the given object at the given index shifting all the elements up.
void InsertMultipleAt(UPInt index, UPInt num, const ValueType& val = ValueType())
{
OVR_ASSERT(index <= Data.Size);
Data.Resize(Data.Size + num);
if (index < Data.Size - num)
{
AllocatorType::CopyArrayBackward(
Data.Data + index + num,
Data.Data + index,
Data.Size - num - index);
}
for (UPInt i = 0; i < num; ++i)
AllocatorType::Construct(Data.Data + index + i, val);
}
// Append the given data to the array.
void Append(const SelfType& other)
{
Append(other.Data.Data, other.GetSize());
}
// Append the given data to the array.
void Append(const ValueType other[], UPInt count)
{
Data.Append(other, count);
}
class Iterator
{
SelfType* pArray;
SPInt CurIndex;
public:
Iterator() : pArray(0), CurIndex(-1) {}
Iterator(SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
Iterator& operator++()
{
if (pArray)
{
if (CurIndex < (SPInt)pArray->GetSize())
++CurIndex;
}
return *this;
}
Iterator operator++(int)
{
Iterator it(*this);
operator++();
return it;
}
Iterator& operator--()
{
if (pArray)
{
if (CurIndex >= 0)
--CurIndex;
}
return *this;
}
Iterator operator--(int)
{
Iterator it(*this);
operator--();
return it;
}
Iterator operator+(int delta) const
{
return Iterator(pArray, CurIndex + delta);
}
Iterator operator-(int delta) const
{
return Iterator(pArray, CurIndex - delta);
}
SPInt operator-(const Iterator& right) const
{
OVR_ASSERT(pArray == right.pArray);
return CurIndex - right.CurIndex;
}
ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; }
ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
void Remove()
{
if (!IsFinished())
pArray->RemoveAt(CurIndex);
}
SPInt GetIndex() const { return CurIndex; }
};
Iterator Begin() { return Iterator(this); }
Iterator End() { return Iterator(this, (SPInt)GetSize()); }
Iterator Last() { return Iterator(this, (SPInt)GetSize() - 1); }
class ConstIterator
{
const SelfType* pArray;
SPInt CurIndex;
public:
ConstIterator() : pArray(0), CurIndex(-1) {}
ConstIterator(const SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
ConstIterator& operator++()
{
if (pArray)
{
if (CurIndex < (int)pArray->GetSize())
++CurIndex;
}
return *this;
}
ConstIterator operator++(int)
{
ConstIterator it(*this);
operator++();
return it;
}
ConstIterator& operator--()
{
if (pArray)
{
if (CurIndex >= 0)
--CurIndex;
}
return *this;
}
ConstIterator operator--(int)
{
ConstIterator it(*this);
operator--();
return it;
}
ConstIterator operator+(int delta) const
{
return ConstIterator(pArray, CurIndex + delta);
}
ConstIterator operator-(int delta) const
{
return ConstIterator(pArray, CurIndex - delta);
}
SPInt operator-(const ConstIterator& right) const
{
OVR_ASSERT(pArray == right.pArray);
return CurIndex - right.CurIndex;
}
const ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; }
const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
const ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
SPInt GetIndex() const { return CurIndex; }
};
ConstIterator Begin() const { return ConstIterator(this); }
ConstIterator End() const { return ConstIterator(this, (SPInt)GetSize()); }
ConstIterator Last() const { return ConstIterator(this, (SPInt)GetSize() - 1); }
protected:
ArrayData Data;
};
//-----------------------------------------------------------------------------------
// ***** Array
//
// General purpose array for movable objects that require explicit
// construction/destruction.
template<class T, class SizePolicy=ArrayDefaultPolicy>
class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> >
{
public:
typedef T ValueType;
typedef ContainerAllocator<T> AllocatorType;
typedef SizePolicy SizePolicyType;
typedef Array<T, SizePolicy> SelfType;
typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType;
Array() : BaseType() {}
Array(int size) : BaseType(size) {}
Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
Array(const SelfType& a) : BaseType(a) {}
const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
};
// ***** ArrayPOD
//
// General purpose array for movable objects that DOES NOT require
// construction/destruction. Constructors and destructors are not called!
// Global heap is in use.
template<class T, class SizePolicy=ArrayDefaultPolicy>
class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> >
{
public:
typedef T ValueType;
typedef ContainerAllocator_POD<T> AllocatorType;
typedef SizePolicy SizePolicyType;
typedef ArrayPOD<T, SizePolicy> SelfType;
typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType;
ArrayPOD() : BaseType() {}
ArrayPOD(int size) : BaseType(size) {}
ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
ArrayPOD(const SelfType& a) : BaseType(a) {}
const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
};
// ***** ArrayCPP
//
// General purpose, fully C++ compliant array. Can be used with non-movable data.
// Global heap is in use.
template<class T, class SizePolicy=ArrayDefaultPolicy>
class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> >
{
public:
typedef T ValueType;
typedef ContainerAllocator_CPP<T> AllocatorType;
typedef SizePolicy SizePolicyType;
typedef ArrayCPP<T, SizePolicy> SelfType;
typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType;
ArrayCPP() : BaseType() {}
ArrayCPP(int size) : BaseType(size) {}
ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
ArrayCPP(const SelfType& a) : BaseType(a) {}
const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
};
// ***** ArrayCC
//
// A modification of the array that uses the given default value to
// construct the elements. The constructors and destructors are
// properly called, the objects must be movable.
template<class T, class SizePolicy=ArrayDefaultPolicy>
class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >
{
public:
typedef T ValueType;
typedef ContainerAllocator<T> AllocatorType;
typedef SizePolicy SizePolicyType;
typedef ArrayCC<T, SizePolicy> SelfType;
typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > BaseType;
ArrayCC(const ValueType& defval) : BaseType(defval) {}
ArrayCC(const ValueType& defval, int size) : BaseType(defval, size) {}
ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); }
ArrayCC(const SelfType& a) : BaseType(a) {}
const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
};
} // OVR
#endif

View file

@ -1,860 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_Atomic.h
Content : Contains atomic operations and inline fastest locking
functionality. Will contain #ifdefs for OS efficiency.
Have non-thread-safe implementaion if not available.
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Atomic_h
#define OVR_Atomic_h
#include "OVR_Types.h"
// Include System thread functionality.
#if defined(OVR_OS_WIN32)
#include <windows.h>
#else
#include <pthread.h>
#endif
namespace OVR {
// ****** Declared classes
// If there is NO thread support we implement AtomicOps and
// Lock objects as no-ops. The other classes are not defined.
template<class C> class AtomicOps;
template<class T> class AtomicInt;
template<class T> class AtomicPtr;
class Lock;
//-----------------------------------------------------------------------------------
// ***** AtomicOps
// Atomic operations are provided by the AtomicOps templates class,
// implemented through system-specific AtomicOpsRaw specializations.
// It provides several fundamental operations such as Exchange, ExchangeAdd
// CompareAndSet, and Store_Release. Each function includes several memory
// synchronization versions, important for multiprocessing CPUs with weak
// memory consistency. The following memory fencing strategies are supported:
//
// - NoSync. No memory synchronization is done for atomic op.
// - Release. All other memory writes are completed before atomic op
// writes its results.
// - Acquire. Further memory reads are forced to wait until atomic op
// executes, guaranteeing that the right values will be seen.
// - Sync. A combination of Release and Acquire.
// *** AtomicOpsRaw
// AtomicOpsRaw is a specialized template that provides atomic operations
// used by AtomicOps. This class has two fundamental qualities: (1) it
// defines a type T of correct size, and (2) provides operations that work
// atomically, such as Exchange_Sync and CompareAndSet_Release.
// AtomicOpsRawBase class contains shared constants/classes for AtomicOpsRaw.
// The primary thing is does is define sync class objects, whose destructor and
// constructor provide places to insert appropriate synchronization calls, on
// systems where such calls are necessary. So far, the breakdown is as follows:
//
// - X86 systems don't need custom syncs, since their exchange/atomic
// instructions are implicitly synchronized.
// - PowerPC requires lwsync/isync instructions that can use this mechanism.
// - If some other systems require a mechanism where syncing type is associated
// with a particular instruction, the default implementation (which implements
// all Sync, Acquire, and Release modes in terms of NoSync and fence) may not
// work. Ii that case it will need to be #ifdef-ed conditionally.
struct AtomicOpsRawBase
{
#if !defined(OVR_ENABLE_THREADS) || defined(OVR_CPU_X86) || defined(OVR_OS_WIN32) || defined(OVR_OS_IPHONE)
// Need to have empty constructor to avoid class 'unused' variable warning.
struct FullSync { inline FullSync() { } };
struct AcquireSync { inline AcquireSync() { } };
struct ReleaseSync { inline ReleaseSync() { } };
#elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC)
struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("isync\n"); } };
struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("isync\n"); } };
struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } };
#elif defined(OVR_CPU_MIPS)
struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("sync\n"); } };
struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("sync\n"); } };
struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } };
#elif defined(OVR_CPU_ARM)
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"); } };
#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4)
// __sync functions are already full sync
struct FullSync { inline FullSync() { } };
struct AcquireSync { inline AcquireSync() { } };
struct ReleaseSync { inline ReleaseSync() { } };
#endif
};
// 4-Byte raw data atomic op implementation class.
struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase
{
#if !defined(OVR_ENABLE_THREADS)
// Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl.
typedef UInt32 T;
// *** Thread - Safe Atomic Versions.
#elif defined(OVR_OS_WIN32)
// Use special defined for VC6, where volatile is not used and
// InterlockedCompareExchange is declared incorrectly.
typedef LONG T;
#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC < 1300)
typedef T* InterlockTPtr;
typedef LPVOID ET;
typedef ET* InterlockETPtr;
#else
typedef volatile T* InterlockTPtr;
typedef T ET;
typedef InterlockTPtr InterlockETPtr;
#endif
inline static T Exchange_NoSync(volatile T* p, T val) { return InterlockedExchange((InterlockTPtr)p, val); }
inline static T ExchangeAdd_NoSync(volatile T* p, T val) { return InterlockedExchangeAdd((InterlockTPtr)p, val); }
inline static bool CompareAndSet_NoSync(volatile T* p, T c, T val) { return InterlockedCompareExchange((InterlockETPtr)p, (ET)val, (ET)c) == (ET)c; }
#elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC)
typedef UInt32 T;
static inline UInt32 Exchange_NoSync(volatile UInt32 *i, UInt32 j)
{
UInt32 ret;
asm volatile("1:\n\t"
"lwarx %[r],0,%[i]\n\t"
"stwcx. %[j],0,%[i]\n\t"
"bne- 1b\n"
: "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [j] "b" (j) : "cc", "memory");
return ret;
}
static inline UInt32 ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
{
UInt32 dummy, ret;
asm volatile("1:\n\t"
"lwarx %[r],0,%[i]\n\t"
"add %[o],%[r],%[j]\n\t"
"stwcx. %[o],0,%[i]\n\t"
"bne- 1b\n"
: "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc", "memory");
return ret;
}
static inline bool CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
{
UInt32 ret;
asm volatile("1:\n\t"
"lwarx %[r],0,%[i]\n\t"
"cmpw 0,%[r],%[cmp]\n\t"
"mfcr %[r]\n\t"
"bne- 2f\n\t"
"stwcx. %[val],0,%[i]\n\t"
"bne- 1b\n\t"
"2:\n"
: "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc", "memory");
return (ret & 0x20000000) ? 1 : 0;
}
#elif defined(OVR_CPU_MIPS)
typedef UInt32 T;
static inline UInt32 Exchange_NoSync(volatile UInt32 *i, UInt32 j)
{
UInt32 ret;
asm volatile("1:\n\t"
"ll %[r],0(%[i])\n\t"
"sc %[j],0(%[i])\n\t"
"beq %[j],$0,1b\n\t"
"nop \n"
: "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory");
return ret;
}
static inline UInt32 ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
{
UInt32 ret;
asm volatile("1:\n\t"
"ll %[r],0(%[i])\n\t"
"addu %[j],%[r],%[j]\n\t"
"sc %[j],0(%[i])\n\t"
"beq %[j],$0,1b\n\t"
"nop \n"
: "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory");
return ret;
}
static inline bool CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
{
UInt32 ret, dummy;
asm volatile("1:\n\t"
"move %[r],$0\n\t"
"ll %[o],0(%[i])\n\t"
"bne %[o],%[c],2f\n\t"
"move %[r],%[v]\n\t"
"sc %[r],0(%[i])\n\t"
"beq %[r],$0,1b\n\t"
"nop \n\t"
"2:\n"
: "+m" (*i),[r] "=&d" (ret), [o] "=&d" (dummy) : [i] "d" (i), [c] "d" (c), [v] "d" (value)
: "cc", "memory");
return ret;
}
#elif defined(OVR_CPU_ARM) && defined(OVR_CC_ARM)
typedef UInt32 T;
static inline UInt32 Exchange_NoSync(volatile UInt32 *i, UInt32 j)
{
for(;;)
{
T r = __ldrex(i);
if (__strex(j, i) == 0)
return r;
}
}
static inline UInt32 ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
{
for(;;)
{
T r = __ldrex(i);
if (__strex(r + j, i) == 0)
return r;
}
}
static inline bool CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
{
for(;;)
{
T r = __ldrex(i);
if (r != c)
return 0;
if (__strex(value, i) == 0)
return 1;
}
}
#elif defined(OVR_CPU_ARM)
typedef UInt32 T;
static inline UInt32 Exchange_NoSync(volatile UInt32 *i, UInt32 j)
{
UInt32 ret, dummy;
asm volatile("1:\n\t"
"ldrex %[r],[%[i]]\n\t"
"strex %[t],%[j],[%[i]]\n\t"
"cmp %[t],#0\n\t"
"bne 1b\n\t"
: "+m" (*i), [r] "=&r" (ret), [t] "=&r" (dummy) : [i] "r" (i), [j] "r" (j) : "cc", "memory");
return ret;
}
static inline UInt32 ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
{
UInt32 ret, dummy, test;
asm volatile("1:\n\t"
"ldrex %[r],[%[i]]\n\t"
"add %[o],%[r],%[j]\n\t"
"strex %[t],%[o],[%[i]]\n\t"
"cmp %[t],#0\n\t"
"bne 1b\n\t"
: "+m" (*i), [r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [j] "r" (j) : "cc", "memory");
return ret;
}
static inline bool CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
{
UInt32 ret = 1, dummy, test;
asm volatile("1:\n\t"
"ldrex %[o],[%[i]]\n\t"
"cmp %[o],%[c]\n\t"
"bne 2f\n\t"
"strex %[r],%[v],[%[i]]\n\t"
"cmp %[r],#0\n\t"
"bne 1b\n\t"
"2:\n"
: "+m" (*i),[r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [c] "r" (c), [v] "r" (value)
: "cc", "memory");
return !ret;
}
#elif defined(OVR_CPU_X86)
typedef UInt32 T;
static inline UInt32 Exchange_NoSync(volatile UInt32 *i, UInt32 j)
{
asm volatile("xchgl %1,%[i]\n"
: "+m" (*i), "=q" (j) : [i] "m" (*i), "1" (j) : "cc", "memory");
return j;
}
static inline UInt32 ExchangeAdd_NoSync(volatile UInt32 *i, UInt32 j)
{
asm volatile("lock; xaddl %1,%[i]\n"
: "+m" (*i), "+q" (j) : [i] "m" (*i) : "cc", "memory");
return j;
}
static inline bool CompareAndSet_NoSync(volatile UInt32 *i, UInt32 c, UInt32 value)
{
UInt32 ret;
asm volatile("lock; cmpxchgl %[v],%[i]\n"
: "+m" (*i), "=a" (ret) : [i] "m" (*i), "1" (c), [v] "q" (value) : "cc", "memory");
return (ret == c);
}
#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
typedef UInt32 T;
static inline T Exchange_NoSync(volatile T *i, T j)
{
T v;
do {
v = *i;
} while (!__sync_bool_compare_and_swap(i, v, j));
return v;
}
static inline T ExchangeAdd_NoSync(volatile T *i, T j)
{
return __sync_fetch_and_add(i, j);
}
static inline bool CompareAndSet_NoSync(volatile T *i, T c, T value)
{
return __sync_bool_compare_and_swap(i, c, value);
}
#endif // OS
};
// 8-Byte raw data data atomic op implementation class.
// Currently implementation is provided only on systems with 64-bit pointers.
struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase
{
#if !defined(OVR_64BIT_POINTERS) || !defined(OVR_ENABLE_THREADS)
// Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl.
typedef UInt64 T;
// *** Thread - Safe OS specific versions.
#elif defined(OVR_OS_WIN32)
// This is only for 64-bit systems.
typedef LONG64 T;
typedef volatile T* InterlockTPtr;
inline static T Exchange_NoSync(volatile T* p, T val) { return InterlockedExchange64((InterlockTPtr)p, val); }
inline static T ExchangeAdd_NoSync(volatile T* p, T val) { return InterlockedExchangeAdd64((InterlockTPtr)p, val); }
inline static bool CompareAndSet_NoSync(volatile T* p, T c, T val) { return InterlockedCompareExchange64((InterlockTPtr)p, val, c) == c; }
#elif defined(OVR_CPU_PPC64)
typedef UInt64 T;
static inline UInt64 Exchange_NoSync(volatile UInt64 *i, UInt64 j)
{
UInt64 dummy, ret;
asm volatile("1:\n\t"
"ldarx %[r],0,%[i]\n\t"
"mr %[o],%[j]\n\t"
"stdcx. %[o],0,%[i]\n\t"
"bne- 1b\n"
: "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc");
return ret;
}
static inline UInt64 ExchangeAdd_NoSync(volatile UInt64 *i, UInt64 j)
{
UInt64 dummy, ret;
asm volatile("1:\n\t"
"ldarx %[r],0,%[i]\n\t"
"add %[o],%[r],%[j]\n\t"
"stdcx. %[o],0,%[i]\n\t"
"bne- 1b\n"
: "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc");
return ret;
}
static inline bool CompareAndSet_NoSync(volatile UInt64 *i, UInt64 c, UInt64 value)
{
UInt64 ret, dummy;
asm volatile("1:\n\t"
"ldarx %[r],0,%[i]\n\t"
"cmpw 0,%[r],%[cmp]\n\t"
"mfcr %[r]\n\t"
"bne- 2f\n\t"
"stdcx. %[val],0,%[i]\n\t"
"bne- 1b\n\t"
"2:\n"
: "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc");
return (ret & 0x20000000) ? 1 : 0;
}
#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
typedef UInt64 T;
static inline T Exchange_NoSync(volatile T *i, T j)
{
T v;
do {
v = *i;
} while (!__sync_bool_compare_and_swap(i, v, j));
return v;
}
static inline T ExchangeAdd_NoSync(volatile T *i, T j)
{
return __sync_fetch_and_add(i, j);
}
static inline bool CompareAndSet_NoSync(volatile T *i, T c, T value)
{
return __sync_bool_compare_and_swap(i, c, value);
}
#endif // OS
};
// Default implementation for AtomicOpsRaw; provides implementation of mem-fenced
// atomic operations where fencing is done with a sync object wrapped around a NoSync
// operation implemented in the base class. If such implementation is not possible
// on a given platform, #ifdefs can be used to disable it and then op functions can be
// implemented individually in the appropriate AtomicOpsRaw<size> class.
template<class O>
struct AtomicOpsRaw_DefImpl : public O
{
typedef typename O::T O_T;
typedef typename O::FullSync O_FullSync;
typedef typename O::AcquireSync O_AcquireSync;
typedef typename O::ReleaseSync O_ReleaseSync;
// If there is no thread support, provide the default implementation. In this case,
// the base class (0) must still provide the T declaration.
#ifndef OVR_ENABLE_THREADS
// Atomic exchange of val with argument. Returns old val.
inline static O_T Exchange_NoSync(volatile O_T* p, O_T val) { O_T old = *p; *p = val; return old; }
// Adds a new val to argument; returns its old val.
inline static O_T ExchangeAdd_NoSync(volatile O_T* p, O_T val) { O_T old = *p; *p += val; return old; }
// Compares the argument data with 'c' val.
// If succeeded, stores val int '*p' and returns true; otherwise returns false.
inline static bool CompareAndSet_NoSync(volatile O_T* p, O_T c, O_T val) { if (*p==c) { *p = val; return 1; } return 0; }
#endif
// If NoSync wrapped implementation may not be possible, it this block should be
// replaced with per-function implementation in O.
// "AtomicOpsRaw_DefImpl<O>::" prefix in calls below.
inline static O_T Exchange_Sync(volatile O_T* p, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::Exchange_NoSync(p, val); }
inline static O_T Exchange_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::Exchange_NoSync(p, val); }
inline static O_T Exchange_Acquire(volatile O_T* p, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::Exchange_NoSync(p, val); }
inline static O_T ExchangeAdd_Sync(volatile O_T* p, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::ExchangeAdd_NoSync(p, val); }
inline static O_T ExchangeAdd_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::ExchangeAdd_NoSync(p, val); }
inline static O_T ExchangeAdd_Acquire(volatile O_T* p, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::ExchangeAdd_NoSync(p, val); }
inline static bool CompareAndSet_Sync(volatile O_T* p, O_T c, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::CompareAndSet_NoSync(p,c,val); }
inline static bool CompareAndSet_Release(volatile O_T* p, O_T c, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::CompareAndSet_NoSync(p,c,val); }
inline static bool CompareAndSet_Acquire(volatile O_T* p, O_T c, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl<O>::CompareAndSet_NoSync(p,c,val); }
// Loads and stores with memory fence. These have only the relevant versions.
#ifdef OVR_CPU_X86
// On X86, Store_Release is implemented as exchange. Note that we can also
// consider 'sfence' in the future, although it is not as compatible with older CPUs.
inline static void Store_Release(volatile O_T* p, O_T val) { Exchange_Release(p, val); }
#else
inline static void Store_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); *p = val; }
#endif
inline static O_T Load_Acquire(const volatile O_T* p) { O_AcquireSync sync; OVR_UNUSED(sync); return *p; }
};
template<int size>
struct AtomicOpsRaw : public AtomicOpsRawBase { };
template<>
struct AtomicOpsRaw<4> : public AtomicOpsRaw_DefImpl<AtomicOpsRaw_4ByteImpl>
{
// Ensure that assigned type size is correct.
AtomicOpsRaw()
{ OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl<AtomicOpsRaw_4ByteImpl>::T) == 4); }
};
template<>
struct AtomicOpsRaw<8> : public AtomicOpsRaw_DefImpl<AtomicOpsRaw_8ByteImpl>
{
AtomicOpsRaw()
{ OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl<AtomicOpsRaw_8ByteImpl>::T) == 8); }
};
// *** AtomicOps - implementation of atomic Ops for specified class
// Implements atomic ops on a class, provided that the object is either
// 4 or 8 bytes in size (depending on the AtomicOpsRaw specializations
// available). Relies on AtomicOpsRaw for much of implementation.
template<class C>
class AtomicOps
{
typedef AtomicOpsRaw<sizeof(C)> Ops;
typedef typename Ops::T T;
typedef volatile typename Ops::T* PT;
// We cast through unions to (1) avoid pointer size compiler warnings
// and (2) ensure that there are no problems with strict pointer aliasing.
union C2T_union { C c; T t; };
public:
// General purpose implementation for standard syncs.
inline static C Exchange_Sync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Sync((PT)p, u.t); return u.c; }
inline static C Exchange_Release(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Release((PT)p, u.t); return u.c; }
inline static C Exchange_Acquire(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Acquire((PT)p, u.t); return u.c; }
inline static C Exchange_NoSync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_NoSync((PT)p, u.t); return u.c; }
inline static C ExchangeAdd_Sync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Sync((PT)p, u.t); return u.c; }
inline static C ExchangeAdd_Release(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Release((PT)p, u.t); return u.c; }
inline static C ExchangeAdd_Acquire(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Acquire((PT)p, u.t); return u.c; }
inline static C ExchangeAdd_NoSync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_NoSync((PT)p, u.t); return u.c; }
inline static bool CompareAndSet_Sync(volatile C* p, C c, C val) { C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Sync((PT)p, cu.t, u.t); }
inline static bool CompareAndSet_Release(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Release((PT)p, cu.t, u.t); }
inline static bool CompareAndSet_Relse(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Acquire((PT)p, cu.t, u.t); }
inline static bool CompareAndSet_NoSync(volatile C* p, C c, C val) { C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_NoSync((PT)p, cu.t, u.t); }
// Loads and stores with memory fence. These have only the relevant versions.
inline static void Store_Release(volatile C* p, C val) { C2T_union u; u.c = val; Ops::Store_Release((PT)p, u.t); }
inline static C Load_Acquire(const volatile C* p) { C2T_union u; u.t = Ops::Load_Acquire((PT)p); return u.c; }
};
// Atomic value base class - implements operations shared for integers and pointers.
template<class T>
class AtomicValueBase
{
protected:
typedef AtomicOps<T> Ops;
public:
volatile T Value;
inline AtomicValueBase() { }
explicit inline AtomicValueBase(T val) { Ops::Store_Release(&Value, val); }
// Most libraries (TBB and Joshua Scholar's) library do not do Load_Acquire
// here, since most algorithms do not require atomic loads. Needs some research.
inline operator T() const { return Value; }
// *** Standard Atomic inlines
inline T Exchange_Sync(T val) { return Ops::Exchange_Sync(&Value, val); }
inline T Exchange_Release(T val) { return Ops::Exchange_Release(&Value, val); }
inline T Exchange_Acquire(T val) { return Ops::Exchange_Acquire(&Value, val); }
inline T Exchange_NoSync(T val) { return Ops::Exchange_NoSync(&Value, val); }
inline bool CompareAndSet_Sync(T c, T val) { return Ops::CompareAndSet_Sync(&Value, c, val); }
inline bool CompareAndSet_Release(T c, T val) { return Ops::CompareAndSet_Release(&Value, c, val); }
inline bool CompareAndSet_Acquire(T c, T val) { return Ops::CompareAndSet_Relse(&Value, c, val); }
inline bool CompareAndSet_NoSync(T c, T val) { return Ops::CompareAndSet_NoSync(&Value, c, val); }
// Load & Store.
inline void Store_Release(T val) { Ops::Store_Release(&Value, val); }
inline T Load_Acquire() const { return Ops::Load_Acquire(&Value); }
};
// ***** AtomicPtr - Atomic pointer template
// This pointer class supports atomic assignments with release,
// increment / decrement operations, and conditional compare + set.
template<class T>
class AtomicPtr : public AtomicValueBase<T*>
{
typedef typename AtomicValueBase<T*>::Ops Ops;
public:
// Initialize pointer value to 0 by default; use Store_Release only with explicit constructor.
inline AtomicPtr() : AtomicValueBase<T*>() { this->Value = 0; }
explicit inline AtomicPtr(T* val) : AtomicValueBase<T*>(val) { }
// Pointer access.
inline T* operator -> () const { return this->Load_Acquire(); }
// It looks like it is convenient to have Load_Acquire characteristics
// for this, since that is convenient for algorithms such as linked
// list traversals that can be added to bu another thread.
inline operator T* () const { return this->Load_Acquire(); }
// *** Standard Atomic inlines (applicable to pointers)
// ExhangeAdd considers pointer size for pointers.
template<class I>
inline T* ExchangeAdd_Sync(I incr) { return Ops::ExchangeAdd_Sync(&this->Value, ((T*)0) + incr); }
template<class I>
inline T* ExchangeAdd_Release(I incr) { return Ops::ExchangeAdd_Release(&this->Value, ((T*)0) + incr); }
template<class I>
inline T* ExchangeAdd_Acquire(I incr) { return Ops::ExchangeAdd_Acquire(&this->Value, ((T*)0) + incr); }
template<class I>
inline T* ExchangeAdd_NoSync(I incr) { return Ops::ExchangeAdd_NoSync(&this->Value, ((T*)0) + incr); }
// *** Atomic Operators
inline T* operator = (T* val) { this->Store_Release(val); return val; }
template<class I>
inline T* operator += (I val) { return ExchangeAdd_Sync(val) + val; }
template<class I>
inline T* operator -= (I val) { return operator += (-val); }
inline T* operator ++ () { return ExchangeAdd_Sync(1) + 1; }
inline T* operator -- () { return ExchangeAdd_Sync(-1) - 1; }
inline T* operator ++ (int) { return ExchangeAdd_Sync(1); }
inline T* operator -- (int) { return ExchangeAdd_Sync(-1); }
};
// ***** AtomicInt - Atomic integer template
// Implements an atomic integer type; the exact type to use is provided
// as an argument. Supports atomic Acquire / Release semantics, atomic
// arithmetic operations, and atomic conditional compare + set.
template<class T>
class AtomicInt : public AtomicValueBase<T>
{
typedef typename AtomicValueBase<T>::Ops Ops;
public:
inline AtomicInt() : AtomicValueBase<T>() { }
explicit inline AtomicInt(T val) : AtomicValueBase<T>(val) { }
// *** Standard Atomic inlines (applicable to int)
inline T ExchangeAdd_Sync(T val) { return Ops::ExchangeAdd_Sync(&this->Value, val); }
inline T ExchangeAdd_Release(T val) { return Ops::ExchangeAdd_Release(&this->Value, val); }
inline T ExchangeAdd_Acquire(T val) { return Ops::ExchangeAdd_Acquire(&this->Value, val); }
inline T ExchangeAdd_NoSync(T val) { return Ops::ExchangeAdd_NoSync(&this->Value, val); }
// These increments could be more efficient because they don't return a value.
inline void Increment_Sync() { ExchangeAdd_Sync((T)1); }
inline void Increment_Release() { ExchangeAdd_Release((T)1); }
inline void Increment_Acquire() { ExchangeAdd_Acquire((T)1); }
inline void Increment_NoSync() { ExchangeAdd_NoSync((T)1); }
// *** Atomic Operators
inline T operator = (T val) { this->Store_Release(val); return val; }
inline T operator += (T val) { return ExchangeAdd_Sync(val) + val; }
inline T operator -= (T val) { return ExchangeAdd_Sync(0 - val) - val; }
inline T operator ++ () { return ExchangeAdd_Sync((T)1) + 1; }
inline T operator -- () { return ExchangeAdd_Sync(((T)0)-1) - 1; }
inline T operator ++ (int) { return ExchangeAdd_Sync((T)1); }
inline T operator -- (int) { return ExchangeAdd_Sync(((T)0)-1); }
// More complex atomic operations. Leave it to compiler whether to optimize them or not.
T operator &= (T arg)
{
T comp, newVal;
do {
comp = this->Value;
newVal = comp & arg;
} while(!this->CompareAndSet_Sync(comp, newVal));
return newVal;
}
T operator |= (T arg)
{
T comp, newVal;
do {
comp = this->Value;
newVal = comp | arg;
} while(!this->CompareAndSet_Sync(comp, newVal));
return newVal;
}
T operator ^= (T arg)
{
T comp, newVal;
do {
comp = this->Value;
newVal = comp ^ arg;
} while(!this->CompareAndSet_Sync(comp, newVal));
return newVal;
}
T operator *= (T arg)
{
T comp, newVal;
do {
comp = this->Value;
newVal = comp * arg;
} while(!this->CompareAndSet_Sync(comp, newVal));
return newVal;
}
T operator /= (T arg)
{
T comp, newVal;
do {
comp = this->Value;
newVal = comp / arg;
} while(!CompareAndSet_Sync(comp, newVal));
return newVal;
}
T operator >>= (unsigned bits)
{
T comp, newVal;
do {
comp = this->Value;
newVal = comp >> bits;
} while(!CompareAndSet_Sync(comp, newVal));
return newVal;
}
T operator <<= (unsigned bits)
{
T comp, newVal;
do {
comp = this->Value;
newVal = comp << bits;
} while(!this->CompareAndSet_Sync(comp, newVal));
return newVal;
}
};
//-----------------------------------------------------------------------------------
// ***** Lock
// Lock is a simplest and most efficient mutual-exclusion lock class.
// Unlike Mutex, it cannot be waited on.
class Lock
{
// NOTE: Locks are not allocatable and they themselves should not allocate
// memory by standard means. This is the case because StandardAllocator
// relies on this class.
// Make 'delete' private. Don't do this for 'new' since it can be redefined.
void operator delete(void*) {}
// *** Lock implementation for various platforms.
#if !defined(OVR_ENABLE_THREADS)
public:
// With no thread support, lock does nothing.
inline Lock() { }
inline Lock(unsigned) { }
inline ~Lock() { }
inline void DoLock() { }
inline void Unlock() { }
// Windows.
#elif defined(OVR_OS_WIN32)
CRITICAL_SECTION cs;
public:
Lock(unsigned spinCount = 0);
~Lock();
// Locking functions.
inline void DoLock() { ::EnterCriticalSection(&cs); }
inline void Unlock() { ::LeaveCriticalSection(&cs); }
#else
pthread_mutex_t mutex;
public:
static pthread_mutexattr_t RecursiveAttr;
static bool RecursiveAttrInit;
Lock (unsigned dummy = 0)
{
OVR_UNUSED(dummy);
if (!RecursiveAttrInit)
{
pthread_mutexattr_init(&RecursiveAttr);
pthread_mutexattr_settype(&RecursiveAttr, PTHREAD_MUTEX_RECURSIVE);
RecursiveAttrInit = 1;
}
pthread_mutex_init(&mutex,&RecursiveAttr);
}
~Lock () { pthread_mutex_destroy(&mutex); }
inline void DoLock() { pthread_mutex_lock(&mutex); }
inline void Unlock() { pthread_mutex_unlock(&mutex); }
#endif // OVR_ENABLE_THREDS
public:
// Locker class, used for automatic locking
class Locker
{
public:
Lock *pLock;
inline Locker(Lock *plock)
{ pLock = plock; pLock->DoLock(); }
inline ~Locker()
{ pLock->Unlock(); }
};
};
} // OVR
#endif

View file

@ -1,55 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_Color.h
Content : Contains color struct.
Created : February 7, 2013
Notes :
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Color_h
#define OVR_Color_h
#include "OVR_Types.h"
namespace OVR {
struct Color
{
UByte R,G,B,A;
Color() {}
// Constructs color by channel. Alpha is set to 0xFF (fully visible)
// if not specified.
Color(unsigned char r,unsigned char g,unsigned char b, unsigned char a = 0xFF)
: R(r), G(g), B(b), A(a) { }
// 0xAARRGGBB - Common HTML color Hex layout
Color(unsigned c)
: R((unsigned char)(c>>16)), G((unsigned char)(c>>8)),
B((unsigned char)c), A((unsigned char)(c>>24)) { }
bool operator==(const Color& b) const
{
return R == b.R && G == b.G && B == b.B && A == b.A;
}
void GetRGBA(float *r, float *g, float *b, float* a) const
{
*r = R / 255.0f;
*g = G / 255.0f;
*b = B / 255.0f;
*a = A / 255.0f;
}
};
}
#endif

View file

@ -1,256 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_ContainerAllocator.h
Content : Template allocators and constructors for containers.
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_ContainerAllocator_h
#define OVR_ContainerAllocator_h
#include "OVR_Allocator.h"
#include <string.h>
namespace OVR {
//-----------------------------------------------------------------------------------
// ***** Container Allocator
// ContainerAllocator serves as a template argument for allocations done by
// containers, such as Array and Hash; replacing it could allow allocator
// substitution in containers.
class ContainerAllocatorBase
{
public:
static void* Alloc(UPInt size) { return OVR_ALLOC(size); }
static void* Realloc(void* p, UPInt newSize) { return OVR_REALLOC(p, newSize); }
static void Free(void *p) { OVR_FREE(p); }
};
//-----------------------------------------------------------------------------------
// ***** Constructors, Destructors, Copiers
// Plain Old Data - movable, no special constructors/destructor.
template<class T>
class ConstructorPOD
{
public:
static void Construct(void *) {}
static void Construct(void *p, const T& source)
{
*(T*)p = source;
}
// Same as above, but allows for a different type of constructor.
template <class S>
static void ConstructAlt(void *p, const S& source)
{
*(T*)p = source;
}
static void ConstructArray(void*, UPInt) {}
static void ConstructArray(void* p, UPInt count, const T& source)
{
UByte *pdata = (UByte*)p;
for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
*(T*)pdata = source;
}
static void ConstructArray(void* p, UPInt count, const T* psource)
{
memcpy(p, psource, sizeof(T) * count);
}
static void Destruct(T*) {}
static void DestructArray(T*, UPInt) {}
static void CopyArrayForward(T* dst, const T* src, UPInt count)
{
memmove(dst, src, count * sizeof(T));
}
static void CopyArrayBackward(T* dst, const T* src, UPInt count)
{
memmove(dst, src, count * sizeof(T));
}
static bool IsMovable() { return true; }
};
//-----------------------------------------------------------------------------------
// ***** ConstructorMov
//
// Correct C++ construction and destruction for movable objects
template<class T>
class ConstructorMov
{
public:
static void Construct(void* p)
{
OVR::Construct<T>(p);
}
static void Construct(void* p, const T& source)
{
OVR::Construct<T>(p, source);
}
// Same as above, but allows for a different type of constructor.
template <class S>
static void ConstructAlt(void* p, const S& source)
{
OVR::ConstructAlt<T,S>(p, source);
}
static void ConstructArray(void* p, UPInt count)
{
UByte* pdata = (UByte*)p;
for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
Construct(pdata);
}
static void ConstructArray(void* p, UPInt count, const T& source)
{
UByte* pdata = (UByte*)p;
for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
Construct(pdata, source);
}
static void ConstructArray(void* p, UPInt count, const T* psource)
{
UByte* pdata = (UByte*)p;
for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
Construct(pdata, *psource++);
}
static void Destruct(T* p)
{
p->~T();
OVR_UNUSED(p); // Suppress silly MSVC warning
}
static void DestructArray(T* p, UPInt count)
{
p += count - 1;
for (UPInt i=0; i<count; ++i, --p)
p->~T();
}
static void CopyArrayForward(T* dst, const T* src, UPInt count)
{
memmove(dst, src, count * sizeof(T));
}
static void CopyArrayBackward(T* dst, const T* src, UPInt count)
{
memmove(dst, src, count * sizeof(T));
}
static bool IsMovable() { return true; }
};
//-----------------------------------------------------------------------------------
// ***** ConstructorCPP
//
// Correct C++ construction and destruction for movable objects
template<class T>
class ConstructorCPP
{
public:
static void Construct(void* p)
{
OVR::Construct<T>(p);
}
static void Construct(void* p, const T& source)
{
OVR::Construct<T>(p, source);
}
// Same as above, but allows for a different type of constructor.
template <class S>
static void ConstructAlt(void* p, const S& source)
{
OVR::ConstructAlt<T,S>(p, source);
}
static void ConstructArray(void* p, UPInt count)
{
UByte* pdata = (UByte*)p;
for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
Construct(pdata);
}
static void ConstructArray(void* p, UPInt count, const T& source)
{
UByte* pdata = (UByte*)p;
for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
Construct(pdata, source);
}
static void ConstructArray(void* p, UPInt count, const T* psource)
{
UByte* pdata = (UByte*)p;
for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
Construct(pdata, *psource++);
}
static void Destruct(T* p)
{
p->~T();
OVR_UNUSED(p); // Suppress silly MSVC warning
}
static void DestructArray(T* p, UPInt count)
{
p += count - 1;
for (UPInt i=0; i<count; ++i, --p)
p->~T();
}
static void CopyArrayForward(T* dst, const T* src, UPInt count)
{
for(UPInt i = 0; i < count; ++i)
dst[i] = src[i];
}
static void CopyArrayBackward(T* dst, const T* src, UPInt count)
{
for(UPInt i = count; i; --i)
dst[i-1] = src[i-1];
}
static bool IsMovable() { return false; }
};
//-----------------------------------------------------------------------------------
// ***** Container Allocator with movement policy
//
// Simple wraps as specialized allocators
template<class T> struct ContainerAllocator_POD : ContainerAllocatorBase, ConstructorPOD<T> {};
template<class T> struct ContainerAllocator : ContainerAllocatorBase, ConstructorMov<T> {};
template<class T> struct ContainerAllocator_CPP : ContainerAllocatorBase, ConstructorCPP<T> {};
} // OVR
#endif

View file

@ -1,518 +0,0 @@
/************************************************************************************
PublicHeader: Kernel
Filename : OVR_File.h
Content : Header for all internal file management - functions and structures
to be inherited by OS specific subclasses.
Created : September 19, 2012
Notes :
Notes : errno may not be preserved across use of BaseFile member functions
: Directories cannot be deleted while files opened from them are in use
(For the GetFullName function)
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_File_h
#define OVR_File_h
#include "OVR_RefCount.h"
#include "OVR_Std.h"
#include "OVR_Alg.h"
#include <stdio.h>
#include "OVR_String.h"
namespace OVR {
// ***** Declared classes
class FileConstants;
class File;
class DelegatedFile;
class BufferedFile;
// ***** Flags for File & Directory accesses
class FileConstants
{
public:
// *** File open flags
enum OpenFlags
{
Open_Read = 1,
Open_Write = 2,
Open_ReadWrite = 3,
// Opens file and truncates it to zero length
// - file must have write permission
// - when used with Create, it opens an existing
// file and empties it or creates a new file
Open_Truncate = 4,
// Creates and opens new file
// - does not erase contents if file already
// exists unless combined with Truncate
Open_Create = 8,
// Returns an error value if the file already exists
Open_CreateOnly = 24,
// Open file with buffering
Open_Buffered = 32
};
// *** File Mode flags
enum Modes
{
Mode_Read = 0444,
Mode_Write = 0222,
Mode_Execute = 0111,
Mode_ReadWrite = 0666
};
// *** Seek operations
enum SeekOps
{
Seek_Set = 0,
Seek_Cur = 1,
Seek_End = 2
};
// *** Errors
enum Errors
{
Error_FileNotFound = 0x1001,
Error_Access = 0x1002,
Error_IOError = 0x1003,
Error_DiskFull = 0x1004
};
};
//-----------------------------------------------------------------------------------
// ***** File Class
// The pure virtual base random-access file
// This is a base class to all files
class File : public RefCountBase<File>, public FileConstants
{
public:
File() { }
// ** Location Information
// Returns a file name path relative to the 'reference' directory
// This is often a path that was used to create a file
// (this is not a global path, global path can be obtained with help of directory)
virtual const char* GetFilePath() = 0;
// ** File Information
// Return 1 if file's usable (open)
virtual bool IsValid() = 0;
// Return 1 if file's writable, otherwise 0
virtual bool IsWritable() = 0;
// Return position
virtual int Tell() = 0;
virtual SInt64 LTell() = 0;
// File size
virtual int GetLength() = 0;
virtual SInt64 LGetLength() = 0;
// Returns file stats
// 0 for failure
//virtual bool Stat(FileStats *pfs) = 0;
// Return errno-based error code
// Useful if any other function failed
virtual int GetErrorCode() = 0;
// ** Stream implementation & I/O
// Blocking write, will write in the given number of bytes to the stream
// Returns : -1 for error
// Otherwise number of bytes read
virtual int Write(const UByte *pbufer, int numBytes) = 0;
// Blocking read, will read in the given number of bytes or less from the stream
// Returns : -1 for error
// Otherwise number of bytes read,
// if 0 or < numBytes, no more bytes available; end of file or the other side of stream is closed
virtual int Read(UByte *pbufer, int numBytes) = 0;
// Skips (ignores) a given # of bytes
// Same return values as Read
virtual int SkipBytes(int numBytes) = 0;
// Returns the number of bytes available to read from a stream without blocking
// For a file, this should generally be number of bytes to the end
virtual int BytesAvailable() = 0;
// Causes any implementation's buffered data to be delivered to destination
// Return 0 for error
virtual bool Flush() = 0;
// Need to provide a more optimized implementation that doe snot necessarily involve a lot of seeking
inline bool IsEOF() { return !BytesAvailable(); }
// Seeking
// Returns new position, -1 for error
virtual int Seek(int offset, int origin=Seek_Set) = 0;
virtual SInt64 LSeek(SInt64 offset, int origin=Seek_Set) = 0;
// Seek simplification
int SeekToBegin() {return Seek(0); }
int SeekToEnd() {return Seek(0,Seek_End); }
int Skip(int numBytes) {return Seek(numBytes,Seek_Cur); }
// Appends other file data from a stream
// Return -1 for error, else # of bytes written
virtual int CopyFromStream(File *pstream, int byteSize) = 0;
// Closes the file
// After close, file cannot be accessed
virtual bool Close() = 0;
// ***** Inlines for convenient primitive type serialization
// Read/Write helpers
private:
UInt64 PRead64() { UInt64 v = 0; Read((UByte*)&v, 8); return v; }
UInt32 PRead32() { UInt32 v = 0; Read((UByte*)&v, 4); return v; }
UInt16 PRead16() { UInt16 v = 0; Read((UByte*)&v, 2); return v; }
UByte PRead8() { UByte v = 0; Read((UByte*)&v, 1); return v; }
void PWrite64(UInt64 v) { Write((UByte*)&v, 8); }
void PWrite32(UInt32 v) { Write((UByte*)&v, 4); }
void PWrite16(UInt16 v) { Write((UByte*)&v, 2); }
void PWrite8(UByte v) { Write((UByte*)&v, 1); }
public:
// Writing primitive types - Little Endian
inline void WriteUByte(UByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v)); }
inline void WriteSByte(SByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v)); }
inline void WriteUInt8(UByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v)); }
inline void WriteSInt8(SByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToLE(v)); }
inline void WriteUInt16(UInt16 v) { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v)); }
inline void WriteSInt16(SInt16 v) { PWrite16((UInt16)Alg::ByteUtil::SystemToLE(v)); }
inline void WriteUInt32(UInt32 v) { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v)); }
inline void WriteSInt32(SInt32 v) { PWrite32((UInt32)Alg::ByteUtil::SystemToLE(v)); }
inline void WriteUInt64(UInt64 v) { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v)); }
inline void WriteSInt64(SInt64 v) { PWrite64((UInt64)Alg::ByteUtil::SystemToLE(v)); }
inline void WriteFloat(float v) { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 4); }
inline void WriteDouble(double v) { v = Alg::ByteUtil::SystemToLE(v); Write((UByte*)&v, 8); }
// Writing primitive types - Big Endian
inline void WriteUByteBE(UByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v)); }
inline void WriteSByteBE(SByte v) { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v)); }
inline void WriteUInt8BE(UInt16 v) { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v)); }
inline void WriteSInt8BE(SInt16 v) { PWrite8((UByte)Alg::ByteUtil::SystemToBE(v)); }
inline void WriteUInt16BE(UInt16 v) { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v)); }
inline void WriteSInt16BE(UInt16 v) { PWrite16((UInt16)Alg::ByteUtil::SystemToBE(v)); }
inline void WriteUInt32BE(UInt32 v) { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v)); }
inline void WriteSInt32BE(UInt32 v) { PWrite32((UInt32)Alg::ByteUtil::SystemToBE(v)); }
inline void WriteUInt64BE(UInt64 v) { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v)); }
inline void WriteSInt64BE(UInt64 v) { PWrite64((UInt64)Alg::ByteUtil::SystemToBE(v)); }
inline void WriteFloatBE(float v) { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 4); }
inline void WriteDoubleBE(double v) { v = Alg::ByteUtil::SystemToBE(v); Write((UByte*)&v, 8); }
// Reading primitive types - Little Endian
inline UByte ReadUByte() { return (UByte)Alg::ByteUtil::LEToSystem(PRead8()); }
inline SByte ReadSByte() { return (SByte)Alg::ByteUtil::LEToSystem(PRead8()); }
inline UByte ReadUInt8() { return (UByte)Alg::ByteUtil::LEToSystem(PRead8()); }
inline SByte ReadSInt8() { return (SByte)Alg::ByteUtil::LEToSystem(PRead8()); }
inline UInt16 ReadUInt16() { return (UInt16)Alg::ByteUtil::LEToSystem(PRead16()); }
inline SInt16 ReadSInt16() { return (SInt16)Alg::ByteUtil::LEToSystem(PRead16()); }
inline UInt32 ReadUInt32() { return (UInt32)Alg::ByteUtil::LEToSystem(PRead32()); }
inline SInt32 ReadSInt32() { return (SInt32)Alg::ByteUtil::LEToSystem(PRead32()); }
inline UInt64 ReadUInt64() { return (UInt64)Alg::ByteUtil::LEToSystem(PRead64()); }
inline SInt64 ReadSInt64() { return (SInt64)Alg::ByteUtil::LEToSystem(PRead64()); }
inline float ReadFloat() { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::LEToSystem(v); }
inline double ReadDouble() { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::LEToSystem(v); }
// Reading primitive types - Big Endian
inline UByte ReadUByteBE() { return (UByte)Alg::ByteUtil::BEToSystem(PRead8()); }
inline SByte ReadSByteBE() { return (SByte)Alg::ByteUtil::BEToSystem(PRead8()); }
inline UByte ReadUInt8BE() { return (UByte)Alg::ByteUtil::BEToSystem(PRead8()); }
inline SByte ReadSInt8BE() { return (SByte)Alg::ByteUtil::BEToSystem(PRead8()); }
inline UInt16 ReadUInt16BE() { return (UInt16)Alg::ByteUtil::BEToSystem(PRead16()); }
inline SInt16 ReadSInt16BE() { return (SInt16)Alg::ByteUtil::BEToSystem(PRead16()); }
inline UInt32 ReadUInt32BE() { return (UInt32)Alg::ByteUtil::BEToSystem(PRead32()); }
inline SInt32 ReadSInt32BE() { return (SInt32)Alg::ByteUtil::BEToSystem(PRead32()); }
inline UInt64 ReadUInt64BE() { return (UInt64)Alg::ByteUtil::BEToSystem(PRead64()); }
inline SInt64 ReadSInt64BE() { return (SInt64)Alg::ByteUtil::BEToSystem(PRead64()); }
inline float ReadFloatBE() { float v = 0.0f; Read((UByte*)&v, 4); return Alg::ByteUtil::BEToSystem(v); }
inline double ReadDoubleBE() { double v = 0.0; Read((UByte*)&v, 8); return Alg::ByteUtil::BEToSystem(v); }
};
// *** Delegated File
class DelegatedFile : public File
{
protected:
// Delegating file pointer
Ptr<File> pFile;
// Hidden default constructor
DelegatedFile() : pFile(0) { }
DelegatedFile(const DelegatedFile &source) : File() { OVR_UNUSED(source); }
public:
// Constructors
DelegatedFile(File *pfile) : pFile(pfile) { }
// ** Location Information
virtual const char* GetFilePath() { return pFile->GetFilePath(); }
// ** File Information
virtual bool IsValid() { return pFile && pFile->IsValid(); }
virtual bool IsWritable() { return pFile->IsWritable(); }
// virtual bool IsRecoverable() { return pFile->IsRecoverable(); }
virtual int Tell() { return pFile->Tell(); }
virtual SInt64 LTell() { return pFile->LTell(); }
virtual int GetLength() { return pFile->GetLength(); }
virtual SInt64 LGetLength() { return pFile->LGetLength(); }
//virtual bool Stat(FileStats *pfs) { return pFile->Stat(pfs); }
virtual int GetErrorCode() { return pFile->GetErrorCode(); }
// ** Stream implementation & I/O
virtual int Write(const UByte *pbuffer, int numBytes) { return pFile->Write(pbuffer,numBytes); }
virtual int Read(UByte *pbuffer, int numBytes) { return pFile->Read(pbuffer,numBytes); }
virtual int SkipBytes(int numBytes) { return pFile->SkipBytes(numBytes); }
virtual int BytesAvailable() { return pFile->BytesAvailable(); }
virtual bool Flush() { return pFile->Flush(); }
// Seeking
virtual int Seek(int offset, int origin=Seek_Set) { return pFile->Seek(offset,origin); }
virtual SInt64 LSeek(SInt64 offset, int origin=Seek_Set) { return pFile->LSeek(offset,origin); }
virtual int CopyFromStream(File *pstream, int byteSize) { return pFile->CopyFromStream(pstream,byteSize); }
// Closing the file
virtual bool Close() { return pFile->Close(); }
};
//-----------------------------------------------------------------------------------
// ***** Buffered File
// This file class adds buffering to an existing file
// Buffered file never fails by itself; if there's not
// enough memory for buffer, no buffer's used
class BufferedFile : public DelegatedFile
{
protected:
enum BufferModeType
{
NoBuffer,
ReadBuffer,
WriteBuffer
};
// Buffer & the mode it's in
UByte* pBuffer;
BufferModeType BufferMode;
// Position in buffer
unsigned Pos;
// Data in buffer if reading
unsigned DataSize;
// Underlying file position
UInt64 FilePos;
// Initializes buffering to a certain mode
bool SetBufferMode(BufferModeType mode);
// Flushes buffer
// WriteBuffer - write data to disk, ReadBuffer - reset buffer & fix file position
void FlushBuffer();
// Loads data into ReadBuffer
// WARNING: Right now LoadBuffer() assumes the buffer's empty
void LoadBuffer();
// Hidden constructor
BufferedFile();
inline BufferedFile(const BufferedFile &source) : DelegatedFile() { OVR_UNUSED(source); }
public:
// Constructor
// - takes another file as source
BufferedFile(File *pfile);
~BufferedFile();
// ** Overridden functions
// We override all the functions that can possibly
// require buffer mode switch, flush, or extra calculations
virtual int Tell();
virtual SInt64 LTell();
virtual int GetLength();
virtual SInt64 LGetLength();
// virtual bool Stat(GFileStats *pfs);
virtual int Write(const UByte *pbufer, int numBytes);
virtual int Read(UByte *pbufer, int numBytes);
virtual int SkipBytes(int numBytes);
virtual int BytesAvailable();
virtual bool Flush();
virtual int Seek(int offset, int origin=Seek_Set);
virtual SInt64 LSeek(SInt64 offset, int origin=Seek_Set);
virtual int CopyFromStream(File *pstream, int byteSize);
virtual bool Close();
};
//-----------------------------------------------------------------------------------
// ***** Memory File
class MemoryFile : public File
{
public:
const char* GetFilePath() { return FilePath.ToCStr(); }
bool IsValid() { return Valid; }
bool IsWritable() { return false; }
bool Flush() { return true; }
int GetErrorCode() { return 0; }
int Tell() { return FileIndex; }
SInt64 LTell() { return (SInt64) FileIndex; }
int GetLength() { return FileSize; }
SInt64 LGetLength() { return (SInt64) FileSize; }
bool Close()
{
Valid = false;
return false;
}
int CopyFromStream(File *pstream, int byteSize)
{ OVR_UNUSED2(pstream, byteSize);
return 0;
}
int Write(const UByte *pbuffer, int numBytes)
{ OVR_UNUSED2(pbuffer, numBytes);
return 0;
}
int Read(UByte *pbufer, int numBytes)
{
if (FileIndex + numBytes > FileSize)
{
numBytes = FileSize - FileIndex;
}
if (numBytes > 0)
{
::memcpy (pbufer, &FileData [FileIndex], numBytes);
FileIndex += numBytes;
}
return numBytes;
}
int SkipBytes(int numBytes)
{
if (FileIndex + numBytes > FileSize)
{
numBytes = FileSize - FileIndex;
}
FileIndex += numBytes;
return numBytes;
}
int BytesAvailable()
{
return (FileSize - FileIndex);
}
int Seek(int offset, int origin = Seek_Set)
{
switch (origin)
{
case Seek_Set : FileIndex = offset; break;
case Seek_Cur : FileIndex += offset; break;
case Seek_End : FileIndex = FileSize - offset; break;
}
return FileIndex;
}
SInt64 LSeek(SInt64 offset, int origin = Seek_Set)
{
return (SInt64) Seek((int) offset, origin);
}
public:
MemoryFile (const String& fileName, const UByte *pBuffer, int buffSize)
: FilePath(fileName)
{
FileData = pBuffer;
FileSize = buffSize;
FileIndex = 0;
Valid = (!fileName.IsEmpty() && pBuffer && buffSize > 0) ? true : false;
}
// pfileName should be encoded as UTF-8 to support international file names.
MemoryFile (const char* pfileName, const UByte *pBuffer, int buffSize)
: FilePath(pfileName)
{
FileData = pBuffer;
FileSize = buffSize;
FileIndex = 0;
Valid = (pfileName && pBuffer && buffSize > 0) ? true : false;
}
private:
String FilePath;
const UByte *FileData;
int FileSize;
int FileIndex;
bool Valid;
};
// ***** Global path helpers
// Find trailing short filename in a path.
const char* OVR_CDECL GetShortFilename(const char* purl);
} // OVR
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,240 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_KeyCodes.h
Content : Common keyboard constants
Created : September 19, 2012
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_KeyCodes_h
#define OVR_KeyCodes_h
namespace OVR {
//-----------------------------------------------------------------------------------
// ***** KeyCode
// KeyCode enumeration defines platform-independent keyboard key constants.
// Note that Key_A through Key_Z are mapped to capital ascii constants.
enum KeyCode
{
// Key_None indicates that no key was specified.
Key_None = 0,
// A through Z and numbers 0 through 9.
Key_A = 65,
Key_B,
Key_C,
Key_D,
Key_E,
Key_F,
Key_G,
Key_H,
Key_I,
Key_J,
Key_K,
Key_L,
Key_M,
Key_N,
Key_O,
Key_P,
Key_Q,
Key_R,
Key_S,
Key_T,
Key_U,
Key_V,
Key_W,
Key_X,
Key_Y,
Key_Z,
Key_Num0 = 48,
Key_Num1,
Key_Num2,
Key_Num3,
Key_Num4,
Key_Num5,
Key_Num6,
Key_Num7,
Key_Num8,
Key_Num9,
// Numeric keypad.
Key_KP_0 = 0xa0,
Key_KP_1,
Key_KP_2,
Key_KP_3,
Key_KP_4,
Key_KP_5,
Key_KP_6,
Key_KP_7,
Key_KP_8,
Key_KP_9,
Key_KP_Multiply,
Key_KP_Add,
Key_KP_Enter,
Key_KP_Subtract,
Key_KP_Decimal,
Key_KP_Divide,
// Function keys.
Key_F1 = 0xb0,
Key_F2,
Key_F3,
Key_F4,
Key_F5,
Key_F6,
Key_F7,
Key_F8,
Key_F9,
Key_F10,
Key_F11,
Key_F12,
Key_F13,
Key_F14,
Key_F15,
// Other keys.
Key_Backspace = 8,
Key_Tab,
Key_Clear = 12,
Key_Return,
Key_Shift = 16,
Key_Control,
Key_Alt,
Key_Pause,
Key_CapsLock = 20, // Toggle
Key_Escape = 27,
Key_Space = 32,
Key_Quote = 39,
Key_PageUp = 0xc0,
Key_PageDown,
Key_End,
Key_Home,
Key_Left,
Key_Up,
Key_Right,
Key_Down,
Key_Insert,
Key_Delete,
Key_Help,
Key_Comma = 44,
Key_Minus,
Key_Slash = 47,
Key_Period,
Key_NumLock = 144, // Toggle
Key_ScrollLock = 145, // Toggle
Key_Semicolon = 59,
Key_Equal = 61,
Key_Bar = 192,
Key_BracketLeft = 91,
Key_Backslash,
Key_BracketRight,
Key_OEM_AX = 0xE1, // 'AX' key on Japanese AX keyboard
Key_OEM_102 = 0xE2, // "<>" or "\|" on RT 102-key keyboard.
Key_ICO_HELP = 0xE3, // Help key on ICO
Key_ICO_00 = 0xE4, // 00 key on ICO
Key_Meta,
// Total number of keys.
Key_CodeCount
};
//-----------------------------------------------------------------------------------
class KeyModifiers
{
public:
enum
{
Key_ShiftPressed = 0x01,
Key_CtrlPressed = 0x02,
Key_AltPressed = 0x04,
Key_MetaPressed = 0x08,
Key_CapsToggled = 0x10,
Key_NumToggled = 0x20,
Key_ScrollToggled = 0x40,
Initialized_Bit = 0x80,
Initialized_Mask = 0xFF
};
unsigned char States;
KeyModifiers() : States(0) { }
KeyModifiers(unsigned char st) : States((unsigned char)(st | Initialized_Bit)) { }
void Reset() { States = 0; }
bool IsShiftPressed() const { return (States & Key_ShiftPressed) != 0; }
bool IsCtrlPressed() const { return (States & Key_CtrlPressed) != 0; }
bool IsAltPressed() const { return (States & Key_AltPressed) != 0; }
bool IsMetaPressed() const { return (States & Key_MetaPressed) != 0; }
bool IsCapsToggled() const { return (States & Key_CapsToggled) != 0; }
bool IsNumToggled() const { return (States & Key_NumToggled) != 0; }
bool IsScrollToggled() const{ return (States & Key_ScrollToggled) != 0; }
void SetShiftPressed(bool v = true) { (v) ? States |= Key_ShiftPressed : States &= ~Key_ShiftPressed; }
void SetCtrlPressed(bool v = true) { (v) ? States |= Key_CtrlPressed : States &= ~Key_CtrlPressed; }
void SetAltPressed(bool v = true) { (v) ? States |= Key_AltPressed : States &= ~Key_AltPressed; }
void SetMetaPressed(bool v = true) { (v) ? States |= Key_MetaPressed : States &= ~Key_MetaPressed; }
void SetCapsToggled(bool v = true) { (v) ? States |= Key_CapsToggled : States &= ~Key_CapsToggled; }
void SetNumToggled(bool v = true) { (v) ? States |= Key_NumToggled : States &= ~Key_NumToggled; }
void SetScrollToggled(bool v = true) { (v) ? States |= Key_ScrollToggled: States &= ~Key_ScrollToggled; }
bool IsInitialized() const { return (States & Initialized_Mask) != 0; }
};
//-----------------------------------------------------------------------------------
/*
enum PadKeyCode
{
Pad_None, // Indicates absence of key code.
Pad_Back,
Pad_Start,
Pad_A,
Pad_B,
Pad_X,
Pad_Y,
Pad_R1, // RightShoulder;
Pad_L1, // LeftShoulder;
Pad_R2, // RightTrigger;
Pad_L2, // LeftTrigger;
Pad_Up,
Pad_Down,
Pad_Right,
Pad_Left,
Pad_Plus,
Pad_Minus,
Pad_1,
Pad_2,
Pad_H,
Pad_C,
Pad_Z,
Pad_O,
Pad_T,
Pad_S,
Pad_Select,
Pad_Home,
Pad_RT, // RightThumb;
Pad_LT // LeftThumb;
};
*/
} // OVR
#endif

View file

@ -1,325 +0,0 @@
/************************************************************************************
PublicHeader: OVR
Filename : OVR_List.h
Content : Template implementation for doubly-connected linked List
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_List_h
#define OVR_List_h
#include "OVR_Types.h"
namespace OVR {
//-----------------------------------------------------------------------------------
// ***** ListNode
//
// Base class for the elements of the intrusive linked list.
// To store elements in the List do:
//
// struct MyData : ListNode<MyData>
// {
// . . .
// };
template<class T>
struct ListNode
{
union {
T* pPrev;
void* pVoidPrev;
};
union {
T* pNext;
void* pVoidNext;
};
void RemoveNode()
{
pPrev->pNext = pNext;
pNext->pPrev = pPrev;
}
// Removes us from the list and inserts pnew there instead.
void ReplaceNodeWith(T* pnew)
{
pPrev->pNext = pnew;
pNext->pPrev = pnew;
pnew->pPrev = pPrev;
pnew->pNext = pNext;
}
// Inserts the argument linked list node after us in the list.
void InsertNodeAfter(T* p)
{
p->pPrev = pNext->pPrev; // this
p->pNext = pNext;
pNext->pPrev = p;
pNext = p;
}
// Inserts the argument linked list node before us in the list.
void InsertNodeBefore(T* p)
{
p->pNext = pNext->pPrev; // this
p->pPrev = pPrev;
pPrev->pNext = p;
pPrev = p;
}
void Alloc_MoveTo(ListNode<T>* pdest)
{
pdest->pNext = pNext;
pdest->pPrev = pPrev;
pPrev->pNext = (T*)pdest;
pNext->pPrev = (T*)pdest;
}
};
//------------------------------------------------------------------------
// ***** List
//
// Doubly linked intrusive list.
// The data type must be derived from ListNode.
//
// Adding: PushFront(), PushBack().
// Removing: Remove() - the element must be in the list!
// Moving: BringToFront(), SendToBack() - the element must be in the list!
//
// Iterating:
// MyData* data = MyList.GetFirst();
// while (!MyList.IsNull(data))
// {
// . . .
// data = MyList.GetNext(data);
// }
//
// Removing:
// MyData* data = MyList.GetFirst();
// while (!MyList.IsNull(data))
// {
// MyData* next = MyList.GetNext(data);
// if (ToBeRemoved(data))
// MyList.Remove(data);
// data = next;
// }
//
// List<> represents a doubly-linked list of T, where each T must derive
// from ListNode<B>. B specifies the base class that was directly
// derived from ListNode, and is only necessary if there is an intermediate
// inheritance chain.
template<class T, class B = T> class List
{
public:
typedef T ValueType;
List()
{
Root.pNext = Root.pPrev = (ValueType*)&Root;
}
void Clear()
{
Root.pNext = Root.pPrev = (ValueType*)&Root;
}
const ValueType* GetFirst() const { return (const ValueType*)Root.pNext; }
const ValueType* GetLast () const { return (const ValueType*)Root.pPrev; }
ValueType* GetFirst() { return (ValueType*)Root.pNext; }
ValueType* GetLast () { return (ValueType*)Root.pPrev; }
// Determine if list is empty (i.e.) points to itself.
// Go through void* access to avoid issues with strict-aliasing optimizing out the
// access after RemoveNode(), etc.
bool IsEmpty() const { return Root.pVoidNext == (const T*)(const B*)&Root; }
bool IsFirst(const ValueType* p) const { return p == Root.pNext; }
bool IsLast (const ValueType* p) const { return p == Root.pPrev; }
bool IsNull (const ValueType* p) const { return p == (const T*)(const B*)&Root; }
inline static const ValueType* GetPrev(const ValueType* p) { return (const ValueType*)p->pPrev; }
inline static const ValueType* GetNext(const ValueType* p) { return (const ValueType*)p->pNext; }
inline static ValueType* GetPrev( ValueType* p) { return (ValueType*)p->pPrev; }
inline static ValueType* GetNext( ValueType* p) { return (ValueType*)p->pNext; }
void PushFront(ValueType* p)
{
p->pNext = Root.pNext;
p->pPrev = (ValueType*)&Root;
Root.pNext->pPrev = p;
Root.pNext = p;
}
void PushBack(ValueType* p)
{
p->pPrev = Root.pPrev;
p->pNext = (ValueType*)&Root;
Root.pPrev->pNext = p;
Root.pPrev = p;
}
static void Remove(ValueType* p)
{
p->pPrev->pNext = p->pNext;
p->pNext->pPrev = p->pPrev;
}
void BringToFront(ValueType* p)
{
Remove(p);
PushFront(p);
}
void SendToBack(ValueType* p)
{
Remove(p);
PushBack(p);
}
// Appends the contents of the argument list to the front of this list;
// items are removed from the argument list.
void PushListToFront(List<T>& src)
{
if (!src.IsEmpty())
{
ValueType* pfirst = src.GetFirst();
ValueType* plast = src.GetLast();
src.Clear();
plast->pNext = Root.pNext;
pfirst->pPrev = (ValueType*)&Root;
Root.pNext->pPrev = plast;
Root.pNext = pfirst;
}
}
void PushListToBack(List<T>& src)
{
if (!src.IsEmpty())
{
ValueType* pfirst = src.GetFirst();
ValueType* plast = src.GetLast();
src.Clear();
plast->pNext = (ValueType*)&Root;
pfirst->pPrev = Root.pPrev;
Root.pPrev->pNext = pfirst;
Root.pPrev = plast;
}
}
// Removes all source list items after (and including) the 'pfirst' node from the
// source list and adds them to out list.
void PushFollowingListItemsToFront(List<T>& src, ValueType *pfirst)
{
if (pfirst != &src.Root)
{
ValueType *plast = src.Root.pPrev;
// Remove list remainder from source.
pfirst->pPrev->pNext = (ValueType*)&src.Root;
src.Root.pPrev = pfirst->pPrev;
// Add the rest of the items to list.
plast->pNext = Root.pNext;
pfirst->pPrev = (ValueType*)&Root;
Root.pNext->pPrev = plast;
Root.pNext = pfirst;
}
}
// Removes all source list items up to but NOT including the 'pend' node from the
// source list and adds them to out list.
void PushPrecedingListItemsToFront(List<T>& src, ValueType *ptail)
{
if (src.GetFirst() != ptail)
{
ValueType *pfirst = src.Root.pNext;
ValueType *plast = ptail->pPrev;
// Remove list remainder from source.
ptail->pPrev = (ValueType*)&src.Root;
src.Root.pNext = ptail;
// Add the rest of the items to list.
plast->pNext = Root.pNext;
pfirst->pPrev = (ValueType*)&Root;
Root.pNext->pPrev = plast;
Root.pNext = pfirst;
}
}
// Removes a range of source list items starting at 'pfirst' and up to, but not including 'pend',
// and adds them to out list. Note that source items MUST already be in the list.
void PushListItemsToFront(ValueType *pfirst, ValueType *pend)
{
if (pfirst != pend)
{
ValueType *plast = pend->pPrev;
// Remove list remainder from source.
pfirst->pPrev->pNext = pend;
pend->pPrev = pfirst->pPrev;
// Add the rest of the items to list.
plast->pNext = Root.pNext;
pfirst->pPrev = (ValueType*)&Root;
Root.pNext->pPrev = plast;
Root.pNext = pfirst;
}
}
void Alloc_MoveTo(List<T>* pdest)
{
if (IsEmpty())
pdest->Clear();
else
{
pdest->Root.pNext = Root.pNext;
pdest->Root.pPrev = Root.pPrev;
Root.pNext->pPrev = (ValueType*)&pdest->Root;
Root.pPrev->pNext = (ValueType*)&pdest->Root;
}
}
private:
// Copying is prohibited
List(const List<T>&);
const List<T>& operator = (const List<T>&);
ListNode<B> Root;
};
//------------------------------------------------------------------------
// ***** FreeListElements
//
// Remove all elements in the list and free them in the allocator
template<class List, class Allocator>
void FreeListElements(List& list, Allocator& allocator)
{
typename List::ValueType* self = list.GetFirst();
while(!list.IsNull(self))
{
typename List::ValueType* next = list.GetNext(self);
allocator.Free(self);
self = next;
}
list.Clear();
}
} // OVR
#endif

View file

@ -1,193 +0,0 @@
/************************************************************************************
PublicHeader: OVR
Filename : OVR_Log.h
Content : Logging support
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Log_h
#define OVR_Log_h
#include "OVR_Types.h"
#include <stdarg.h>
namespace OVR {
//-----------------------------------------------------------------------------------
// ***** Logging Constants
// LogMaskConstants defined bit mask constants that describe what log messages
// should be displayed.
enum LogMaskConstants
{
LogMask_Regular = 0x100,
LogMask_Debug = 0x200,
LogMask_None = 0,
LogMask_All = LogMask_Regular|LogMask_Debug
};
// LogMessageType describes the type of the log message, controls when it is
// displayed and what prefix/suffix is given to it. Messages are subdivided into
// regular and debug logging types. Debug logging is only generated in debug builds.
//
// Log_Text - General output text displayed without prefix or new-line.
// Used in OVR libraries for general log flow messages
// such as "Device Initialized".
//
// Log_Error - Error message output with "Error: %s\n", intended for
// application/sample-level use only, in cases where an expected
// operation failed. OVR libraries should not use this internally,
// reporting status codes instead.
//
// Log_DebugText - Message without prefix or new lines; output in Debug build only.
//
// Log_Debug - Debug-build only message, formatted with "Debug: %s\n".
// Intended to comment on incorrect API usage that doesn't lead
// to crashes but can be avoided with proper use.
// There is no Debug Error on purpose, since real errors should
// be handled by API user.
//
// Log_Assert - Debug-build only message, formatted with "Assert: %s\n".
// Intended for severe unrecoverable conditions in library
// source code. Generated though OVR_ASSERT_MSG(c, "Text").
enum LogMessageType
{
// General Logging
Log_Text = LogMask_Regular | 0,
Log_Error = LogMask_Regular | 1, // "Error: %s\n".
// Debug-only messages (not generated in release build)
Log_DebugText = LogMask_Debug | 0,
Log_Debug = LogMask_Debug | 1, // "Debug: %s\n".
Log_Assert = LogMask_Debug | 2, // "Assert: %s\n".
};
// LOG_VAARG_ATTRIBUTE macro, enforces printf-style fromatting for message types
#ifdef __GNUC__
# define OVR_LOG_VAARG_ATTRIBUTE(a,b) __attribute__((format (printf, a, b)))
#else
# define OVR_LOG_VAARG_ATTRIBUTE(a,b)
#endif
//-----------------------------------------------------------------------------------
// ***** Log
// Log defines a base class interface that can be implemented to catch both
// debug and runtime messages.
// Debug logging can be overridden by calling Log::SetGlobalLog.
class Log
{
friend class System;
public:
Log(unsigned logMask = LogMask_Debug) : LoggingMask(logMask) { }
virtual ~Log();
// Log formating buffer size used by default LogMessageVarg. Longer strings are truncated.
enum { MaxLogBufferMessageSize = 2048 };
unsigned GetLoggingMask() const { return LoggingMask; }
void SetLoggingMask(unsigned logMask) { LoggingMask = logMask; }
// 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);
// 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);
// 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,
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.
static void DefaultLogOutput(const char* textBuffer, bool debug);
// Determines if the specified message type is for debugging only.
static bool IsDebugMessage(LogMessageType messageType)
{
return (messageType & LogMask_Debug) != 0;
}
// *** Global APIs
// Global Log registration APIs.
// - Global log is used for OVR_DEBUG messages. Set global log to null (0)
// to disable all logging.
static void SetGlobalLog(Log *log);
static Log* GetGlobalLog();
// Returns default log singleton instance.
static Log* GetDefaultLog();
// Applies logMask to the default log and returns a pointer to it.
// By default, only Debug logging is enabled, so to avoid SDK generating console
// messages in user app (those are always disabled in release build,
// even if the flag is set). This function is useful in System constructor.
static Log* ConfigureDefaultLog(unsigned logMask = LogMask_Debug)
{
Log* log = GetDefaultLog();
log->SetLoggingMask(logMask);
return log;
}
private:
// Logging mask described by LogMaskConstants.
unsigned LoggingMask;
};
//-----------------------------------------------------------------------------------
// ***** Global Logging Functions and Debug Macros
// These functions will output text to global log with semantics described by
// their LogMessageType.
void LogText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
void LogError(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
#ifdef OVR_BUILD_DEBUG
// Debug build only logging.
void LogDebugText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
void LogDebug(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
void LogAssert(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
// Macro to do debug logging, printf-style.
// An extra set of set of parenthesis must be used around arguments,
// as in: OVR_LOG_DEBUG(("Value %d", 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)
#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)
#endif
} // OVR
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,522 +0,0 @@
/************************************************************************************
PublicHeader: Kernel
Filename : OVR_RefCount.h
Content : Reference counting implementation headers
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_RefCount_h
#define OVR_RefCount_h
#include "OVR_Types.h"
#include "OVR_Allocator.h"
namespace OVR {
//-----------------------------------------------------------------------------------
// ***** Reference Counting
// There are three types of reference counting base classes:
//
// RefCountBase - Provides thread-safe reference counting (Default).
// RefCountBaseNTS - Non Thread Safe version of reference counting.
// ***** Declared classes
template<class C>
class RefCountBase;
template<class C>
class RefCountBaseNTS;
class RefCountImpl;
class RefCountNTSImpl;
//-----------------------------------------------------------------------------------
// ***** Implementation For Reference Counting
// RefCountImplCore holds RefCount value and defines a few utility
// functions shared by all implementations.
class RefCountImplCore
{
protected:
volatile int RefCount;
public:
// RefCountImpl constructor always initializes RefCount to 1 by default.
OVR_FORCE_INLINE RefCountImplCore() : RefCount(1) { }
// Need virtual destructor
// This: 1. Makes sure the right destructor's called.
// 2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem()
virtual ~RefCountImplCore();
// Debug method only.
int GetRefCount() const { return RefCount; }
// This logic is used to detect invalid 'delete' calls of reference counted
// objects. Direct delete calls are not allowed on them unless they come in
// internally from Release.
#ifdef OVR_BUILD_DEBUG
static void OVR_CDECL reportInvalidDelete(void *pmem);
inline static void checkInvalidDelete(RefCountImplCore *pmem)
{
if (pmem->RefCount != 0)
reportInvalidDelete(pmem);
}
#else
inline static void checkInvalidDelete(RefCountImplCore *) { }
#endif
// Base class ref-count content should not be copied.
void operator = (const RefCountImplCore &) { }
};
class RefCountNTSImplCore
{
protected:
mutable int RefCount;
public:
// RefCountImpl constructor always initializes RefCount to 1 by default.
OVR_FORCE_INLINE RefCountNTSImplCore() : RefCount(1) { }
// Need virtual destructor
// This: 1. Makes sure the right destructor's called.
// 2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem()
virtual ~RefCountNTSImplCore();
// Debug method only.
int GetRefCount() const { return RefCount; }
// This logic is used to detect invalid 'delete' calls of reference counted
// objects. Direct delete calls are not allowed on them unless they come in
// internally from Release.
#ifdef OVR_BUILD_DEBUG
static void OVR_CDECL reportInvalidDelete(void *pmem);
OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *pmem)
{
if (pmem->RefCount != 0)
reportInvalidDelete(pmem);
}
#else
OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *) { }
#endif
// Base class ref-count content should not be copied.
void operator = (const RefCountNTSImplCore &) { }
};
// RefCountImpl provides Thread-Safe implementation of reference counting, so
// it should be used by default in most places.
class RefCountImpl : public RefCountImplCore
{
public:
// Thread-Safe Ref-Count Implementation.
void AddRef();
void Release();
};
// RefCountVImpl provides Thread-Safe implementation of reference counting, plus,
// virtual AddRef and Release.
class RefCountVImpl : public RefCountImplCore
{
public:
// Thread-Safe Ref-Count Implementation.
virtual void AddRef();
virtual void Release();
};
// RefCountImplNTS provides Non-Thread-Safe implementation of reference counting,
// which is slightly more efficient since it doesn't use atomics.
class RefCountNTSImpl : public RefCountNTSImplCore
{
public:
OVR_FORCE_INLINE void AddRef() const { RefCount++; }
void Release() const;
};
// RefCountBaseStatImpl<> is a common class that adds new/delete override with Stat tracking
// to the reference counting implementation. Base must be one of the RefCountImpl classes.
template<class Base>
class RefCountBaseStatImpl : public Base
{
public:
RefCountBaseStatImpl() { }
// *** Override New and Delete
// DOM-IGNORE-BEGIN
// Undef new temporarily if it is being redefined
#ifdef OVR_DEFINE_NEW
#undef new
#endif
#ifdef OVR_BUILD_DEBUG
// Custom check used to detect incorrect calls of 'delete' on ref-counted objects.
#define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) \
do {if (p) Base::checkInvalidDelete((class_name*)p); } while(0)
#else
#define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p)
#endif
// Redefine all new & delete operators.
OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE)
#ifdef OVR_DEFINE_NEW
#define new OVR_DEFINE_NEW
#endif
// OVR_BUILD_DEFINE_NEW
// DOM-IGNORE-END
};
//-----------------------------------------------------------------------------------
// *** End user RefCountBase<> classes
// RefCountBase is a base class for classes that require thread-safe reference
// counting; it also overrides the new and delete operators to use MemoryHeap.
//
// Reference counted objects start out with RefCount value of 1. Further lifetime
// management is done through the AddRef() and Release() methods, typically
// hidden by Ptr<>.
template<class C>
class RefCountBase : public RefCountBaseStatImpl<RefCountImpl>
{
public:
// Constructor.
OVR_FORCE_INLINE RefCountBase() : RefCountBaseStatImpl<RefCountImpl>() { }
};
// RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release
template<class C>
class RefCountBaseV : public RefCountBaseStatImpl<RefCountVImpl>
{
public:
// Constructor.
OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatImpl<RefCountVImpl>() { }
};
// RefCountBaseNTS is a base class for classes that require Non-Thread-Safe reference
// counting; it also overrides the new and delete operators to use MemoryHeap.
// This class should only be used if all pointers to it are known to be assigned,
// destroyed and manipulated within one thread.
//
// Reference counted objects start out with RefCount value of 1. Further lifetime
// management is done through the AddRef() and Release() methods, typically
// hidden by Ptr<>.
template<class C>
class RefCountBaseNTS : public RefCountBaseStatImpl<RefCountNTSImpl>
{
public:
// Constructor.
OVR_FORCE_INLINE RefCountBaseNTS() : RefCountBaseStatImpl<RefCountNTSImpl>() { }
};
//-----------------------------------------------------------------------------------
// ***** Pickable template pointer
enum PickType { PickValue };
template <typename T>
class Pickable
{
public:
Pickable() : pV(NULL) {}
explicit Pickable(T* p) : pV(p) {}
Pickable(T* p, PickType) : pV(p)
{
OVR_ASSERT(pV);
if (pV)
pV->AddRef();
}
template <typename OT>
Pickable(const Pickable<OT>& other) : pV(other.GetPtr()) {}
public:
Pickable& operator =(const Pickable& other)
{
OVR_ASSERT(pV == NULL);
pV = other.pV;
// Extra check.
//other.pV = NULL;
return *this;
}
public:
T* GetPtr() const { return pV; }
T* operator->() const
{
return pV;
}
T& operator*() const
{
OVR_ASSERT(pV);
return *pV;
}
private:
T* pV;
};
template <typename T>
OVR_FORCE_INLINE
Pickable<T> MakePickable(T* p)
{
return Pickable<T>(p);
}
//-----------------------------------------------------------------------------------
// ***** Ref-Counted template pointer
// Automatically AddRefs and Releases interfaces
void* ReturnArg0(void* p);
template<class C>
class Ptr
{
#ifdef OVR_CC_ARM
static C* ReturnArg(void* p) { return (C*)ReturnArg0(p); }
#endif
protected:
C *pObject;
public:
// Constructors
OVR_FORCE_INLINE Ptr() : pObject(0)
{ }
#ifdef OVR_CC_ARM
OVR_FORCE_INLINE Ptr(C &robj) : pObject(ReturnArg(&robj))
#else
OVR_FORCE_INLINE Ptr(C &robj) : pObject(&robj)
#endif
{ }
OVR_FORCE_INLINE Ptr(Pickable<C> v) : pObject(v.GetPtr())
{
// No AddRef() on purpose.
}
OVR_FORCE_INLINE Ptr(Ptr<C>& other, PickType) : pObject(other.pObject)
{
other.pObject = NULL;
// No AddRef() on purpose.
}
OVR_FORCE_INLINE Ptr(C *pobj)
{
if (pobj) pobj->AddRef();
pObject = pobj;
}
OVR_FORCE_INLINE Ptr(const Ptr<C> &src)
{
if (src.pObject) src.pObject->AddRef();
pObject = src.pObject;
}
template<class R>
OVR_FORCE_INLINE Ptr(Ptr<R> &src)
{
if (src) src->AddRef();
pObject = src;
}
template<class R>
OVR_FORCE_INLINE Ptr(Pickable<R> v) : pObject(v.GetPtr())
{
// No AddRef() on purpose.
}
// Destructor
OVR_FORCE_INLINE ~Ptr()
{
if (pObject) pObject->Release();
}
// Compares
OVR_FORCE_INLINE bool operator == (const Ptr &other) const { return pObject == other.pObject; }
OVR_FORCE_INLINE bool operator != (const Ptr &other) const { return pObject != other.pObject; }
OVR_FORCE_INLINE bool operator == (C *pother) const { return pObject == pother; }
OVR_FORCE_INLINE bool operator != (C *pother) const { return pObject != pother; }
OVR_FORCE_INLINE bool operator < (const Ptr &other) const { return pObject < other.pObject; }
// Assignment
template<class R>
OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<R> &src)
{
if (src) src->AddRef();
if (pObject) pObject->Release();
pObject = src;
return *this;
}
// Specialization
OVR_FORCE_INLINE const Ptr<C>& operator = (const Ptr<C> &src)
{
if (src) src->AddRef();
if (pObject) pObject->Release();
pObject = src;
return *this;
}
OVR_FORCE_INLINE const Ptr<C>& operator = (C *psrc)
{
if (psrc) psrc->AddRef();
if (pObject) pObject->Release();
pObject = psrc;
return *this;
}
OVR_FORCE_INLINE const Ptr<C>& operator = (C &src)
{
if (pObject) pObject->Release();
pObject = &src;
return *this;
}
OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<C> src)
{
return Pick(src);
}
template<class R>
OVR_FORCE_INLINE Ptr<C>& operator = (Pickable<R> src)
{
return Pick(src);
}
// Set Assignment
template<class R>
OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<R> &src)
{
if (src) src->AddRef();
if (pObject) pObject->Release();
pObject = src;
return *this;
}
// Specialization
OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<C> &src)
{
if (src) src->AddRef();
if (pObject) pObject->Release();
pObject = src;
return *this;
}
OVR_FORCE_INLINE Ptr<C>& SetPtr(C *psrc)
{
if (psrc) psrc->AddRef();
if (pObject) pObject->Release();
pObject = psrc;
return *this;
}
OVR_FORCE_INLINE Ptr<C>& SetPtr(C &src)
{
if (pObject) pObject->Release();
pObject = &src;
return *this;
}
OVR_FORCE_INLINE Ptr<C>& SetPtr(Pickable<C> src)
{
return Pick(src);
}
// Nulls ref-counted pointer without decrement
OVR_FORCE_INLINE void NullWithoutRelease()
{
pObject = 0;
}
// Clears the pointer to the object
OVR_FORCE_INLINE void Clear()
{
if (pObject) pObject->Release();
pObject = 0;
}
// Obtain pointer reference directly, for D3D interfaces
OVR_FORCE_INLINE C*& GetRawRef() { return pObject; }
// Access Operators
OVR_FORCE_INLINE C* GetPtr() const { return pObject; }
OVR_FORCE_INLINE C& operator * () const { return *pObject; }
OVR_FORCE_INLINE C* operator -> () const { return pObject; }
// Conversion
OVR_FORCE_INLINE operator C* () const { return pObject; }
// Pickers.
// Pick a value.
OVR_FORCE_INLINE Ptr<C>& Pick(Ptr<C>& other)
{
if (&other != this)
{
if (pObject) pObject->Release();
pObject = other.pObject;
other.pObject = 0;
}
return *this;
}
OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<C> v)
{
if (v.GetPtr() != pObject)
{
if (pObject) pObject->Release();
pObject = v.GetPtr();
}
return *this;
}
template<class R>
OVR_FORCE_INLINE Ptr<C>& Pick(Pickable<R> v)
{
if (v.GetPtr() != pObject)
{
if (pObject) pObject->Release();
pObject = v.GetPtr();
}
return *this;
}
OVR_FORCE_INLINE Ptr<C>& Pick(C* p)
{
if (p != pObject)
{
if (pObject) pObject->Release();
pObject = p;
}
return *this;
}
};
} // OVR
#endif

View file

@ -1,503 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_Std.h
Content : Standard C function interface
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Std_h
#define OVR_Std_h
#include "OVR_Types.h"
#include <stdarg.h> // for va_list args
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#if !defined(OVR_OS_WINCE) && defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
#define OVR_MSVC_SAFESTRING
#include <errno.h>
#endif
// Wide-char funcs
#include <wchar.h>
#include <wctype.h>
namespace OVR {
#if defined(OVR_OS_WIN32)
inline char* OVR_CDECL OVR_itoa(int val, char *dest, UPInt destsize, int radix)
{
#if defined(OVR_MSVC_SAFESTRING)
_itoa_s(val, dest, destsize, radix);
return dest;
#else
OVR_UNUSED(destsize);
return itoa(val, dest, radix);
#endif
}
#else // OVR_OS_WIN32
inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix)
{
if (val == 0)
{
if (len > 1)
{
dest[0] = '0';
dest[1] = '\0';
}
return dest;
}
int cur = val;
unsigned int i = 0;
unsigned int sign = 0;
if (val < 0)
{
val = -val;
sign = 1;
}
while ((val != 0) && (i < (len - 1 - sign)))
{
cur = val % radix;
val /= radix;
if (radix == 16)
{
switch(cur)
{
case 10:
dest[i] = 'a';
break;
case 11:
dest[i] = 'b';
break;
case 12:
dest[i] = 'c';
break;
case 13:
dest[i] = 'd';
break;
case 14:
dest[i] = 'e';
break;
case 15:
dest[i] = 'f';
break;
default:
dest[i] = (char)('0' + cur);
break;
}
}
else
{
dest[i] = (char)('0' + cur);
}
++i;
}
if (sign)
{
dest[i++] = '-';
}
for (unsigned int j = 0; j < i / 2; ++j)
{
char tmp = dest[j];
dest[j] = dest[i - 1 - j];
dest[i - 1 - j] = tmp;
}
dest[i] = '\0';
return dest;
}
#endif
// String functions
inline UPInt OVR_CDECL OVR_strlen(const char* str)
{
return strlen(str);
}
inline char* OVR_CDECL OVR_strcpy(char* dest, UPInt destsize, const char* src)
{
#if defined(OVR_MSVC_SAFESTRING)
strcpy_s(dest, destsize, src);
return dest;
#else
OVR_UNUSED(destsize);
return strcpy(dest, src);
#endif
}
inline char* OVR_CDECL OVR_strncpy(char* dest, UPInt destsize, const char* src, UPInt count)
{
#if defined(OVR_MSVC_SAFESTRING)
strncpy_s(dest, destsize, src, count);
return dest;
#else
OVR_UNUSED(destsize);
return strncpy(dest, src, count);
#endif
}
inline char * OVR_CDECL OVR_strcat(char* dest, UPInt destsize, const char* src)
{
#if defined(OVR_MSVC_SAFESTRING)
strcat_s(dest, destsize, src);
return dest;
#else
OVR_UNUSED(destsize);
return strcat(dest, src);
#endif
}
inline int OVR_CDECL OVR_strcmp(const char* dest, const char* src)
{
return strcmp(dest, src);
}
inline const char* OVR_CDECL OVR_strchr(const char* str, char c)
{
return strchr(str, c);
}
inline char* OVR_CDECL OVR_strchr(char* str, char c)
{
return strchr(str, c);
}
inline const char* OVR_strrchr(const char* str, char c)
{
UPInt len = OVR_strlen(str);
for (UPInt i=len; i>0; i--)
if (str[i]==c)
return str+i;
return 0;
}
inline const UByte* OVR_CDECL OVR_memrchr(const UByte* str, UPInt size, UByte c)
{
for (SPInt i = (SPInt)size - 1; i >= 0; i--)
{
if (str[i] == c)
return str + i;
}
return 0;
}
inline char* OVR_CDECL OVR_strrchr(char* str, char c)
{
UPInt len = OVR_strlen(str);
for (UPInt i=len; i>0; i--)
if (str[i]==c)
return str+i;
return 0;
}
double OVR_CDECL OVR_strtod(const char* string, char** tailptr);
inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix)
{
return strtol(string, tailptr, radix);
}
inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix)
{
return strtoul(string, tailptr, radix);
}
inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, UPInt size)
{
return strncmp(ws1, ws2, size);
}
inline UInt64 OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base)
{
#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
return _strtoui64(nptr, endptr, base);
#else
return strtoull(nptr, endptr, base);
#endif
}
inline SInt64 OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base)
{
#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
return _strtoi64(nptr, endptr, base);
#else
return strtoll(nptr, endptr, base);
#endif
}
inline SInt64 OVR_CDECL OVR_atoq(const char* string)
{
#if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
return _atoi64(string);
#else
return atoll(string);
#endif
}
inline UInt64 OVR_CDECL OVR_atouq(const char* string)
{
return OVR_strtouq(string, NULL, 10);
}
// Implemented in GStd.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, UPInt count);
inline UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char* format, ...)
{
va_list argList;
va_start(argList,format);
UPInt ret;
#if defined(OVR_CC_MSVC)
#if defined(OVR_MSVC_SAFESTRING)
ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
OVR_ASSERT(ret != -1);
#else
OVR_UNUSED(destsize);
ret = _vsnprintf(dest, destsize - 1, format, argList); // -1 for space for the null character
OVR_ASSERT(ret != -1);
dest[destsize-1] = 0;
#endif
#else
OVR_UNUSED(destsize);
ret = vsprintf(dest, format, argList);
OVR_ASSERT(ret < destsize);
#endif
va_end(argList);
return ret;
}
inline UPInt OVR_CDECL OVR_vsprintf(char *dest, UPInt destsize, const char * format, va_list argList)
{
UPInt ret;
#if defined(OVR_CC_MSVC)
#if defined(OVR_MSVC_SAFESTRING)
dest[0] = '\0';
int rv = vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
if (rv == -1)
{
dest[destsize - 1] = '\0';
ret = destsize - 1;
}
else
ret = (UPInt)rv;
#else
OVR_UNUSED(destsize);
int rv = _vsnprintf(dest, destsize - 1, format, argList);
OVR_ASSERT(rv != -1);
ret = (UPInt)rv;
dest[destsize-1] = 0;
#endif
#else
OVR_UNUSED(destsize);
ret = (UPInt)vsprintf(dest, format, argList);
OVR_ASSERT(ret < destsize);
#endif
return ret;
}
// Returns the number of characters in the formatted string.
inline UPInt OVR_CDECL OVR_vscprintf(const char * format, va_list argList)
{
UPInt ret;
#if defined(OVR_CC_MSVC)
ret = (UPInt) _vscprintf(format, argList);
#else
ret = (UPInt) vsnprintf(NULL, 0, format, argList);
#endif
return ret;
}
wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, UPInt destsize, const wchar_t* src);
wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src, UPInt count);
wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src);
UPInt OVR_CDECL OVR_wcslen(const wchar_t* str);
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);
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
#else
// not supported, use regular wcsicmp
return OVR_wcsicmp(a, b);
#endif
}
inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b)
{
#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX)
return wcscoll(a, b);
#else
// not supported, use regular wcscmp
return OVR_wcscmp(a, b);
#endif
}
#ifndef OVR_NO_WCTYPE
inline int OVR_CDECL UnicodeCharIs(const UInt16* table, wchar_t charCode)
{
unsigned offset = table[charCode >> 8];
if (offset == 0) return 0;
if (offset == 1) return 1;
return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0;
}
extern const UInt16 UnicodeAlnumBits[];
extern const UInt16 UnicodeAlphaBits[];
extern const UInt16 UnicodeDigitBits[];
extern const UInt16 UnicodeSpaceBits[];
extern const UInt16 UnicodeXDigitBits[];
// Uncomment if necessary
//extern const UInt16 UnicodeCntrlBits[];
//extern const UInt16 UnicodeGraphBits[];
//extern const UInt16 UnicodeLowerBits[];
//extern const UInt16 UnicodePrintBits[];
//extern const UInt16 UnicodePunctBits[];
//extern const UInt16 UnicodeUpperBits[];
inline int OVR_CDECL OVR_iswalnum (wchar_t charCode) { return UnicodeCharIs(UnicodeAlnumBits, charCode); }
inline int OVR_CDECL OVR_iswalpha (wchar_t charCode) { return UnicodeCharIs(UnicodeAlphaBits, charCode); }
inline int OVR_CDECL OVR_iswdigit (wchar_t charCode) { return UnicodeCharIs(UnicodeDigitBits, charCode); }
inline int OVR_CDECL OVR_iswspace (wchar_t charCode) { return UnicodeCharIs(UnicodeSpaceBits, charCode); }
inline int OVR_CDECL OVR_iswxdigit(wchar_t charCode) { return UnicodeCharIs(UnicodeXDigitBits, charCode); }
// Uncomment if necessary
//inline int OVR_CDECL OVR_iswcntrl (wchar_t charCode) { return UnicodeCharIs(UnicodeCntrlBits, charCode); }
//inline int OVR_CDECL OVR_iswgraph (wchar_t charCode) { return UnicodeCharIs(UnicodeGraphBits, charCode); }
//inline int OVR_CDECL OVR_iswlower (wchar_t charCode) { return UnicodeCharIs(UnicodeLowerBits, charCode); }
//inline int OVR_CDECL OVR_iswprint (wchar_t charCode) { return UnicodeCharIs(UnicodePrintBits, charCode); }
//inline int OVR_CDECL OVR_iswpunct (wchar_t charCode) { return UnicodeCharIs(UnicodePunctBits, charCode); }
//inline int OVR_CDECL OVR_iswupper (wchar_t charCode) { return UnicodeCharIs(UnicodeUpperBits, charCode); }
int OVR_CDECL OVR_towupper(wchar_t charCode);
int OVR_CDECL OVR_towlower(wchar_t charCode);
#else // OVR_NO_WCTYPE
inline int OVR_CDECL OVR_iswspace(wchar_t c)
{
return iswspace(c);
}
inline int OVR_CDECL OVR_iswdigit(wchar_t c)
{
return iswdigit(c);
}
inline int OVR_CDECL OVR_iswxdigit(wchar_t c)
{
return iswxdigit(c);
}
inline int OVR_CDECL OVR_iswalpha(wchar_t c)
{
return iswalpha(c);
}
inline int OVR_CDECL OVR_iswalnum(wchar_t c)
{
return iswalnum(c);
}
inline wchar_t OVR_CDECL OVR_towlower(wchar_t c)
{
return (wchar_t)towlower(c);
}
inline wchar_t OVR_towupper(wchar_t c)
{
return (wchar_t)towupper(c);
}
#endif // OVR_NO_WCTYPE
// ASCII versions of tolower and toupper. Don't use "char"
inline int OVR_CDECL OVR_tolower(int c)
{
return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c;
}
inline int OVR_CDECL OVR_toupper(int c)
{
return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
}
inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr)
{
#if defined(OVR_OS_OTHER)
OVR_UNUSED(tailptr);
char buffer[64];
char* tp = NULL;
UPInt max = OVR_wcslen(string);
if (max > 63) max = 63;
unsigned char c = 0;
for (UPInt i=0; i < max; i++)
{
c = (unsigned char)string[i];
buffer[i] = ((c) < 128 ? (char)c : '!');
}
buffer[max] = 0;
return OVR_strtod(buffer, &tp);
#else
return wcstod(string, tailptr);
#endif
}
inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int radix)
{
#if defined(OVR_OS_OTHER)
OVR_UNUSED(tailptr);
char buffer[64];
char* tp = NULL;
UPInt max = OVR_wcslen(string);
if (max > 63) max = 63;
unsigned char c = 0;
for (UPInt i=0; i < max; i++)
{
c = (unsigned char)string[i];
buffer[i] = ((c) < 128 ? (char)c : '!');
}
buffer[max] = 0;
return strtol(buffer, &tp, radix);
#else
return wcstol(string, tailptr, radix);
#endif
}
} // OVR
#endif // OVR_Std_h

View file

@ -1,645 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_String.h
Content : String UTF8 string implementation with copy-on-write semantics
(thread-safe for assignment but not modification).
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_String_h
#define OVR_String_h
#include "OVR_Types.h"
#include "OVR_Allocator.h"
#include "OVR_UTF8Util.h"
#include "OVR_Atomic.h"
#include "OVR_Std.h"
#include "OVR_Alg.h"
namespace OVR {
// ***** Classes
class String;
class StringBuffer;
//-----------------------------------------------------------------------------------
// ***** String Class
// String is UTF8 based string class with copy-on-write implementation
// for assignment.
class String
{
protected:
enum FlagConstants
{
//Flag_GetLength = 0x7FFFFFFF,
// This flag is set if GetLength() == GetSize() for a string.
// Avoid extra scanning is Substring and indexing logic.
Flag_LengthIsSizeShift = (sizeof(UPInt)*8 - 1)
};
// Internal structure to hold string data
struct DataDesc
{
// Number of bytes. Will be the same as the number of chars if the characters
// are ascii, may not be equal to number of chars in case string data is UTF8.
UPInt Size;
volatile SInt32 RefCount;
char Data[1];
void AddRef()
{
AtomicOps<SInt32>::ExchangeAdd_NoSync(&RefCount, 1);
}
// Decrement ref count. This needs to be thread-safe, since
// a different thread could have also decremented the ref count.
// For example, if u start off with a ref count = 2. Now if u
// decrement the ref count and check against 0 in different
// statements, a different thread can also decrement the ref count
// in between our decrement and checking against 0 and will find
// the ref count = 0 and delete the object. This will lead to a crash
// when context switches to our thread and we'll be trying to delete
// an already deleted object. Hence decrementing the ref count and
// checking against 0 needs to made an atomic operation.
void Release()
{
if ((AtomicOps<SInt32>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
OVR_FREE(this);
}
static UPInt GetLengthFlagBit() { return UPInt(1) << Flag_LengthIsSizeShift; }
UPInt GetSize() const { return Size & ~GetLengthFlagBit() ; }
UPInt GetLengthFlag() const { return Size & GetLengthFlagBit(); }
bool LengthIsSize() const { return GetLengthFlag() != 0; }
};
// Heap type of the string is encoded in the lower bits.
enum HeapType
{
HT_Global = 0, // Heap is global.
HT_Local = 1, // SF::String_loc: Heap is determined based on string's address.
HT_Dynamic = 2, // SF::String_temp: Heap is stored as a part of the class.
HT_Mask = 3
};
union {
DataDesc* pData;
UPInt HeapTypeBits;
};
typedef union {
DataDesc* pData;
UPInt HeapTypeBits;
} DataDescUnion;
inline HeapType GetHeapType() const { return (HeapType) (HeapTypeBits & HT_Mask); }
inline DataDesc* GetData() const
{
DataDescUnion u;
u.pData = pData;
u.HeapTypeBits = (u.HeapTypeBits & ~(UPInt)HT_Mask);
return u.pData;
}
inline void SetData(DataDesc* pdesc)
{
HeapType ht = GetHeapType();
pData = pdesc;
OVR_ASSERT((HeapTypeBits & HT_Mask) == 0);
HeapTypeBits |= ht;
}
DataDesc* AllocData(UPInt size, UPInt lengthIsSize);
DataDesc* AllocDataCopy1(UPInt size, UPInt lengthIsSize,
const char* pdata, UPInt copySize);
DataDesc* AllocDataCopy2(UPInt size, UPInt lengthIsSize,
const char* pdata1, UPInt copySize1,
const char* pdata2, UPInt copySize2);
// Special constructor to avoid data initalization when used in derived class.
struct NoConstructor { };
String(const NoConstructor&) { }
public:
// For initializing string with dynamic buffer
struct InitStruct
{
virtual ~InitStruct() { }
virtual void InitString(char* pbuffer, UPInt size) const = 0;
};
// Constructors / Destructors.
String();
String(const char* data);
String(const char* data1, const char* pdata2, const char* pdata3 = 0);
String(const char* data, UPInt buflen);
String(const String& src);
String(const StringBuffer& src);
String(const InitStruct& src, UPInt size);
explicit String(const wchar_t* data);
// Destructor (Captain Obvious guarantees!)
~String()
{
GetData()->Release();
}
// Declaration of NullString
static DataDesc NullData;
// *** General Functions
void Clear();
// For casting to a pointer to char.
operator const char*() const { return GetData()->Data; }
// Pointer to raw buffer.
const char* ToCStr() const { return GetData()->Data; }
// Returns number of bytes
UPInt GetSize() const { return GetData()->GetSize() ; }
// Tells whether or not the string is empty
bool IsEmpty() const { return GetSize() == 0; }
// Returns number of characters
UPInt GetLength() const;
// Returns character at the specified index
UInt32 GetCharAt(UPInt index) const;
UInt32 GetFirstCharAt(UPInt index, const char** offset) const;
UInt32 GetNextChar(const char** offset) const;
// Appends a character
void AppendChar(UInt32 ch);
// Append a string
void AppendString(const wchar_t* pstr, SPInt len = -1);
void AppendString(const char* putf8str, SPInt utf8StrSz = -1);
// Assigned a string with dynamic data (copied through initializer).
void AssignString(const InitStruct& src, UPInt size);
// Assigns string with known size.
void AssignString(const char* putf8str, UPInt size);
// Resize the string to the new size
// void Resize(UPInt _size);
// Removes the character at posAt
void Remove(UPInt posAt, SPInt len = 1);
// Returns a String that's a substring of this.
// -start is the index of the first UTF8 character you want to include.
// -end is the index one past the last UTF8 character you want to include.
String Substring(UPInt start, UPInt end) const;
// Case-conversion
String ToUpper() const;
String ToLower() const;
// Inserts substr at posAt
String& Insert (const char* substr, UPInt posAt, SPInt len = -1);
// Inserts character at posAt
UPInt InsertCharAt(UInt32 c, UPInt posAt);
// Inserts substr at posAt, which is an index of a character (not byte).
// Of size is specified, it is in bytes.
// String& Insert(const UInt32* substr, UPInt posAt, SPInt size = -1);
// Get Byte index of the character at position = index
UPInt GetByteIndex(UPInt index) const { return (UPInt)UTF8Util::GetByteIndex(index, GetData()->Data); }
// Utility: case-insensitive string compare. stricmp() & strnicmp() are not
// ANSI or POSIX, do not seem to appear in Linux.
static int OVR_STDCALL CompareNoCase(const char* a, const char* b);
static int OVR_STDCALL CompareNoCase(const char* a, const char* b, SPInt len);
// Hash function, case-insensitive
static UPInt OVR_STDCALL BernsteinHashFunctionCIS(const void* pdataIn, UPInt size, UPInt seed = 5381);
// Hash function, case-sensitive
static UPInt OVR_STDCALL BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed = 5381);
// ***** File path parsing helper functions.
// Implemented in OVR_String_FilePath.cpp.
// Absolute paths can star with:
// - protocols: 'file://', 'http://'
// - windows drive: 'c:\'
// - UNC share name: '\\share'
// - unix root '/'
static bool HasAbsolutePath(const char* path);
static bool HasExtension(const char* path);
static bool HasProtocol(const char* path);
bool HasAbsolutePath() const { return HasAbsolutePath(ToCStr()); }
bool HasExtension() const { return HasExtension(ToCStr()); }
bool HasProtocol() const { return HasProtocol(ToCStr()); }
String GetProtocol() const; // Returns protocol, if any, with trailing '://'.
String GetPath() const; // Returns path with trailing '/'.
String GetFilename() const; // Returns filename, including extension.
String GetExtension() const; // Returns extension with a dot.
void StripProtocol(); // Strips front protocol, if any, from the string.
void StripExtension(); // Strips off trailing extension.
// Operators
// Assignment
void operator = (const char* str);
void operator = (const wchar_t* str);
void operator = (const String& src);
void operator = (const StringBuffer& src);
// Addition
void operator += (const String& src);
void operator += (const char* psrc) { AppendString(psrc); }
void operator += (const wchar_t* psrc) { AppendString(psrc); }
void operator += (char ch) { AppendChar(ch); }
String operator + (const char* str) const;
String operator + (const String& src) const;
// Comparison
bool operator == (const String& str) const
{
return (OVR_strcmp(GetData()->Data, str.GetData()->Data)== 0);
}
bool operator != (const String& str) const
{
return !operator == (str);
}
bool operator == (const char* str) const
{
return OVR_strcmp(GetData()->Data, str) == 0;
}
bool operator != (const char* str) const
{
return !operator == (str);
}
bool operator < (const char* pstr) const
{
return OVR_strcmp(GetData()->Data, pstr) < 0;
}
bool operator < (const String& str) const
{
return *this < str.GetData()->Data;
}
bool operator > (const char* pstr) const
{
return OVR_strcmp(GetData()->Data, pstr) > 0;
}
bool operator > (const String& str) const
{
return *this > str.GetData()->Data;
}
int CompareNoCase(const char* pstr) const
{
return CompareNoCase(GetData()->Data, pstr);
}
int CompareNoCase(const String& str) const
{
return CompareNoCase(GetData()->Data, str.ToCStr());
}
// Accesses raw bytes
const char& operator [] (int index) const
{
OVR_ASSERT(index >= 0 && (UPInt)index < GetSize());
return GetData()->Data[index];
}
const char& operator [] (UPInt index) const
{
OVR_ASSERT(index < GetSize());
return GetData()->Data[index];
}
// Case insensitive keys are used to look up insensitive string in hash tables
// for SWF files with version before SWF 7.
struct NoCaseKey
{
const String* pStr;
NoCaseKey(const String &str) : pStr(&str){};
};
bool operator == (const NoCaseKey& strKey) const
{
return (CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0);
}
bool operator != (const NoCaseKey& strKey) const
{
return !(CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0);
}
// Hash functor used for strings.
struct HashFunctor
{
UPInt operator()(const String& data) const
{
UPInt size = data.GetSize();
return String::BernsteinHashFunction((const char*)data, size);
}
};
// Case-insensitive hash functor used for strings. Supports additional
// lookup based on NoCaseKey.
struct NoCaseHashFunctor
{
UPInt operator()(const String& data) const
{
UPInt size = data.GetSize();
return String::BernsteinHashFunctionCIS((const char*)data, size);
}
UPInt operator()(const NoCaseKey& data) const
{
UPInt size = data.pStr->GetSize();
return String::BernsteinHashFunctionCIS((const char*)data.pStr->ToCStr(), size);
}
};
};
//-----------------------------------------------------------------------------------
// ***** String Buffer used for Building Strings
class StringBuffer
{
char* pData;
UPInt Size;
UPInt BufferSize;
UPInt GrowSize;
mutable bool LengthIsSize;
public:
// Constructors / Destructor.
StringBuffer();
explicit StringBuffer(UPInt growSize);
StringBuffer(const char* data);
StringBuffer(const char* data, UPInt buflen);
StringBuffer(const String& src);
StringBuffer(const StringBuffer& src);
explicit StringBuffer(const wchar_t* data);
~StringBuffer();
// Modify grow size used for growing/shrinking the buffer.
UPInt GetGrowSize() const { return GrowSize; }
void SetGrowSize(UPInt growSize);
// *** General Functions
// Does not release memory, just sets Size to 0
void Clear();
// For casting to a pointer to char.
operator const char*() const { return (pData) ? pData : ""; }
// Pointer to raw buffer.
const char* ToCStr() const { return (pData) ? pData : ""; }
// Returns number of bytes.
UPInt GetSize() const { return Size ; }
// Tells whether or not the string is empty.
bool IsEmpty() const { return GetSize() == 0; }
// Returns number of characters
UPInt GetLength() const;
// Returns character at the specified index
UInt32 GetCharAt(UPInt index) const;
UInt32 GetFirstCharAt(UPInt index, const char** offset) const;
UInt32 GetNextChar(const char** offset) const;
// Resize the string to the new size
void Resize(UPInt _size);
void Reserve(UPInt _size);
// Appends a character
void AppendChar(UInt32 ch);
// Append a string
void AppendString(const wchar_t* pstr, SPInt len = -1);
void AppendString(const char* putf8str, SPInt utf8StrSz = -1);
void AppendFormat(const char* format, ...);
// Assigned a string with dynamic data (copied through initializer).
//void AssignString(const InitStruct& src, UPInt size);
// Inserts substr at posAt
void Insert (const char* substr, UPInt posAt, SPInt len = -1);
// Inserts character at posAt
UPInt InsertCharAt(UInt32 c, UPInt posAt);
// Assignment
void operator = (const char* str);
void operator = (const wchar_t* str);
void operator = (const String& src);
// Addition
void operator += (const String& src) { AppendString(src.ToCStr(),src.GetSize()); }
void operator += (const char* psrc) { AppendString(psrc); }
void operator += (const wchar_t* psrc) { AppendString(psrc); }
void operator += (char ch) { AppendChar(ch); }
//String operator + (const char* str) const ;
//String operator + (const String& src) const ;
// Accesses raw bytes
char& operator [] (int index)
{
OVR_ASSERT(((UPInt)index) < GetSize());
return pData[index];
}
char& operator [] (UPInt index)
{
OVR_ASSERT(index < GetSize());
return pData[index];
}
const char& operator [] (int index) const
{
OVR_ASSERT(((UPInt)index) < GetSize());
return pData[index];
}
const char& operator [] (UPInt index) const
{
OVR_ASSERT(index < GetSize());
return pData[index];
}
};
//
// Wrapper for string data. The data must have a guaranteed
// lifespan throughout the usage of the wrapper. Not intended for
// cached usage. Not thread safe.
//
class StringDataPtr
{
public:
StringDataPtr() : pStr(NULL), Size(0) {}
StringDataPtr(const StringDataPtr& p)
: pStr(p.pStr), Size(p.Size) {}
StringDataPtr(const char* pstr, UPInt sz)
: pStr(pstr), Size(sz) {}
StringDataPtr(const char* pstr)
: pStr(pstr), Size((pstr != NULL) ? OVR_strlen(pstr) : 0) {}
explicit StringDataPtr(const String& str)
: pStr(str.ToCStr()), Size(str.GetSize()) {}
template <typename T, int N>
StringDataPtr(const T (&v)[N])
: pStr(v), Size(N) {}
public:
const char* ToCStr() const { return pStr; }
UPInt GetSize() const { return Size; }
bool IsEmpty() const { return GetSize() == 0; }
// value is a prefix of this string
// Character's values are not compared.
bool IsPrefix(const StringDataPtr& value) const
{
return ToCStr() == value.ToCStr() && GetSize() >= value.GetSize();
}
// value is a suffix of this string
// Character's values are not compared.
bool IsSuffix(const StringDataPtr& value) const
{
return ToCStr() <= value.ToCStr() && (End()) == (value.End());
}
// Find first character.
// init_ind - initial index.
SPInt FindChar(char c, UPInt init_ind = 0) const
{
for (UPInt i = init_ind; i < GetSize(); ++i)
if (pStr[i] == c)
return static_cast<SPInt>(i);
return -1;
}
// Find last character.
// init_ind - initial index.
SPInt FindLastChar(char c, UPInt init_ind = ~0) const
{
if (init_ind == (UPInt)~0 || init_ind > GetSize())
init_ind = GetSize();
else
++init_ind;
for (UPInt i = init_ind; i > 0; --i)
if (pStr[i - 1] == c)
return static_cast<SPInt>(i - 1);
return -1;
}
// Create new object and trim size bytes from the left.
StringDataPtr GetTrimLeft(UPInt size) const
{
// Limit trim size to the size of the string.
size = Alg::PMin(GetSize(), size);
return StringDataPtr(ToCStr() + size, GetSize() - size);
}
// Create new object and trim size bytes from the right.
StringDataPtr GetTrimRight(UPInt size) const
{
// Limit trim to the size of the string.
size = Alg::PMin(GetSize(), size);
return StringDataPtr(ToCStr(), GetSize() - size);
}
// Create new object, which contains next token.
// Useful for parsing.
StringDataPtr GetNextToken(char separator = ':') const
{
UPInt cur_pos = 0;
const char* cur_str = ToCStr();
for (; cur_pos < GetSize() && cur_str[cur_pos]; ++cur_pos)
{
if (cur_str[cur_pos] == separator)
{
break;
}
}
return StringDataPtr(ToCStr(), cur_pos);
}
// Trim size bytes from the left.
StringDataPtr& TrimLeft(UPInt size)
{
// Limit trim size to the size of the string.
size = Alg::PMin(GetSize(), size);
pStr += size;
Size -= size;
return *this;
}
// Trim size bytes from the right.
StringDataPtr& TrimRight(UPInt size)
{
// Limit trim to the size of the string.
size = Alg::PMin(GetSize(), size);
Size -= size;
return *this;
}
const char* Begin() const { return ToCStr(); }
const char* End() const { return ToCStr() + GetSize(); }
// Hash functor used string data pointers
struct HashFunctor
{
UPInt operator()(const StringDataPtr& data) const
{
return String::BernsteinHashFunction(data.ToCStr(), data.GetSize());
}
};
bool operator== (const StringDataPtr& data) const
{
return (OVR_strncmp(pStr, data.pStr, data.Size) == 0);
}
protected:
const char* pStr;
UPInt Size;
};
} // OVR
#endif

View file

@ -1,89 +0,0 @@
/************************************************************************************
PublicHeader: None
Filename : OVR_StringHash.h
Content : String hash table used when optional case-insensitive
lookup is required.
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_StringHash_h
#define OVR_StringHash_h
#include "OVR_String.h"
#include "OVR_Hash.h"
namespace OVR {
//-----------------------------------------------------------------------------------
// *** StringHash
// This is a custom string hash table that supports case-insensitive
// searches through special functions such as GetCaseInsensitive, etc.
// This class is used for Flash labels, exports and other case-insensitive tables.
template<class U, class Allocator = ContainerAllocator<U> >
class StringHash : public Hash<String, U, String::NoCaseHashFunctor, Allocator>
{
public:
typedef U ValueType;
typedef StringHash<U, Allocator> SelfType;
typedef Hash<String, U, String::NoCaseHashFunctor, Allocator> BaseType;
public:
void operator = (const SelfType& src) { BaseType::operator = (src); }
bool GetCaseInsensitive(const String& key, U* pvalue) const
{
String::NoCaseKey ikey(key);
return BaseType::GetAlt(ikey, pvalue);
}
// Pointer-returning get variety.
const U* GetCaseInsensitive(const String& key) const
{
String::NoCaseKey ikey(key);
return BaseType::GetAlt(ikey);
}
U* GetCaseInsensitive(const String& key)
{
String::NoCaseKey ikey(key);
return BaseType::GetAlt(ikey);
}
typedef typename BaseType::Iterator base_iterator;
base_iterator FindCaseInsensitive(const String& key)
{
String::NoCaseKey ikey(key);
return BaseType::FindAlt(ikey);
}
// Set just uses a find and assigns value if found. The key is not modified;
// this behavior is identical to Flash string variable assignment.
void SetCaseInsensitive(const String& key, const U& value)
{
base_iterator it = FindCaseInsensitive(key);
if (it != BaseType::End())
{
it->Second = value;
}
else
{
BaseType::Add(key, value);
}
}
};
} // OVR
#endif

View file

@ -1,93 +0,0 @@
/************************************************************************************
PublicHeader: Kernel
Filename : OVR_SysFile.h
Content : Header for all internal file management - functions and structures
to be inherited by OS specific subclasses.
Created : September 19, 2012
Notes :
Notes : errno may not be preserved across use of GBaseFile member functions
: Directories cannot be deleted while files opened from them are in use
(For the GetFullName function)
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_SysFile_h
#define OVR_SysFile_h
#include "OVR_File.h"
namespace OVR {
// ***** Declared classes
class SysFile;
//-----------------------------------------------------------------------------------
// *** File Statistics
// This class contents are similar to _stat, providing
// creation, modify and other information about the file.
struct FileStat
{
// No change or create time because they are not available on most systems
SInt64 ModifyTime;
SInt64 AccessTime;
SInt64 FileSize;
bool operator== (const FileStat& stat) const
{
return ( (ModifyTime == stat.ModifyTime) &&
(AccessTime == stat.AccessTime) &&
(FileSize == stat.FileSize) );
}
};
//-----------------------------------------------------------------------------------
// *** System File
// System file is created to access objects on file system directly
// This file can refer directly to path.
// System file can be open & closed several times; however, such use is not recommended
// This class is realy a wrapper around an implementation of File interface for a
// particular platform.
class SysFile : public DelegatedFile
{
protected:
SysFile(const SysFile &source) : DelegatedFile () { OVR_UNUSED(source); }
public:
// ** Constructor
SysFile();
// Opens a file
SysFile(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite);
// ** Open & management
bool Open(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite);
OVR_FORCE_INLINE bool Create(const String& path, int mode = Mode_ReadWrite)
{ return Open(path, Open_ReadWrite|Open_Create, mode); }
// Helper function: obtain file statistics information. In GFx, this is used to detect file changes.
// Return 0 if function failed, most likely because the file doesn't exist.
static bool OVR_CDECL GetFileStat(FileStat* pfileStats, const String& path);
// ** Overrides
// Overridden to provide re-open support
virtual int GetErrorCode();
virtual bool IsValid();
virtual bool Close();
};
} // Namespace OVR
#endif

View file

@ -1,67 +0,0 @@
/************************************************************************************
PublicHeader: OVR
Filename : OVR_System.h
Content : General kernel initialization/cleanup, including that
of the memory allocator.
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_System_h
#define OVR_System_h
#include "OVR_Allocator.h"
#include "OVR_Log.h"
namespace OVR {
// ***** System Core Initialization class
// System initialization must take place before any other OVR_Kernel objects are used;
// this is done my calling System::Init(). Among other things, this is necessary to
// initialize the memory allocator. Similarly, System::Destroy must be
// called before program exist for proper cleanup. Both of these tasks can be achieved by
// simply creating System object first, allowing its constructor/destructor do the work.
// TBD: Require additional System class for Oculus Rift API?
class System
{
public:
// System constructor expects allocator to be specified, if it is being substituted.
System(Log* log = Log::ConfigureDefaultLog(LogMask_Debug),
Allocator* palloc = DefaultAllocator::InitSystemSingleton())
{
Init(log, palloc);
}
~System()
{
Destroy();
}
// Returns 'true' if system was properly initialized.
static bool OVR_CDECL IsInitialized();
// Initializes System core. Users can override memory implementation by passing
// a different Allocator here.
static void OVR_CDECL Init(Log* log = Log::ConfigureDefaultLog(LogMask_Debug),
Allocator *palloc = DefaultAllocator::InitSystemSingleton());
// De-initializes System more, finalizing the threading system and destroying
// the global memory allocator.
static void OVR_CDECL Destroy();
};
} // OVR
#endif

View file

@ -1,396 +0,0 @@
/************************************************************************************
PublicHeader: None
Filename : OVR_Threads.h
Content : Contains thread-related (safe) functionality
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Threads_h
#define OVR_Threads_h
#include "OVR_Types.h"
#include "OVR_Atomic.h"
#include "OVR_RefCount.h"
#include "OVR_Array.h"
// Defines the infinite wait delay timeout
#define OVR_WAIT_INFINITE 0xFFFFFFFF
// To be defined in the project configuration options
#ifdef OVR_ENABLE_THREADS
namespace OVR {
//-----------------------------------------------------------------------------------
// ****** Declared classes
// Declared with thread support only
class Mutex;
class WaitCondition;
class Event;
// Implementation forward declarations
class MutexImpl;
class WaitConditionImpl;
//-----------------------------------------------------------------------------------
// ***** Mutex
// Mutex class represents a system Mutex synchronization object that provides access
// serialization between different threads, allowing one thread mutually exclusive access
// to a resource. Mutex is more heavy-weight then Lock, but supports WaitCondition.
class Mutex
{
friend class WaitConditionImpl;
friend class MutexImpl;
MutexImpl *pImpl;
public:
// Constructor/destructor
Mutex(bool recursive = 1);
~Mutex();
// Locking functions
void DoLock();
bool TryLock();
void Unlock();
// Returns 1 if the mutes is currently locked by another thread
// Returns 0 if the mutex is not locked by another thread, and can therefore be acquired.
bool IsLockedByAnotherThread();
// Locker class; Used for automatic locking of a mutex withing scope
class Locker
{
public:
Mutex *pMutex;
Locker(Mutex *pmutex)
{ pMutex = pmutex; pMutex->DoLock(); }
~Locker()
{ pMutex->Unlock(); }
};
};
//-----------------------------------------------------------------------------------
// ***** WaitCondition
/*
WaitCondition is a synchronization primitive that can be used to implement what is known as a monitor.
Dependent threads wait on a wait condition by calling Wait(), and get woken up by other threads that
call Notify() or NotifyAll().
The unique feature of this class is that it provides an atomic way of first releasing a Mutex, and then
starting a wait on a wait condition. If both the mutex and the wait condition are associated with the same
resource, this ensures that any condition checked for while the mutex was locked does not change before
the wait on the condition is actually initiated.
*/
class WaitCondition
{
friend class WaitConditionImpl;
// Internal implementation structure
WaitConditionImpl *pImpl;
public:
// Constructor/destructor
WaitCondition();
~WaitCondition();
// Release mutex and wait for condition. The mutex is re-aquired after the wait.
// Delay is specified in milliseconds (1/1000 of a second).
bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
// Notify a condition, releasing at one object waiting
void Notify();
// Notify a condition, releasing all objects waiting
void NotifyAll();
};
//-----------------------------------------------------------------------------------
// ***** Event
// Event is a wait-able synchronization object similar to Windows event.
// Event can be waited on until it's signaled by another thread calling
// either SetEvent or PulseEvent.
class Event
{
// Event state, its mutex and the wait condition
volatile bool State;
volatile bool Temporary;
mutable Mutex StateMutex;
WaitCondition StateWaitCondition;
void updateState(bool newState, bool newTemp, bool mustNotify);
public:
Event(bool setInitially = 0) : State(setInitially), Temporary(false) { }
~Event() { }
// Wait on an event condition until it is set
// Delay is specified in milliseconds (1/1000 of a second).
bool Wait(unsigned delay = OVR_WAIT_INFINITE);
// Set an event, releasing objects waiting on it
void SetEvent()
{ updateState(true, false, true); }
// Reset an event, un-signaling it
void ResetEvent()
{ updateState(false, false, false); }
// Set and then reset an event once a waiter is released.
// If threads are already waiting, they will be notified and released
// If threads are not waiting, the event is set until the first thread comes in
void PulseEvent()
{ updateState(true, true, true); }
};
//-----------------------------------------------------------------------------------
// ***** Thread class
// ThreadId uniquely identifies a thread; returned by GetCurrentThreadId() and
// Thread::GetThreadId.
typedef void* ThreadId;
// *** Thread flags
// Indicates that the thread is has been started, i.e. Start method has been called, and threads
// OnExit() method has not yet been called/returned.
#define OVR_THREAD_STARTED 0x01
// This flag is set once the thread has ran, and finished.
#define OVR_THREAD_FINISHED 0x02
// This flag is set temporarily if this thread was started suspended. It is used internally.
#define OVR_THREAD_START_SUSPENDED 0x08
// This flag is used to ask a thread to exit. Message driven threads will usually check this flag
// and finish once it is set.
#define OVR_THREAD_EXIT 0x10
class Thread : public RefCountBase<Thread>
{ // NOTE: Waitable must be the first base since it implements RefCountImpl.
public:
// *** Callback functions, can be used instead of overriding Run
// Run function prototypes.
// Thread function and user handle passed to it, executed by the default
// Thread::Run implementation if not null.
typedef int (*ThreadFn)(Thread *pthread, void* h);
// Thread ThreadFunction1 is executed if not 0, otherwise ThreadFunction2 is tried
ThreadFn ThreadFunction;
// User handle passes to a thread
void* UserHandle;
// Thread state to start a thread with
enum ThreadState
{
NotRunning = 0,
Running = 1,
Suspended = 2
};
// Thread priority
enum ThreadPriority
{
CriticalPriority,
HighestPriority,
AboveNormalPriority,
NormalPriority,
BelowNormalPriority,
LowestPriority,
IdlePriority,
};
// Thread constructor parameters
struct CreateParams
{
CreateParams(ThreadFn func = 0, void* hand = 0, UPInt ssize = 128 * 1024,
int proc = -1, ThreadState state = NotRunning, ThreadPriority prior = NormalPriority)
: threadFunction(func), userHandle(hand), stackSize(ssize),
processor(proc), initialState(state), priority(prior) {}
ThreadFn threadFunction; // Thread function
void* userHandle; // User handle passes to a thread
UPInt stackSize; // Thread stack size
int processor; // Thread hardware processor
ThreadState initialState; //
ThreadPriority priority; // Thread priority
};
// *** Constructors
// A default constructor always creates a thread in NotRunning state, because
// the derived class has not yet been initialized. The derived class can call Start explicitly.
// "processor" parameter specifies which hardware processor this thread will be run on.
// -1 means OS decides this. Implemented only on Win32
Thread(UPInt stackSize = 128 * 1024, int processor = -1);
// Constructors that initialize the thread with a pointer to function.
// An option to start a thread is available, but it should not be used if classes are derived from Thread.
// "processor" parameter specifies which hardware processor this thread will be run on.
// -1 means OS decides this. Implemented only on Win32
Thread(ThreadFn threadFunction, void* userHandle = 0, UPInt stackSize = 128 * 1024,
int processor = -1, ThreadState initialState = NotRunning);
// Constructors that initialize the thread with a create parameters structure.
explicit Thread(const CreateParams& params);
// Destructor.
virtual ~Thread();
// Waits for all Threads to finish; should be called only from the root
// application thread. Once this function returns, we know that all other
// thread's references to Thread object have been released.
static void OVR_CDECL FinishAllThreads();
// *** Overridable Run function for thread processing
// - returning from this method will end the execution of the thread
// - return value is usually 0 for success
virtual int Run();
// Called after return/exit function
virtual void OnExit();
// *** Thread management
// Starts the thread if its not already running
// - internally sets up the threading and calls Run()
// - initial state can either be Running or Suspended, NotRunning will just fail and do nothing
// - returns the exit code
virtual bool Start(ThreadState initialState = Running);
// Quits with an exit code
virtual void Exit(int exitCode=0);
// Suspend the thread until resumed
// Returns 1 for success, 0 for failure.
bool Suspend();
// Resumes currently suspended thread
// Returns 1 for success, 0 for failure.
bool Resume();
// Static function to return a pointer to the current thread
//static Thread* GetThread();
// *** Thread status query functions
bool GetExitFlag() const;
void SetExitFlag(bool exitFlag);
// Determines whether the thread was running and is now finished
bool IsFinished() const;
// Determines if the thread is currently suspended
bool IsSuspended() const;
// Returns current thread state
ThreadState GetThreadState() const;
// Returns the number of available CPUs on the system
static int GetCPUCount();
// Returns the thread exit code. Exit code is initialized to 0,
// 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)
void* GetOSHandle() const { return ThreadHandle; }
#else
pthread_t GetOSHandle() const { return ThreadHandle; }
#endif
#if defined(OVR_OS_WIN32)
ThreadId GetThreadId() const { return IdValue; }
#else
ThreadId GetThreadId() const { return (ThreadId)GetOSHandle(); }
#endif
static int GetOSPriority(ThreadPriority);
// *** Sleep
// Sleep secs seconds
static bool Sleep(unsigned secs);
// Sleep msecs milliseconds
static bool MSleep(unsigned msecs);
// *** Debugging functionality
#if defined(OVR_OS_WIN32)
virtual void SetThreadName( const char* name );
#else
virtual void SetThreadName( const char* name ) { OVR_UNUSED(name); }
#endif
private:
#if defined(OVR_OS_WIN32)
friend unsigned WINAPI Thread_Win32StartFn(void *pthread);
#else
friend void *Thread_PthreadStartFn(void * phandle);
static int InitAttr;
static pthread_attr_t Attr;
#endif
protected:
// Thread state flags
AtomicInt<UInt32> ThreadFlags;
AtomicInt<SInt32> SuspendCount;
UPInt StackSize;
// Hardware processor which this thread is running on.
int Processor;
ThreadPriority Priority;
#if defined(OVR_OS_WIN32)
void* ThreadHandle;
volatile ThreadId IdValue;
// System-specific cleanup function called from destructor
void CleanupSystemThread();
#else
pthread_t ThreadHandle;
#endif
// Exit code of the thread, as returned by Run.
int ExitCode;
// Internal run function.
int PRun();
// Finishes the thread and releases internal reference to it.
void FinishAndRelease();
void Init(const CreateParams& params);
// Protected copy constructor
Thread(const Thread &source) { OVR_UNUSED(source); }
};
// Returns the unique Id of a thread it is called on, intended for
// comparison purposes.
ThreadId GetCurrentThreadId();
} // OVR
#endif // OVR_ENABLE_THREADS
#endif // OVR_Threads_h

View file

@ -1,100 +0,0 @@
/************************************************************************************
PublicHeader: OVR
Filename : OVR_Timer.h
Content : Provides static functions for precise timing
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Timer_h
#define OVR_Timer_h
#include "OVR_Types.h"
namespace OVR {
//-----------------------------------------------------------------------------------
// ***** Timer
// Timer class defines a family of static functions used for application
// timing and profiling.
class Timer
{
public:
enum {
MsPerSecond = 1000, // Milliseconds in one second.
MksPerMs = 1000, // Microseconds in one millisecond.
MksPerSecond = MsPerSecond * MksPerMs
};
// ***** Timing APIs for Application
// These APIs should be used to guide animation and other program functions
// that require precision.
// Returns ticks in milliseconds, as a 32-bit number. May wrap around every
// 49.2 days. Use either time difference of two values of GetTicks to avoid
// wrap-around. GetTicksMs may perform better then GetTicks.
static UInt32 OVR_STDCALL GetTicksMs();
// GetTicks returns general-purpose high resolution application timer value,
// measured in microseconds (mks, or 1/1000000 of a second). The actual precision
// is system-specific and may be much lower, such as 1 ms.
static UInt64 OVR_STDCALL GetTicks();
// ***** Profiling APIs.
// These functions should be used for profiling, but may have system specific
// artifacts that make them less appropriate for general system use.
// On Win32, for example these rely on QueryPerformanceConter may have
// problems with thread-core switching and power modes.
// Return a hi-res timer value in mks (1/1000000 of a sec).
// Generally you want to call this at the start and end of an
// operation, and pass the difference to
// TicksToSeconds() to find out how long the operation took.
static UInt64 OVR_STDCALL GetProfileTicks();
// More convenient zero-based profile timer in seconds. First call initializes
// the "zero" value; future calls return the difference. Not thread safe for first call.
// Due to low precision of Double, may malfunction after long runtime.
static double OVR_STDCALL GetProfileSeconds();
// Get the raw cycle counter value, providing the maximum possible timer resolution.
static UInt64 OVR_STDCALL GetRawTicks();
static UInt64 OVR_STDCALL GetRawFrequency();
// ***** Tick and time unit conversion.
// Convert micro-second ticks value into seconds value.
static inline double TicksToSeconds(UInt64 ticks)
{
return static_cast<double>(ticks) * (1.0 / (double)MksPerSecond);
}
// Convert Raw or frequency-unit ticks to seconds based on specified frequency.
static inline double RawTicksToSeconds(UInt64 rawTicks, UInt64 rawFrequency)
{
return static_cast<double>(rawTicks) * rawFrequency;
}
private:
friend class System;
// System called during program startup/shutdown.
static void initializeTimerSystem();
static void shutdownTimerSystem();
};
} // Namespace OVR
#endif

View file

@ -1,456 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_Types.h
Content : Standard library defines and simple types
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Types_H
#define OVR_Types_H
//-----------------------------------------------------------------------------------
// ****** Operating System
//
// 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
#if (defined(__APPLE__) && (defined(__GNUC__) ||\
defined(__xlC__) || defined(__xlc__))) || defined(__MACOS__)
# if (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) || defined(__IPHONE_OS_VERSION_MIN_REQUIRED))
# define OVR_OS_IPHONE
# else
# define OVR_OS_DARWIN
# define OVR_OS_MAC
# endif
#elif (defined(WIN64) || defined(_WIN64) || defined(__WIN64__))
# define OVR_OS_WIN32
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
# define OVR_OS_WIN32
#elif defined(__linux__) || defined(__linux)
# define OVR_OS_LINUX
#else
# define OVR_OS_OTHER
#endif
#if defined(ANDROID)
# define OVR_OS_ANDROID
#endif
//-----------------------------------------------------------------------------------
// ***** CPU Architecture
//
// The following CPUs are defined: (OVR_CPU_x)
//
// X86 - x86 (IA-32)
// X86_64 - x86_64 (amd64)
// PPC - PowerPC
// PPC64 - PowerPC64
// MIPS - MIPS
// OTHER - CPU for which no special support is present or needed
#if defined(__x86_64__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
# define OVR_CPU_X86_64
# define OVR_64BIT_POINTERS
#elif defined(__i386__) || defined(OVR_OS_WIN32)
# define OVR_CPU_X86
#elif defined(__powerpc64__)
# define OVR_CPU_PPC64
#elif defined(__ppc__)
# define OVR_CPU_PPC
#elif defined(__mips__) || defined(__MIPSEL__)
# define OVR_CPU_MIPS
#elif defined(__arm__)
# define OVR_CPU_ARM
#else
# define OVR_CPU_OTHER
#endif
//-----------------------------------------------------------------------------------
// ***** Co-Processor Architecture
//
// The following co-processors are defined: (OVR_CPU_x)
//
// SSE - Available on all modern x86 processors.
// Altivec - Available on all modern ppc processors.
// Neon - Available on some armv7+ processors.
#if defined(__SSE__) || defined(OVR_OS_WIN32)
# define OVR_CPU_SSE
#endif // __SSE__
#if defined( __ALTIVEC__ )
# define OVR_CPU_ALTIVEC
#endif // __ALTIVEC__
#if defined(__ARM_NEON__)
# define OVR_CPU_ARM_NEON
#endif // __ARM_NEON__
//-----------------------------------------------------------------------------------
// ***** Compiler
//
// The following compilers are defined: (OVR_CC_x)
//
// MSVC - Microsoft Visual C/C++
// INTEL - Intel C++ for Linux / Windows
// GNU - GNU C++
// ARM - ARM C/C++
#if defined(__INTEL_COMPILER)
// Intel 4.0 = 400
// Intel 5.0 = 500
// Intel 6.0 = 600
// Intel 8.0 = 800
// Intel 9.0 = 900
# define OVR_CC_INTEL __INTEL_COMPILER
#elif defined(_MSC_VER)
// MSVC 5.0 = 1100
// MSVC 6.0 = 1200
// MSVC 7.0 (VC2002) = 1300
// MSVC 7.1 (VC2003) = 1310
// MSVC 8.0 (VC2005) = 1400
// MSVC 9.0 (VC2008) = 1500
// MSVC 10.0 (VC2010) = 1600
# define OVR_CC_MSVC _MSC_VER
#elif defined(__GNUC__)
# define OVR_CC_GNU
#elif defined(__CC_ARM)
# define OVR_CC_ARM
#else
# error "Oculus does not support this Compiler"
#endif
//-----------------------------------------------------------------------------------
// ***** Compiler Warnings
// Disable MSVC warnings
#if defined(OVR_CC_MSVC)
# pragma warning(disable : 4127) // Inconsistent dll linkage
# pragma warning(disable : 4530) // Exception handling
# if (OVR_CC_MSVC<1300)
# pragma warning(disable : 4514) // Unreferenced inline function has been removed
# pragma warning(disable : 4710) // Function not inlined
# pragma warning(disable : 4714) // _force_inline not inlined
# pragma warning(disable : 4786) // Debug variable name longer than 255 chars
# endif // (OVR_CC_MSVC<1300)
#endif // (OVR_CC_MSVC)
// *** Linux Unicode - must come before Standard Includes
#ifdef OVR_OS_LINUX
// Use glibc unicode functions on linux.
# ifndef _GNU_SOURCE
# define _GNU_SOURCE
# endif
#endif
//-----------------------------------------------------------------------------------
// ***** Standard Includes
//
#include <stddef.h>
#include <limits.h>
#include <float.h>
// MSVC Based Memory Leak checking - for now
#if defined(OVR_CC_MSVC) && defined(OVR_BUILD_DEBUG)
# define _CRTDBG_MAP_ALLOC
# include <stdlib.h>
# include <crtdbg.h>
// Uncomment this to help debug memory leaks under Visual Studio in OVR apps only.
// This shouldn't be defined in customer releases.
# ifndef OVR_DEFINE_NEW
# define OVR_DEFINE_NEW new(__FILE__, __LINE__)
# define new OVR_DEFINE_NEW
# endif
#endif
//-----------------------------------------------------------------------------------
// ***** Type definitions for Common Systems
namespace OVR {
typedef char Char;
// Pointer-sized integer
typedef size_t UPInt;
typedef ptrdiff_t SPInt;
#if defined(OVR_OS_WIN32)
typedef char SByte; // 8 bit Integer (Byte)
typedef unsigned char UByte;
typedef short SInt16; // 16 bit Integer (Word)
typedef unsigned short UInt16;
typedef long SInt32; // 32 bit Integer
typedef unsigned long UInt32;
typedef __int64 SInt64; // 64 bit Integer (QWord)
typedef unsigned __int64 UInt64;
#elif defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) || defined(OVR_CC_GNU)
typedef int SByte __attribute__((__mode__ (__QI__)));
typedef unsigned int UByte __attribute__((__mode__ (__QI__)));
typedef int SInt16 __attribute__((__mode__ (__HI__)));
typedef unsigned int UInt16 __attribute__((__mode__ (__HI__)));
typedef int SInt32 __attribute__((__mode__ (__SI__)));
typedef unsigned int UInt32 __attribute__((__mode__ (__SI__)));
typedef int SInt64 __attribute__((__mode__ (__DI__)));
typedef unsigned int UInt64 __attribute__((__mode__ (__DI__)));
#else
#include <sys/types.h>
typedef int8_t SByte;
typedef uint8_t UByte;
typedef int16_t SInt16;
typedef uint16_t UInt16;
typedef int32_t SInt32;
typedef uint32_t UInt32;
typedef int64_t SInt64;
typedef uint64_t UInt64;
#endif
// ***** BaseTypes Namespace
// BaseTypes namespace is explicitly declared to allow base types to be used
// by customers directly without other contents of OVR namespace.
//
// Its is expected that GFx samples will declare 'using namespace OVR::BaseTypes'
// to allow using these directly without polluting the target scope with other
// OVR declarations, such as Ptr<>, String or Mutex.
namespace BaseTypes
{
using OVR::UPInt;
using OVR::SPInt;
using OVR::UByte;
using OVR::SByte;
using OVR::UInt16;
using OVR::SInt16;
using OVR::UInt32;
using OVR::SInt32;
using OVR::UInt64;
using OVR::SInt64;
} // OVR::BaseTypes
} // OVR
//-----------------------------------------------------------------------------------
// ***** Macro Definitions
//
// We define the following:
//
// OVR_BYTE_ORDER - Defined to either OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN
// OVR_FORCE_INLINE - Forces inline expansion of function
// OVR_ASM - Assembly language prefix
// OVR_STR - Prefixes string with L"" if building unicode
//
// OVR_STDCALL - Use stdcall calling convention (Pascal arg order)
// OVR_CDECL - Use cdecl calling convention (C argument order)
// OVR_FASTCALL - Use fastcall calling convention (registers)
//
// Byte order constants, OVR_BYTE_ORDER is defined to be one of these.
#define OVR_LITTLE_ENDIAN 1
#define OVR_BIG_ENDIAN 2
// Force inline substitute - goes before function declaration
#if defined(OVR_CC_MSVC)
# define OVR_FORCE_INLINE __forceinline
#elif defined(OVR_CC_GNU)
# define OVR_FORCE_INLINE __attribute__((always_inline)) inline
#else
# define OVR_FORCE_INLINE inline
#endif // OVR_CC_MSVC
#if defined(OVR_OS_WIN32)
// ***** Win32
// Byte order
#define OVR_BYTE_ORDER OVR_LITTLE_ENDIAN
// Calling convention - goes after function return type but before function name
#ifdef __cplusplus_cli
# define OVR_FASTCALL __stdcall
#else
# define OVR_FASTCALL __fastcall
#endif
#define OVR_STDCALL __stdcall
#define OVR_CDECL __cdecl
// Assembly macros
#if defined(OVR_CC_MSVC)
# define OVR_ASM _asm
#else
# define OVR_ASM asm
#endif // (OVR_CC_MSVC)
#ifdef UNICODE
# define OVR_STR(str) L##str
#else
# define OVR_STR(str) str
#endif // UNICODE
#else
// **** Standard systems
#if (defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN))|| \
(defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN))
# define OVR_BYTE_ORDER OVR_BIG_ENDIAN
#elif (defined(__ARMEB__) || defined(OVR_CPU_PPC) || defined(OVR_CPU_PPC64))
# define OVR_BYTE_ORDER OVR_BIG_ENDIAN
#else
# define OVR_BYTE_ORDER OVR_LITTLE_ENDIAN
#endif
// Assembly macros
#define OVR_ASM __asm__
#define OVR_ASM_PROC(procname) OVR_ASM
#define OVR_ASM_END OVR_ASM
// Calling convention - goes after function return type but before function name
#define OVR_FASTCALL
#define OVR_STDCALL
#define OVR_CDECL
#endif // defined(OVR_OS_WIN32)
//-----------------------------------------------------------------------------------
// ***** OVR_DEBUG_BREAK, OVR_ASSERT
//
// If not in debug build, macros do nothing
#ifndef OVR_BUILD_DEBUG
# define OVR_DEBUG_BREAK ((void)0)
# define OVR_ASSERT(p) ((void)0)
#else
// Microsoft Win32 specific debugging support
#if defined(OVR_OS_WIN32)
# ifdef OVR_CPU_X86
# if defined(__cplusplus_cli)
# define OVR_DEBUG_BREAK do { __debugbreak(); } while(0)
# elif defined(OVR_CC_GNU)
# define OVR_DEBUG_BREAK do { OVR_ASM("int $3\n\t"); } while(0)
# else
# define OVR_DEBUG_BREAK do { OVR_ASM int 3 } while (0)
# endif
# else
# define OVR_DEBUG_BREAK do { __debugbreak(); } while(0)
# endif
// Unix specific debugging support
#elif defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)
# define OVR_DEBUG_BREAK do { OVR_ASM("int $3\n\t"); } while(0)
#else
# define OVR_DEBUG_BREAK do { *((int *) 0) = 1; } while(0)
#endif
// This will cause compiler breakpoint
#define OVR_ASSERT(p) do { if (!(p)) { OVR_DEBUG_BREAK; } } while(0)
#endif // OVR_BUILD_DEBUG
// Compile-time assert; produces compiler error if condition is false
#define OVR_COMPILER_ASSERT(x) { int zero = 0; switch(zero) {case 0: case x:;} }
//-----------------------------------------------------------------------------------
// ***** OVR_UNUSED - Unused Argument handling
// Macro to quiet compiler warnings about unused parameters/variables.
#if defined(OVR_CC_GNU)
# define OVR_UNUSED(a) do {__typeof__ (&a) __attribute__ ((unused)) __tmp = &a; } while(0)
#else
# define OVR_UNUSED(a) (a)
#endif
#define OVR_UNUSED1(a1) OVR_UNUSED(a1)
#define OVR_UNUSED2(a1,a2) OVR_UNUSED(a1); OVR_UNUSED(a2)
#define OVR_UNUSED3(a1,a2,a3) OVR_UNUSED2(a1,a2); OVR_UNUSED(a3)
#define OVR_UNUSED4(a1,a2,a3,a4) OVR_UNUSED3(a1,a2,a3); OVR_UNUSED(a4)
#define OVR_UNUSED5(a1,a2,a3,a4,a5) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED(a5)
#define OVR_UNUSED6(a1,a2,a3,a4,a5,a6) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED2(a5,a6)
#define OVR_UNUSED7(a1,a2,a3,a4,a5,a6,a7) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED3(a5,a6,a7)
#define OVR_UNUSED8(a1,a2,a3,a4,a5,a6,a7,a8) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED4(a5,a6,a7,a8)
#define OVR_UNUSED9(a1,a2,a3,a4,a5,a6,a7,a8,a9) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED5(a5,a6,a7,a8,a9)
//-----------------------------------------------------------------------------------
// ***** Configuration Macros
// SF Build type
#ifdef OVR_BUILD_DEBUG
# define OVR_BUILD_STRING "Debug"
#else
# define OVR_BUILD_STRING "Release"
#endif
//// Enables SF Debugging information
//# define OVR_BUILD_DEBUG
// OVR_DEBUG_STATEMENT injects a statement only in debug builds.
// OVR_DEBUG_SELECT injects first argument in debug builds, second argument otherwise.
#ifdef OVR_BUILD_DEBUG
#define OVR_DEBUG_STATEMENT(s) s
#define OVR_DEBUG_SELECT(d, nd) d
#else
#define OVR_DEBUG_STATEMENT(s)
#define OVR_DEBUG_SELECT(d, nd) nd
#endif
#define OVR_ENABLE_THREADS
//
// Prevents OVR from defining new within
// type macros, so developers can override
// new using the #define new new(...) trick
// - used with OVR_DEFINE_NEW macro
//# define OVR_BUILD_DEFINE_NEW
//
#endif // OVR_Types_h

View file

@ -1,88 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_UTF8Util.h
Content : UTF8 Unicode character encoding/decoding support
Created : September 19, 2012
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_UTF8Util_h
#define OVR_UTF8Util_h
#include "OVR_Types.h"
namespace OVR { namespace UTF8Util {
//-----------------------------------------------------------------------------------
// *** UTF8 string length and indexing.
// Determines the length of UTF8 string in characters.
// If source length is specified (in bytes), null 0 character is counted properly.
SPInt OVR_STDCALL GetLength(const char* putf8str, SPInt length = -1);
// Gets a decoded UTF8 character at index; you can access up to the index returned
// by GetLength. 0 will be returned for out of bounds access.
UInt32 OVR_STDCALL GetCharAt(SPInt index, const char* putf8str, SPInt length = -1);
// Converts UTF8 character index into byte offset.
// -1 is returned if index was out of bounds.
SPInt OVR_STDCALL GetByteIndex(SPInt index, const char* putf8str, SPInt length = -1);
// *** 16-bit Unicode string Encoding/Decoding routines.
// Determines the number of bytes necessary to encode a string.
// Does not count the terminating 0 (null) character.
SPInt OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, SPInt length = -1);
// Encodes a unicode (UCS-2 only) string into a buffer. The size of buffer must be at
// least GetEncodeStringSize() + 1.
void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, SPInt length = -1);
// Decode UTF8 into a wchar_t buffer. Must have GetLength()+1 characters available.
// Characters over 0xFFFF are replaced with 0xFFFD.
// Returns the length of resulting string (number of characters)
UPInt OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, SPInt bytesLen = -1);
// *** Individual character Encoding/Decoding.
// Determined the number of bytes necessary to encode a UCS character.
int OVR_STDCALL GetEncodeCharSize(UInt32 ucsCharacter);
// Encodes the given UCS character into the given UTF-8 buffer.
// Writes the data starting at buffer[offset], and
// increments offset by the number of bytes written.
// May write up to 6 bytes, so make sure there's room in the buffer
void OVR_STDCALL EncodeChar(char* pbuffer, SPInt* poffset, UInt32 ucsCharacter);
// Return the next Unicode character in the UTF-8 encoded buffer.
// Invalid UTF-8 sequences produce a U+FFFD character as output.
// Advances *utf8_buffer past the character returned. Pointer advance
// occurs even if the terminating 0 character is hit, since that allows
// strings with middle '\0' characters to be supported.
UInt32 OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer);
// Safer version of DecodeNextChar, which doesn't advance pointer if
// null character is hit.
inline UInt32 DecodeNextChar(const char** putf8Buffer)
{
UInt32 ch = DecodeNextChar_Advance0(putf8Buffer);
if (ch == 0)
(*putf8Buffer)--;
return ch;
}
}} // OVR::UTF8Util
#endif

View file

@ -1,619 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_Device.h
Content : Definition of HMD-related Device interfaces
Created : September 21, 2012
Authors : Michael Antonov
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_Device_h
#define OVR_Device_h
#include "OVR_DeviceConstants.h"
#include "OVR_DeviceHandle.h"
#include "OVR_DeviceMessages.h"
#include "OVR_HIDDeviceBase.h"
#include "Kernel/OVR_Atomic.h"
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_String.h"
namespace OVR {
// Declared externally
class Profile;
class ProfileManager; // << Should be renamed for consistency
// Forward declarations
class SensorDevice;
class DeviceCommon;
class DeviceManager;
// MessageHandler is a base class from which users derive to receive messages,
// its OnMessage handler will be called for messages once it is installed on
// a device. Same message handler can be installed on multiple devices.
class MessageHandler
{
friend class MessageHandlerImpl;
public:
MessageHandler();
virtual ~MessageHandler();
// Returns 'true' if handler is currently installed on any devices.
bool IsHandlerInstalled() const;
// Should be called from derived class destructor to avoid handler
// being called after it exits.
void RemoveHandlerFromDevices();
// Returns a pointer to the internal lock object that is locked by a
// background thread while OnMessage() is called.
// This lock guaranteed to survive until ~MessageHandler.
Lock* GetHandlerLock() const;
virtual void OnMessage(const Message&) { }
// Determines if handler supports a specific message type. Can
// be used to filter out entire message groups. The result
// returned by this function shouldn't change after handler creation.
virtual bool SupportsMessageType(MessageType) const { return true; }
private:
UPInt Internal[4];
};
//-------------------------------------------------------------------------------------
// ***** DeviceBase
// DeviceBase is the base class for all OVR Devices. It provides the following basic
// functionality:
// - Reports device type, manager, and associated parent (if any).
// - Supports installable message handlers, which are notified of device events.
// - Device objects are created through DeviceHandle::CreateDevice or more commonly
// through DeviceEnumerator<>::CreateDevice.
// - Created devices are reference counted, starting with RefCount of 1.
// - Device is resources are cleaned up when it is Released, although its handles
// may survive longer if referenced.
class DeviceBase : public NewOverrideBase
{
friend class DeviceHandle;
friend class DeviceManagerImpl;
public:
// Enumerating DeviceBase enumerates all devices.
enum { EnumDeviceType = Device_All };
virtual ~DeviceBase() { }
virtual void AddRef();
virtual void Release();
virtual DeviceBase* GetParent() const;
virtual DeviceManager* GetManager() const;
virtual void SetMessageHandler(MessageHandler* handler);
virtual MessageHandler* GetMessageHandler() const;
virtual DeviceType GetType() const;
virtual bool GetDeviceInfo(DeviceInfo* info) const;
// returns the MessageHandler's lock
Lock* GetHandlerLock() const;
protected:
// Internal
virtual DeviceCommon* getDeviceCommon() const = 0;
};
//-------------------------------------------------------------------------------------
// ***** DeviceInfo
// DeviceInfo describes a device and its capabilities, obtained by calling
// GetDeviceInfo. This base class only contains device-independent functionality;
// users will normally use a derived HMDInfo or SensorInfo classes for more
// extensive device info.
class DeviceInfo
{
public:
DeviceInfo() : InfoClassType(Device_None), Type(Device_None), Version(0)
{ ProductName[0] = Manufacturer[0] = 0; }
enum { MaxNameLength = 32 };
// Type of device for which DeviceInfo is intended.
// This will be set to Device_HMD for HMDInfo structure, note that this may be
// different form the actual device type since (Device_None) is valid.
const DeviceType InfoClassType;
// Type of device this describes. This must be the same as InfoClassType when
// InfoClassType != Device_None.
DeviceType Type;
// Name string describing the product: "Oculus Rift DK1", etc.
char ProductName[MaxNameLength];
char Manufacturer[MaxNameLength];
unsigned Version;
protected:
DeviceInfo(DeviceType type) : InfoClassType(type), Type(type), Version(0)
{ ProductName[0] = Manufacturer[0] = 0; }
void operator = (const DeviceInfo&) { OVR_ASSERT(0); } // Assignment not allowed.
};
//-------------------------------------------------------------------------------------
// DeviceEnumerationArgs provides device enumeration argumenrs for DeviceManager::EnumerateDevicesEx.
class DeviceEnumerationArgs
{
public:
DeviceEnumerationArgs(DeviceType enumType, bool availableOnly)
: EnumType(enumType), AvailableOnly(availableOnly)
{ }
// Helper; returns true if args match our enumeration criteria.
bool MatchRule(DeviceType type, bool available) const
{
return ((EnumType == type) || (EnumType == Device_All)) &&
(available || !AvailableOnly);
}
protected:
DeviceType EnumType;
bool AvailableOnly;
};
// DeviceEnumerator<> is used to enumerate and create devices of specified class,
// it is returned by calling MeviceManager::EnumerateDevices. Initially, the enumerator will
// refer to the first device of specified type. Additional devices can be accessed by
// calling Next().
template<class T = DeviceBase>
class DeviceEnumerator : public DeviceHandle
{
friend class DeviceManager;
friend class DeviceManagerImpl;
public:
DeviceEnumerator()
: DeviceHandle(), EnumArgs(Device_None, true) { }
// Next advances enumeration to the next device that first criteria.
// Returns false if no more devices exist that match enumeration criteria.
bool Next() { return enumerateNext(EnumArgs); }
// Creates an instance of the device referenced by enumerator; returns null
// if enumerator does not refer to a valid device or device is unavailable.
// If device was already created, the same object with incremented ref-count is returned.
T* CreateDevice() { return static_cast<T*>(DeviceHandle::CreateDevice()); }
protected:
DeviceEnumerator(const DeviceHandle &dev, const DeviceEnumerationArgs& args)
: DeviceHandle(dev), EnumArgs(args)
{ }
DeviceEnumerationArgs EnumArgs;
};
//-------------------------------------------------------------------------------------
// ***** DeviceManager
// DeviceManager maintains and provides access to devices supported by OVR, such as
// HMDs and sensors. A single instance of DeviceManager is normally created at
// program startup, allowing devices to be enumerated and created. DeviceManager is
// reference counted and is AddRefed by its created child devices, causing it to
// always be the last object that is released.
//
// Install MessageHandler on DeviceManager to detect when devices are inserted or removed.
//
// The following code will create the manager and its first available HMDDevice,
// and then release it when not needed:
//
// DeviceManager* manager = DeviceManager::Create();
// HMDDevice* hmd = manager->EnumerateDevices<HMDDevice>().CreateDevice();
//
// if (hmd) hmd->Release();
// if (manager) manager->Release();
class DeviceManager : public DeviceBase
{
public:
DeviceManager()
{ }
// DeviceBase implementation.
virtual DeviceType GetType() const { return Device_Manager; }
virtual DeviceManager* GetManager() const { return const_cast<DeviceManager*>(this); }
// Every DeviceManager has an associated profile manager, which us used to store
// user settings that may affect device behavior.
virtual ProfileManager* GetProfileManager() const = 0;
// EnumerateDevices enumerates all of the available devices of the specified class,
// returning an enumerator that references the first device. An empty enumerator is
// returned if no devices are available. The following APIs are exposed through
// DeviceEnumerator:
// DeviceEnumerator::GetType() - Check device type. Returns Device_None
// if no device was found/pointed to.
// DeviceEnumerator::GetDeviceInfo() - Get more information on device.
// DeviceEnumerator::CreateDevice() - Create an instance of device.
// DeviceEnumerator::Next() - Move onto next device.
template<class D>
DeviceEnumerator<D> EnumerateDevices(bool availableOnly = true)
{
// TBD: A cleaner (but less efficient) alternative is though enumeratorFromHandle.
DeviceEnumerator<> e = EnumerateDevicesEx(DeviceEnumerationArgs((DeviceType)D::EnumDeviceType, availableOnly));
return *reinterpret_cast<DeviceEnumerator<D>*>(&e);
}
// EnumerateDevicesEx provides internal implementation for device enumeration, enumerating
// devices based on dynamically specified DeviceType in DeviceEnumerationArgs.
// End users should call DeumerateDevices<>() instead.
virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args) = 0;
// Creates a new DeviceManager. Only one instance of DeviceManager should be created at a time.
static DeviceManager* Create();
// Static constant for this device type, used in template cast type checks.
enum { EnumDeviceType = Device_Manager };
// Adds a device (DeviceCreateDesc*) into Devices. Returns NULL,
// if unsuccessful or device is already in the list.
virtual Ptr<DeviceCreateDesc> AddDevice_NeedsLock(const DeviceCreateDesc& createDesc) = 0;
protected:
DeviceEnumerator<> enumeratorFromHandle(const DeviceHandle& h, const DeviceEnumerationArgs& args)
{ return DeviceEnumerator<>(h, args); }
DeviceManager* getThis() { return this; }
};
//-------------------------------------------------------------------------------------
// ***** HMDInfo
// This structure describes various aspects of the HMD allowing us to configure rendering.
//
// Currently included data:
// - Physical screen dimensions, resolution, and eye distances.
// (some of these will be configurable with a tool in the future).
// These arguments allow us to properly setup projection across HMDs.
// - DisplayDeviceName for identifying HMD screen; system-specific interpretation.
//
// TBD:
// - Power on/ off?
// - Sensor rates and capabilities
// - Distortion radius/variables
// - Screen update frequency
// - Distortion needed flag
// - Update modes:
// Set update mode: Stereo (both sides together), mono (same in both eyes),
// Alternating, Alternating scan-lines.
class HMDInfo : public DeviceInfo
{
public:
// Size of the entire screen, in pixels.
unsigned HResolution, VResolution;
// Physical dimensions of the active screen in meters. Can be used to calculate
// projection center while considering IPD.
float HScreenSize, VScreenSize;
// Physical offset from the top of the screen to the eye center, in meters.
// This will usually, but not necessarily be half of VScreenSize.
float VScreenCenter;
// Distance from the eye to screen surface, in meters.
// Useful for calculating FOV and projection.
float EyeToScreenDistance;
// Distance between physical lens centers useful for calculating distortion center.
float LensSeparationDistance;
// Configured distance between the user's eye centers, in meters. Defaults to 0.064.
float InterpupillaryDistance;
// Radial distortion correction coefficients.
// The distortion assumes that the input texture coordinates will be scaled
// by the following equation:
// uvResult = uvInput * (K0 + K1 * uvLength^2 + K2 * uvLength^4)
// Where uvInput is the UV vector from the center of distortion in direction
// of the mapped pixel, uvLength is the magnitude of that vector, and uvResult
// the corresponding location after distortion.
float DistortionK[4];
float ChromaAbCorrection[4];
// Desktop coordinate position of the screen (can be negative; may not be present on all platforms)
int DesktopX, DesktopY;
// Windows:
// "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC.
char DisplayDeviceName[32];
// MacOS:
long DisplayId;
HMDInfo()
: DeviceInfo(Device_HMD),
HResolution(0), VResolution(0), HScreenSize(0), VScreenSize(0),
VScreenCenter(0), EyeToScreenDistance(0),
LensSeparationDistance(0), InterpupillaryDistance(0),
DesktopX(0), DesktopY(0), DisplayId(0)
{
DisplayDeviceName[0] = 0;
memset(DistortionK, 0, sizeof(DistortionK));
DistortionK[0] = 1;
ChromaAbCorrection[0] = ChromaAbCorrection[2] = 1;
ChromaAbCorrection[1] = ChromaAbCorrection[3] = 0;
}
// Operator = copies local fields only (base class must be correct already)
void operator = (const HMDInfo& src)
{
HResolution = src.HResolution;
VResolution = src.VResolution;
HScreenSize = src.HScreenSize;
VScreenSize = src.VScreenSize;
VScreenCenter = src.VScreenCenter;
EyeToScreenDistance = src.EyeToScreenDistance;
LensSeparationDistance = src.LensSeparationDistance;
InterpupillaryDistance = src.InterpupillaryDistance;
DistortionK[0] = src.DistortionK[0];
DistortionK[1] = src.DistortionK[1];
DistortionK[2] = src.DistortionK[2];
DistortionK[3] = src.DistortionK[3];
ChromaAbCorrection[0] = src.ChromaAbCorrection[0];
ChromaAbCorrection[1] = src.ChromaAbCorrection[1];
ChromaAbCorrection[2] = src.ChromaAbCorrection[2];
ChromaAbCorrection[3] = src.ChromaAbCorrection[3];
DesktopX = src.DesktopX;
DesktopY = src.DesktopY;
memcpy(DisplayDeviceName, src.DisplayDeviceName, sizeof(DisplayDeviceName));
DisplayId = src.DisplayId;
}
bool IsSameDisplay(const HMDInfo& o) const
{
return DisplayId == o.DisplayId &&
String::CompareNoCase(DisplayDeviceName,
o.DisplayDeviceName) == 0;
}
};
// HMDDevice represents an Oculus HMD device unit. An instance of this class
// is typically created from the DeviceManager.
// After HMD device is created, we its sensor data can be obtained by
// first creating a Sensor object and then.
// TBD:
// - Configure Sensor
// - APIs to set On-Screen message, other states?
class HMDDevice : public DeviceBase
{
public:
HMDDevice()
{ }
// Static constant for this device type, used in template cast type checks.
enum { EnumDeviceType = Device_HMD };
virtual DeviceType GetType() const { return Device_HMD; }
// Creates a sensor associated with this HMD.
virtual SensorDevice* GetSensor() = 0;
// Requests the currently used profile. This profile affects the
// settings reported by HMDInfo.
virtual Profile* GetProfile() const = 0;
// Obtains the currently used profile name. This is initialized to the default
// profile name, if any; it can then be changed per-device by SetProfileName.
virtual const char* GetProfileName() const = 0;
// Sets the profile user name, changing the data returned by GetProfileInfo.
virtual bool SetProfileName(const char* name) = 0;
// Disconnects from real HMD device. This HMDDevice remains as 'fake' HMD.
// SensorDevice ptr is used to restore the 'fake' HMD (can be NULL).
HMDDevice* Disconnect(SensorDevice*);
// Returns 'true' if HMD device is a 'fake' HMD (was created this way or
// 'Disconnect' method was called).
bool IsDisconnected() const;
};
//-------------------------------------------------------------------------------------
// ***** SensorRange & SensorInfo
// SensorRange specifies maximum value ranges that SensorDevice hardware is configured
// to detect. Although this range doesn't affect the scale of MessageBodyFrame values,
// physical motions whose positive or negative magnitude is outside the specified range
// may get clamped or misreported. Setting lower values may result in higher precision
// tracking.
struct SensorRange
{
SensorRange(float maxAcceleration = 0.0f, float maxRotationRate = 0.0f,
float maxMagneticField = 0.0f)
: MaxAcceleration(maxAcceleration), MaxRotationRate(maxRotationRate),
MaxMagneticField(maxMagneticField)
{ }
// Maximum detected acceleration in m/s^2. Up to 8*G equivalent support guaranteed,
// where G is ~9.81 m/s^2.
// Oculus DK1 HW has thresholds near: 2, 4 (default), 8, 16 G.
float MaxAcceleration;
// Maximum detected angular velocity in rad/s. Up to 8*Pi support guaranteed.
// Oculus DK1 HW thresholds near: 1, 2, 4, 8 Pi (default).
float MaxRotationRate;
// Maximum detectable Magnetic field strength in Gauss. Up to 2.5 Gauss support guaranteed.
// Oculus DK1 HW thresholds near: 0.88, 1.3, 1.9, 2.5 gauss.
float MaxMagneticField;
};
// SensorInfo describes capabilities of the sensor device.
class SensorInfo : public DeviceInfo
{
public:
SensorInfo() : DeviceInfo(Device_Sensor), VendorId(0), ProductId(0)
{
SerialNumber[0] = 0;
}
// HID Vendor and ProductId of the device.
UInt16 VendorId;
UInt16 ProductId;
// MaxRanges report maximum sensor range values supported by HW.
SensorRange MaxRanges;
// Sensor (and display) serial number.
char SerialNumber[20];
private:
void operator = (const SensorInfo&) { OVR_ASSERT(0); } // Assignment not allowed.
};
//-------------------------------------------------------------------------------------
// ***** SensorDevice
// SensorDevice is an interface to sensor data.
// Install a MessageHandler of SensorDevice instance to receive MessageBodyFrame
// notifications.
//
// TBD: Add Polling API? More HID interfaces?
class SensorDevice : public HIDDeviceBase, public DeviceBase
{
public:
SensorDevice()
{ }
// Static constant for this device type, used in template cast type checks.
enum { EnumDeviceType = Device_Sensor };
virtual DeviceType GetType() const { return Device_Sensor; }
// CoordinateFrame defines whether messages come in the coordinate frame
// of the sensor device or HMD, which has a different internal sensor.
// Sensors obtained form the HMD will automatically use HMD coordinates.
enum CoordinateFrame
{
Coord_Sensor = 0,
Coord_HMD = 1
};
virtual void SetCoordinateFrame(CoordinateFrame coordframe) = 0;
virtual CoordinateFrame GetCoordinateFrame() const = 0;
// Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call).
// Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be
// called twice or thrice at the same 'tick'.
// If the rate is < 333 then the OnMessage / MessageBodyFrame will be called three
// times for each 'tick': the first call will contain averaged values, the second
// and third calls will provide with most recent two recorded samples.
virtual void SetReportRate(unsigned rateHz) = 0;
// Returns currently set report rate, in Hz. If 0 - error occurred.
// Note, this value may be different from the one provided for SetReportRate. The return
// value will contain the actual rate.
virtual unsigned GetReportRate() const = 0;
// Sets maximum range settings for the sensor described by SensorRange.
// The function will fail if you try to pass values outside Maximum supported
// by the HW, as described by SensorInfo.
// Pass waitFlag == true to wait for command completion. For waitFlag == true,
// returns true if the range was applied successfully (no HW error).
// For waitFlag = false, return 'true' means that command was enqueued successfully.
virtual bool SetRange(const SensorRange& range, bool waitFlag = false) = 0;
// Return the current sensor range settings for the device. These may not exactly
// match the values applied through SetRange.
virtual void GetRange(SensorRange* range) const = 0;
};
//-------------------------------------------------------------------------------------
// ***** LatencyTestConfiguration
// LatencyTestConfiguration specifies configuration information for the Oculus Latency Tester device.
struct LatencyTestConfiguration
{
LatencyTestConfiguration(const Color& threshold, bool sendSamples = false)
: Threshold(threshold), SendSamples(sendSamples)
{
}
// The color threshold for triggering a detected display change.
Color Threshold;
// Flag specifying whether we wish to receive a stream of color values from the sensor.
bool SendSamples;
};
//-------------------------------------------------------------------------------------
// ***** LatencyTestDisplay
// LatencyTestDisplay sets the mode and contents of the Latency Tester LED display.
// See the 'Latency Tester Specification' document for more details.
struct LatencyTestDisplay
{
LatencyTestDisplay(UByte mode, UInt32 value)
: Mode(mode), Value(value)
{
}
UByte Mode; // The display mode that we wish to select.
UInt32 Value; // The value to display.
};
//-------------------------------------------------------------------------------------
// ***** LatencyTestDevice
// LatencyTestDevice provides an interface to the Oculus Latency Tester which is used to test 'motion to photon' latency.
class LatencyTestDevice : public HIDDeviceBase, public DeviceBase
{
public:
LatencyTestDevice()
{ }
// Static constant for this device type, used in template cast type checks.
enum { EnumDeviceType = Device_LatencyTester };
virtual DeviceType GetType() const { return Device_LatencyTester; }
// Specifies configuration information including the threshold for triggering a detected color change,
// and a flag to enable a stream of sensor values (typically used for debugging).
virtual bool SetConfiguration(const LatencyTestConfiguration& configuration, bool waitFlag = false) = 0;
// Get configuration information from device.
virtual bool GetConfiguration(LatencyTestConfiguration* configuration) = 0;
// Used to calibrate the latency tester at the start of a test. Display the specified color on the screen
// beneath the latency tester and then call this method. Calibration information is lost
// when power is removed from the device.
virtual bool SetCalibrate(const Color& calibrationColor, bool waitFlag = false) = 0;
// Triggers the start of a measurement. This starts the millisecond timer on the device and
// causes it to respond with the 'MessageLatencyTestStarted' message.
virtual bool SetStartTest(const Color& targetColor, bool waitFlag = false) = 0;
// Used to set the value displayed on the LED display panel.
virtual bool SetDisplay(const LatencyTestDisplay& display, bool waitFlag = false) = 0;
virtual DeviceBase* GetDevice() { return this; }
};
} // namespace OVR
#endif

View file

@ -1,39 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_DeviceConstants.h
Content : Device constants
Created : February 5, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_DeviceConstants_h
#define OVR_DeviceConstants_h
namespace OVR {
//-------------------------------------------------------------------------------------
// Different device types supported by OVR; this type is reported by DeviceBase::GetType.
//
enum DeviceType
{
Device_None = 0,
Device_Manager = 1,
Device_HMD = 2,
Device_Sensor = 3,
Device_LatencyTester = 4,
Device_BootLoader = 5,
Device_All = 0xFF // Set for enumeration only, to enumerate all device types.
};
} // namespace OVR
#endif

View file

@ -1,97 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_DeviceHandle.h
Content : Handle to a device that was enumerated
Created : February 5, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_DeviceHandle_h
#define OVR_DeviceHandle_h
#include "OVR_DeviceConstants.h"
namespace OVR {
class DeviceBase;
class DeviceInfo;
// Internal
class DeviceCreateDesc;
class DeviceEnumerationArgs;
//-------------------------------------------------------------------------------------
// ***** DeviceHandle
// DeviceHandle references a specific device that was enumerated; it can be assigned
// directly from DeviceEnumerator.
//
// Devices represented by DeviceHandle are not necessarily created or available.
// A device may become unavailable if, for example, it its unplugged. If the device
// is available, it can be created by calling CreateDevice.
//
class DeviceHandle
{
friend class DeviceManager;
friend class DeviceManagerImpl;
template<class B> friend class HIDDeviceImpl;
public:
DeviceHandle() : pImpl(0) { }
DeviceHandle(const DeviceHandle& src);
~DeviceHandle();
void operator = (const DeviceHandle& src);
bool operator == (const DeviceHandle& other) const { return pImpl == other.pImpl; }
bool operator != (const DeviceHandle& other) const { return pImpl != other.pImpl; }
// operator bool() returns true if Handle/Enumerator points to a valid device.
operator bool () const { return GetType() != Device_None; }
// Returns existing device, or NULL if !IsCreated. The returned ptr is
// addref-ed.
DeviceBase* GetDevice_AddRef() const;
DeviceType GetType() const;
bool GetDeviceInfo(DeviceInfo* info) const;
bool IsAvailable() const;
bool IsCreated() const;
// Returns true, if the handle contains the same device ptr
// as specified in the parameter.
bool IsDevice(DeviceBase*) const;
// Creates a device, or returns AddRefed pointer if one is already created.
// New devices start out with RefCount of 1.
DeviceBase* CreateDevice();
// Creates a device, or returns AddRefed pointer if one is already created.
// New devices start out with RefCount of 1. DeviceT is used to cast the
// DeviceBase* to a concreete type.
template <class DeviceT>
DeviceT* CreateDeviceTyped() const
{
return static_cast<DeviceT*>(DeviceHandle(*this).CreateDevice());
}
// Resets the device handle to uninitialized state.
void Clear();
protected:
explicit DeviceHandle(DeviceCreateDesc* impl);
bool enumerateNext(const DeviceEnumerationArgs& args);
DeviceCreateDesc* pImpl;
};
} // namespace OVR
#endif

View file

@ -1,432 +0,0 @@
/************************************************************************************
Filename : OVR_DeviceImpl.h
Content : Partial back-end independent implementation of Device interfaces
Created : October 10, 2012
Authors : Michael Antonov
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_DeviceImpl_h
#define OVR_DeviceImpl_h
#include "OVR_Device.h"
#include "Kernel/OVR_Atomic.h"
#include "Kernel/OVR_Log.h"
#include "Kernel/OVR_System.h"
#include "Kernel/OVR_Threads.h"
#include "OVR_ThreadCommandQueue.h"
#include "OVR_HIDDevice.h"
namespace OVR {
class DeviceManagerImpl;
class DeviceFactory;
enum
{
Oculus_VendorId = 0x2833
};
//-------------------------------------------------------------------------------------
// Globally shared Lock implementation used for MessageHandlers.
class SharedLock
{
public:
SharedLock() : UseCount(0) {}
Lock* GetLockAddRef();
void ReleaseLock(Lock* plock);
private:
Lock* toLock() { return (Lock*)Buffer; }
// UseCount and max alignment.
volatile int UseCount;
UInt64 Buffer[(sizeof(Lock)+sizeof(UInt64)-1)/sizeof(UInt64)];
};
// Wrapper for MessageHandler that includes synchronization logic.
// References to MessageHandlers are organized in a list to allow for them to
// easily removed with MessageHandler::RemoveAllHandlers.
class MessageHandlerRef : public ListNode<MessageHandlerRef>
{
public:
MessageHandlerRef(DeviceBase* device);
~MessageHandlerRef();
void SetHandler(MessageHandler* hander);
// Not-thread-safe version
void SetHandler_NTS(MessageHandler* hander);
void Call(const Message& msg)
{
Lock::Locker lockScope(pLock);
if (pHandler)
pHandler->OnMessage(msg);
}
Lock* GetLock() const { return pLock; }
// GetHandler() is not thread safe if used out of order across threads; nothing can be done
// about that.
MessageHandler* GetHandler() const { return pHandler; }
DeviceBase* GetDevice() const { return pDevice; }
private:
Lock* pLock; // Cached global handler lock.
DeviceBase* pDevice;
MessageHandler* pHandler;
};
//-------------------------------------------------------------------------------------
// DeviceManagerLock is a synchronization lock used by DeviceManager for Devices
// and is allocated separately for potentially longer lifetime.
//
// DeviceManagerLock is used for all of the following:
// - Adding/removing devices
// - Reporting manager lifetime (pManager != 0) for DeviceHandles
// - Protecting device creation/shutdown.
class DeviceManagerLock : public RefCountBase<DeviceManagerLock>
{
public:
Lock CreateLock;
DeviceManagerImpl* pManager;
DeviceManagerLock() : pManager(0) { }
};
// DeviceCreateDesc provides all of the information needed to create any device, a derived
// instance of this class is created by DeviceFactory during enumeration.
// - DeviceCreateDesc may or may not be a part of DeviceManager::Devices list (check pNext != 0).
// - Referenced and kept alive by DeviceHandle.
class DeviceCreateDesc : public ListNode<DeviceCreateDesc>, public NewOverrideBase
{
void operator = (const DeviceCreateDesc&) { } // Assign not supported; suppress MSVC warning.
public:
DeviceCreateDesc(DeviceFactory* factory, DeviceType type)
: pFactory(factory), Type(type), pLock(0), HandleCount(0), pDevice(0), Enumerated(true)
{
pNext = pPrev = 0;
}
virtual ~DeviceCreateDesc()
{
OVR_ASSERT(!pDevice);
if (pNext)
RemoveNode();
}
DeviceManagerImpl* GetManagerImpl() const { return pLock->pManager; }
Lock* GetLock() const { return &pLock->CreateLock; }
// DeviceCreateDesc reference counting is tied to Devices list management,
// see comments for HandleCount.
void AddRef();
void Release();
// *** Device creation/matching Interface
// Cloning copies us to an allocated object when new device is enumerated.
virtual DeviceCreateDesc* Clone() const = 0;
// Creates a new device instance without Initializing it; the
// later is done my Initialize()/Shutdown() methods of the device itself.
virtual DeviceBase* NewDeviceInstance() = 0;
// Override to return device-specific info.
virtual bool GetDeviceInfo(DeviceInfo* info) const = 0;
enum MatchResult
{
Match_None,
Match_Found,
Match_Candidate
};
// Override to return Match_Found if descriptor matches our device.
// Match_Candidate can be returned, with pcandicate update, if this may be a match
// but more searching is necessary. If this is the case UpdateMatchedCandidate will be called.
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc** pcandidate) const = 0;
// Called for matched candidate after all potential matches are iterated.
// Used to update HMDevice creation arguments from Sensor.
// Optional return param 'newDeviceFlag' will be set to true if the
// 'desc' refers to a new device; false, otherwise.
// Return 'false' to create new object, 'true' if done with this argument.
virtual bool UpdateMatchedCandidate(
const DeviceCreateDesc& desc, bool* newDeviceFlag = NULL)
{ OVR_UNUSED2(desc, newDeviceFlag); return false; }
// Matches HID device to the descriptor.
virtual bool MatchHIDDevice(const HIDDeviceDesc&) const { return false; }
// Matches device by path.
virtual bool MatchDevice(const String& /*path*/) { return false; }
//protected:
DeviceFactory* const pFactory;
const DeviceType Type;
// List in which this descriptor lives. pList->CreateLock required if added/removed.
Ptr<DeviceManagerLock> pLock;
// Strong references to us: Incremented by Device, DeviceHandles & Enumerators.
// May be 0 if device not created and there are no handles.
// Following transitions require pList->CreateLock:
// {1 -> 0}: May delete & remove handle if no longer available.
// {0 -> 1}: Device creation is only possible if manager is still alive.
AtomicInt<UInt32> HandleCount;
// If not null, points to our created device instance. Modified during lock only.
DeviceBase* pDevice;
// True if device is marked as available during enumeration.
bool Enumerated;
};
// Common data present in the implementation of every DeviceBase.
// Injected by DeviceImpl.
class DeviceCommon
{
public:
AtomicInt<UInt32> RefCount;
Ptr<DeviceCreateDesc> pCreateDesc;
Ptr<DeviceBase> pParent;
MessageHandlerRef HandlerRef;
DeviceCommon(DeviceCreateDesc* createDesc, DeviceBase* device, DeviceBase* parent)
: RefCount(1), pCreateDesc(createDesc), pParent(parent), HandlerRef(device)
{
}
// Device reference counting delegates to Manager thread to actually kill devices.
void DeviceAddRef();
void DeviceRelease();
Lock* GetLock() const { return pCreateDesc->GetLock(); }
virtual bool Initialize(DeviceBase* parent) = 0;
virtual void Shutdown() = 0;
};
//-------------------------------------------------------------------------------------
// DeviceImpl address DeviceRecord implementation to a device base class B.
// B must be derived form DeviceBase.
template<class B>
class DeviceImpl : public B, public DeviceCommon
{
public:
DeviceImpl(DeviceCreateDesc* createDesc, DeviceBase* parent)
: DeviceCommon(createDesc, getThis(), parent)
{
}
// Convenience method to avoid manager access typecasts.
DeviceManagerImpl* GetManagerImpl() const { return pCreateDesc->pLock->pManager; }
// Inline to avoid warnings.
DeviceImpl* getThis() { return this; }
// Common implementation delegate to avoid virtual inheritance and dynamic casts.
virtual DeviceCommon* getDeviceCommon() const { return (DeviceCommon*)this; }
/*
virtual void AddRef() { pCreateDesc->DeviceAddRef(); }
virtual void Release() { pCreateDesc->DeviceRelease(); }
virtual DeviceBase* GetParent() const { return pParent.GetPtr(); }
virtual DeviceManager* GetManager() const { return pCreateDesc->pLock->pManager;}
virtual void SetMessageHandler(MessageHandler* handler) { HanderRef.SetHandler(handler); }
virtual MessageHandler* GetMessageHandler() const { return HanderRef.GetHandler(); }
virtual DeviceType GetType() const { return pCreateDesc->Type; }
virtual DeviceType GetType() const { return pCreateDesc->Type; }
*/
};
//-------------------------------------------------------------------------------------
// ***** DeviceFactory
// DeviceFactory is maintained in DeviceManager for each separately-enumerable
// device type; factories allow separation of unrelated enumeration code.
class DeviceFactory : public ListNode<DeviceFactory>, public NewOverrideBase
{
public:
DeviceFactory() : pManager(0)
{
pNext = pPrev = 0;
}
virtual ~DeviceFactory() { }
DeviceManagerImpl* GetManagerImpl() { return pManager; }
// Notifiers called when we are added to/removed from a device.
virtual bool AddedToManager(DeviceManagerImpl* manager)
{
OVR_ASSERT(pManager == 0);
pManager = manager;
return true;
}
virtual void RemovedFromManager()
{
pManager = 0;
}
// *** Device Enumeration/Creation Support
// Passed to EnumerateDevices to be informed of every device detected.
class EnumerateVisitor
{
public:
virtual void Visit(const DeviceCreateDesc& createDesc) = 0;
};
// Enumerates factory devices by notifying EnumerateVisitor about every
// device that is present.
virtual void EnumerateDevices(EnumerateVisitor& visitor) = 0;
// Matches vendorId/productId pair with the factory; returns 'true'
// if the factory can handle the device.
virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
{
OVR_UNUSED2(vendorId, productId);
return false;
}
// Detects the HID device and adds the DeviceCreateDesc into Devices list, if
// the device belongs to this factory. Returns 'false', if not.
virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc)
{
OVR_UNUSED2(pdevMgr, desc);
return false;
}
protected:
DeviceManagerImpl* pManager;
};
//-------------------------------------------------------------------------------------
// ***** DeviceManagerImpl
// DeviceManagerImpl is a partial default DeviceManager implementation that
// maintains a list of devices and supports their enumeration.
class DeviceManagerImpl : public DeviceImpl<OVR::DeviceManager>, public ThreadCommandQueue
{
public:
DeviceManagerImpl();
~DeviceManagerImpl();
// Constructor helper function to create Descriptor and manager lock during initialization.
static DeviceCreateDesc* CreateManagerDesc();
// DeviceManagerImpl provides partial implementation of Initialize/Shutdown that must
// be called by the platform-specific derived class.
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
// Every DeviceManager has an associated profile manager, which is used to store
// user settings that may affect device behavior.
virtual ProfileManager* GetProfileManager() const { return pProfileManager.GetPtr(); }
// Override to return ThreadCommandQueue implementation used to post commands
// to the background device manager thread (that must be created by Initialize).
virtual ThreadCommandQueue* GetThreadQueue() = 0;
// Returns the thread id of the DeviceManager.
virtual ThreadId GetThreadId() const = 0;
virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
//
void AddFactory(DeviceFactory* factory)
{
// This lock is only needed if we call AddFactory after manager thread creation.
Lock::Locker scopeLock(GetLock());
Factories.PushBack(factory);
factory->AddedToManager(this);
}
void CallOnDeviceAdded(DeviceCreateDesc* desc)
{
HandlerRef.Call(MessageDeviceStatus(Message_DeviceAdded, this, DeviceHandle(desc)));
}
void CallOnDeviceRemoved(DeviceCreateDesc* desc)
{
HandlerRef.Call(MessageDeviceStatus(Message_DeviceRemoved, this, DeviceHandle(desc)));
}
// Helper to access Common data for a device.
static DeviceCommon* GetDeviceCommon(DeviceBase* device)
{
return device->getDeviceCommon();
}
// Background-thread callbacks for DeviceCreation/Release. These
DeviceBase* CreateDevice_MgrThread(DeviceCreateDesc* createDesc, DeviceBase* parent = 0);
Void ReleaseDevice_MgrThread(DeviceBase* device);
// Calls EnumerateDevices() on all factories
virtual Void EnumerateAllFactoryDevices();
// Enumerates devices for a particular factory.
virtual Void EnumerateFactoryDevices(DeviceFactory* factory);
virtual HIDDeviceManager* GetHIDDeviceManager() const
{
return HidDeviceManager;
}
// Adds device (DeviceCreateDesc*) into Devices. Returns NULL,
// if unsuccessful or device is already in the list.
virtual Ptr<DeviceCreateDesc> AddDevice_NeedsLock(const DeviceCreateDesc& createDesc);
// Finds a device descriptor by path and optional type.
Ptr<DeviceCreateDesc> FindDevice(const String& path, DeviceType = Device_None);
// Finds HID device by HIDDeviceDesc.
Ptr<DeviceCreateDesc> FindHIDDevice(const HIDDeviceDesc&);
void DetectHIDDevice(const HIDDeviceDesc&);
// Manager Lock-protected list of devices.
List<DeviceCreateDesc> Devices;
// Factories used to detect and manage devices.
List<DeviceFactory> Factories;
protected:
Ptr<HIDDeviceManager> HidDeviceManager;
Ptr<ProfileManager> pProfileManager;
};
} // namespace OVR
#endif

View file

@ -1,162 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_DeviceMessages.h
Content : Definition of messages generated by devices
Created : February 5, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_DeviceMessages_h
#define OVR_DeviceMessages_h
#include "OVR_DeviceConstants.h"
#include "OVR_DeviceHandle.h"
#include "Kernel/OVR_Math.h"
#include "Kernel/OVR_Array.h"
#include "Kernel/OVR_Color.h"
namespace OVR {
class DeviceBase;
class DeviceHandle;
#define OVR_MESSAGETYPE(devName, msgIndex) ((Device_##devName << 8) | msgIndex)
// MessageType identifies the structure of the Message class; based on the message,
// casting can be used to obtain the exact value.
enum MessageType
{
// Used for unassigned message types.
Message_None = 0,
// Device Manager Messages
Message_DeviceAdded = OVR_MESSAGETYPE(Manager, 0), // A new device is detected by manager.
Message_DeviceRemoved = OVR_MESSAGETYPE(Manager, 1), // Existing device has been plugged/unplugged.
// Sensor Messages
Message_BodyFrame = OVR_MESSAGETYPE(Sensor, 0), // Emitted by sensor at regular intervals.
// Latency Tester Messages
Message_LatencyTestSamples = OVR_MESSAGETYPE(LatencyTester, 0),
Message_LatencyTestColorDetected = OVR_MESSAGETYPE(LatencyTester, 1),
Message_LatencyTestStarted = OVR_MESSAGETYPE(LatencyTester, 2),
Message_LatencyTestButton = OVR_MESSAGETYPE(LatencyTester, 3),
};
//-------------------------------------------------------------------------------------
// Base class for all messages.
class Message
{
public:
Message(MessageType type = Message_None,
DeviceBase* pdev = 0) : Type(type), pDevice(pdev)
{ }
MessageType Type; // What kind of message this is.
DeviceBase* pDevice; // Device that emitted the message.
};
// Sensor BodyFrame notification.
// Sensor uses Right-Handed coordinate system to return results, with the following
// axis definitions:
// - Y Up positive
// - X Right Positive
// - Z Back Positive
// Rotations a counter-clockwise (CCW) while looking in the negative direction
// of the axis. This means they are interpreted as follows:
// - Roll is rotation around Z, counter-clockwise (tilting left) in XY plane.
// - Yaw is rotation around Y, positive for turning left.
// - Pitch is rotation around X, positive for pitching up.
class MessageBodyFrame : public Message
{
public:
MessageBodyFrame(DeviceBase* dev)
: Message(Message_BodyFrame, dev), Temperature(0.0f), TimeDelta(0.0f)
{
}
Vector3f Acceleration; // Acceleration in m/s^2.
Vector3f RotationRate; // Angular velocity in rad/s^2.
Vector3f MagneticField; // Magnetic field strength in Gauss.
float Temperature; // Temperature reading on sensor surface, in degrees Celsius.
float TimeDelta; // Time passed since last Body Frame, in seconds.
};
// Sent when we receive a device status changes (e.g.:
// Message_DeviceAdded, Message_DeviceRemoved).
class MessageDeviceStatus : public Message
{
public:
MessageDeviceStatus(MessageType type, DeviceBase* dev, const DeviceHandle &hdev)
: Message(type, dev), Handle(hdev) { }
DeviceHandle Handle;
};
//-------------------------------------------------------------------------------------
// ***** Latency Tester
// Sent when we receive Latency Tester samples.
class MessageLatencyTestSamples : public Message
{
public:
MessageLatencyTestSamples(DeviceBase* dev)
: Message(Message_LatencyTestSamples, dev)
{
}
Array<Color> Samples;
};
// Sent when a Latency Tester 'color detected' event occurs.
class MessageLatencyTestColorDetected : public Message
{
public:
MessageLatencyTestColorDetected(DeviceBase* dev)
: Message(Message_LatencyTestColorDetected, dev)
{
}
UInt16 Elapsed;
Color DetectedValue;
Color TargetValue;
};
// Sent when a Latency Tester 'change color' event occurs.
class MessageLatencyTestStarted : public Message
{
public:
MessageLatencyTestStarted(DeviceBase* dev)
: Message(Message_LatencyTestStarted, dev)
{
}
Color TargetValue;
};
// Sent when a Latency Tester 'button' event occurs.
class MessageLatencyTestButton : public Message
{
public:
MessageLatencyTestButton(DeviceBase* dev)
: Message(Message_LatencyTestButton, dev)
{
}
};
} // namespace OVR
#endif

View file

@ -1,143 +0,0 @@
/************************************************************************************
Filename : OVR_HIDDevice.h
Content : Cross platform HID device interface.
Created : February 22, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_HIDDevice_h
#define OVR_HIDDevice_h
#include "OVR_HIDDeviceBase.h"
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_String.h"
#include "Kernel/OVR_Timer.h"
namespace OVR {
class HIDDevice;
class DeviceManager;
// HIDDeviceDesc contains interesting attributes of a HID device, including a Path
// that can be used to create it.
struct HIDDeviceDesc
{
UInt16 VendorId;
UInt16 ProductId;
UInt16 VersionNumber;
UInt16 Usage;
UInt16 UsagePage;
String Path; // Platform specific.
String Manufacturer;
String Product;
String SerialNumber;
};
// HIDEnumerateVisitor exposes a Visit interface called for every detected device
// by HIDDeviceManager::Enumerate.
class HIDEnumerateVisitor
{
public:
// Should return true if we are interested in supporting
// this HID VendorId and ProductId pair.
virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId)
{ OVR_UNUSED2(vendorId, productId); return true; }
// Override to get notified about available device. Will only be called for
// devices that matched MatchVendorProduct.
virtual void Visit(HIDDevice&, const HIDDeviceDesc&) { }
};
//-------------------------------------------------------------------------------------
// ***** HIDDeviceManager
// Internal manager for enumerating and opening HID devices.
// If an OVR::DeviceManager is created then an OVR::HIDDeviceManager will automatically be created and can be accessed from the
// DeviceManager by calling 'GetHIDDeviceManager()'. When using HIDDeviceManager in standalone mode, the client must call
// 'Create' below.
class HIDDeviceManager : public RefCountBase<HIDDeviceManager>
{
public:
// Creates a new HIDDeviceManager. Only one instance of HIDDeviceManager should be created at a time.
static HIDDeviceManager* Create();
// Enumerate HID devices using a HIDEnumerateVisitor derived visitor class.
virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor) = 0;
// Open a HID device with the specified path.
virtual HIDDevice* Open(const String& path) = 0;
protected:
HIDDeviceManager()
{ }
};
//-------------------------------------------------------------------------------------
// ***** HIDDevice
// HID device object. This is designed to be operated in synchronous
// and asynchronous modes. With no handler set, input messages will be
// stored and can be retrieved by calling 'Read' or 'ReadBlocking'.
class HIDDevice : public RefCountBase<HIDDevice>, public HIDDeviceBase
{
public:
HIDDevice()
: Handler(NULL)
{
}
virtual ~HIDDevice() {}
virtual bool SetFeatureReport(UByte* data, UInt32 length) = 0;
virtual bool GetFeatureReport(UByte* data, UInt32 length) = 0;
// Not yet implemented.
/*
virtual bool Write(UByte* data, UInt32 length) = 0;
virtual bool Read(UByte* pData, UInt32 length, UInt32 timeoutMilliS) = 0;
virtual bool ReadBlocking(UByte* pData, UInt32 length) = 0;
*/
class HIDHandler
{
public:
virtual void OnInputReport(UByte* pData, UInt32 length)
{ OVR_UNUSED2(pData, length); }
virtual UInt64 OnTicks(UInt64 ticksMks)
{ OVR_UNUSED1(ticksMks); return Timer::MksPerSecond * 1000; ; }
enum HIDDeviceMessageType
{
HIDDeviceMessage_DeviceAdded = 0,
HIDDeviceMessage_DeviceRemoved = 1
};
virtual void OnDeviceMessage(HIDDeviceMessageType messageType)
{ OVR_UNUSED1(messageType); }
};
void SetHandler(HIDHandler* handler)
{ Handler = handler; }
protected:
HIDHandler* Handler;
};
} // namespace OVR
#endif

View file

@ -1,40 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_HIDDeviceBase.h
Content : Definition of HID device interface.
Created : March 11, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_HIDDeviceBase_h
#define OVR_HIDDeviceBase_h
#include "Kernel/OVR_Types.h"
namespace OVR {
//-------------------------------------------------------------------------------------
// ***** HIDDeviceBase
// Base interface for HID devices.
class HIDDeviceBase
{
public:
virtual ~HIDDeviceBase() { }
virtual bool SetFeatureReport(UByte* data, UInt32 length) = 0;
virtual bool GetFeatureReport(UByte* data, UInt32 length) = 0;
};
} // namespace OVR
#endif

View file

@ -1,203 +0,0 @@
/************************************************************************************
Filename : OVR_HIDDeviceImpl.h
Content : Implementation of HIDDevice.
Created : March 7, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_HIDDeviceImpl_h
#define OVR_HIDDeviceImpl_h
//#include "OVR_Device.h"
#include "OVR_DeviceImpl.h"
namespace OVR {
//-------------------------------------------------------------------------------------
class HIDDeviceCreateDesc : public DeviceCreateDesc
{
public:
HIDDeviceCreateDesc(DeviceFactory* factory, DeviceType type, const HIDDeviceDesc& hidDesc)
: DeviceCreateDesc(factory, type), HIDDesc(hidDesc) { }
HIDDeviceCreateDesc(const HIDDeviceCreateDesc& other)
: DeviceCreateDesc(other.pFactory, other.Type), HIDDesc(other.HIDDesc) { }
virtual bool MatchDevice(const String& path)
{
// should it be case insensitive?
return HIDDesc.Path.CompareNoCase(path) == 0;
}
HIDDeviceDesc HIDDesc;
};
//-------------------------------------------------------------------------------------
template<class B>
class HIDDeviceImpl : public DeviceImpl<B>, public HIDDevice::HIDHandler
{
public:
HIDDeviceImpl(HIDDeviceCreateDesc* createDesc, DeviceBase* parent)
: DeviceImpl<B>(createDesc, parent)
{
}
// HIDDevice::Handler interface.
virtual void OnDeviceMessage(HIDDeviceMessageType messageType)
{
MessageType handlerMessageType;
switch (messageType) {
case HIDDeviceMessage_DeviceAdded:
handlerMessageType = Message_DeviceAdded;
break;
case HIDDeviceMessage_DeviceRemoved:
handlerMessageType = Message_DeviceRemoved;
break;
default: OVR_ASSERT(0); return;
}
// Do device notification.
{
Lock::Locker scopeLock(this->HandlerRef.GetLock());
if (this->HandlerRef.GetHandler())
{
MessageDeviceStatus status(handlerMessageType, this, OVR::DeviceHandle(this->pCreateDesc));
this->HandlerRef.GetHandler()->OnMessage(status);
}
}
// Do device manager notification.
DeviceManagerImpl* manager = this->GetManagerImpl();
switch (handlerMessageType) {
case Message_DeviceAdded:
manager->CallOnDeviceAdded(this->pCreateDesc);
break;
case Message_DeviceRemoved:
manager->CallOnDeviceRemoved(this->pCreateDesc);
break;
default:;
}
}
virtual bool Initialize(DeviceBase* parent)
{
// Open HID device.
HIDDeviceDesc& hidDesc = *getHIDDesc();
HIDDeviceManager* pManager = GetHIDDeviceManager();
HIDDevice* device = pManager->Open(hidDesc.Path);
if (!device)
{
return false;
}
InternalDevice = *device;
InternalDevice->SetHandler(this);
// AddRef() to parent, forcing chain to stay alive.
DeviceImpl<B>::pParent = parent;
return true;
}
virtual void Shutdown()
{
InternalDevice->SetHandler(NULL);
// Remove the handler, if any.
this->HandlerRef.SetHandler(0);
DeviceImpl<B>::pParent.Clear();
}
DeviceManager* GetDeviceManager()
{
return DeviceImpl<B>::pCreateDesc->GetManagerImpl();
}
HIDDeviceManager* GetHIDDeviceManager()
{
return DeviceImpl<B>::pCreateDesc->GetManagerImpl()->GetHIDDeviceManager();
}
struct WriteData
{
enum { BufferSize = 64 };
UByte Buffer[64];
UPInt Size;
WriteData(UByte* data, UPInt size) : Size(size)
{
OVR_ASSERT(size <= BufferSize);
memcpy(Buffer, data, size);
}
};
bool SetFeatureReport(UByte* data, UInt32 length)
{
WriteData writeData(data, length);
// Push call with wait.
bool result = false;
ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue();
if (!pQueue->PushCallAndWaitResult(this, &HIDDeviceImpl::setFeatureReport, &result, writeData))
return false;
return result;
}
bool setFeatureReport(const WriteData& data)
{
return InternalDevice->SetFeatureReport((UByte*) data.Buffer, (UInt32) data.Size);
}
bool GetFeatureReport(UByte* data, UInt32 length)
{
bool result = false;
ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue();
if (!pQueue->PushCallAndWaitResult(this, &HIDDeviceImpl::getFeatureReport, &result, data, length))
return false;
return result;
}
bool getFeatureReport(UByte* data, UInt32 length)
{
return InternalDevice->GetFeatureReport(data, length);
}
protected:
HIDDevice* GetInternalDevice() const
{
return InternalDevice;
}
HIDDeviceDesc* getHIDDesc() const
{ return &getCreateDesc()->HIDDesc; }
HIDDeviceCreateDesc* getCreateDesc() const
{ return (HIDDeviceCreateDesc*) &(*DeviceImpl<B>::pCreateDesc); }
private:
Ptr<HIDDevice> InternalDevice;
};
} // namespace OVR
#endif

View file

@ -1,143 +0,0 @@
/************************************************************************************
PublicHeader: None
Filename : OVR_JSON.h
Content : JSON format reader and writer
Created : April 9, 2013
Author : Brant Lewis
Notes :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_JSON_H
#define OVR_JSON_H
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_String.h"
#include "Kernel/OVR_List.h"
namespace OVR {
// JSONItemType describes the type of JSON item, specifying the type of
// data that can be obtained from it.
enum JSONItemType
{
JSON_None = 0,
JSON_Null = 1,
JSON_Bool = 2,
JSON_Number = 3,
JSON_String = 4,
JSON_Array = 5,
JSON_Object = 6
};
//-----------------------------------------------------------------------------
// ***** JSON
// JSON object represents a JSON node that can be either a root of the JSON tree
// or a child item. Every node has a type that describes what is is.
// New JSON trees are typically loaded JSON::Load or created with JSON::Parse.
class JSON : public RefCountBase<JSON>, public ListNode<JSON>
{
protected:
List<JSON> Children;
public:
JSONItemType Type; // Type of this JSON node.
String Name; // Name part of the {Name, Value} pair in a parent object.
String Value;
double dValue;
public:
~JSON();
// *** Creation of NEW JSON objects
static JSON* CreateObject() { return new JSON(JSON_Object);}
static JSON* CreateNull() { return new JSON(JSON_Null); }
static JSON* CreateArray() { return new JSON(JSON_Array); }
static JSON* CreateBool(bool b) { return createHelper(JSON_Bool, b ? 1.0 : 0.0); }
static JSON* CreateNumber(double num) { return createHelper(JSON_Number, num); }
static JSON* CreateString(const char *s) { return createHelper(JSON_String, 0.0, s); }
// Creates a new JSON object from parsing string.
// Returns null pointer and fills in *perror in case of parse error.
static JSON* Parse(const char* buff, const char** perror = 0);
// Loads and parses a JSON object from a file.
// Returns 0 and assigns perror with error message on fail.
static JSON* Load(const char* path, const char** perror = 0);
// Saves a JSON object to a file.
bool Save(const char* path);
// *** Object Member Access
// These provide access to child items of the list.
bool HasItems() const { return Children.IsEmpty(); }
// Returns first/last child item, or null if child list is empty
JSON* GetFirstItem() { return (!Children.IsEmpty()) ? Children.GetFirst() : 0; }
JSON* GetLastItem() { return (!Children.IsEmpty()) ? Children.GetLast() : 0; }
// Counts the number of items in the object; these methods are inefficient.
unsigned GetItemCount() const;
JSON* GetItemByIndex(unsigned i);
JSON* GetItemByName(const char* name);
// Returns next item in a list of children; 0 if no more items exist.
JSON* GetNextItem(JSON* item) { return Children.IsNull(item->pNext) ? 0 : item->pNext; }
JSON* GetPrevItem(JSON* item) { return Children.IsNull(item->pPrev) ? 0 : item->pPrev; }
// Child item access functions
void AddItem(const char *string, JSON* item);
void AddNullItem(const char* name) { AddItem(name, CreateNull()); }
void AddBoolItem(const char* name, bool b) { AddItem(name, CreateBool(b)); }
void AddNumberItem(const char* name, double n) { AddItem(name, CreateNumber(n)); }
void AddStringItem(const char* name, const char* s) { AddItem(name, CreateString(s)); }
// void ReplaceItem(unsigned index, JSON* new_item);
// void DeleteItem(unsigned index);
// *** Array Element Access
// Add new elements to the end of array.
void AddArrayElement(JSON *item);
void AddArrayNumber(double n) { AddArrayElement(CreateNumber(n)); }
void AddArrayString(const char* s) { AddArrayElement(CreateString(s)); }
// Accessed array elements; currently inefficient.
int GetArraySize();
double GetArrayNumber(int index);
const char* GetArrayString(int index);
protected:
JSON(JSONItemType itemType = JSON_Object);
static JSON* createHelper(JSONItemType itemType, double dval, const char* strVal = 0);
// JSON Parsing helper functions.
const char* parseValue(const char *buff, const char** perror);
const char* parseNumber(const char *num);
const char* parseArray(const char* value, const char** perror);
const char* parseObject(const char* value, const char** perror);
const char* parseString(const char* str, const char** perror);
char* PrintValue(int depth, bool fmt);
char* PrintObject(int depth, bool fmt);
char* PrintArray(int depth, bool fmt);
};
}
#endif

View file

@ -1,133 +0,0 @@
/************************************************************************************
Filename : OVR_LatencyTestImpl.h
Content : Latency Tester specific implementation.
Created : March 7, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_LatencyTestImpl_h
#define OVR_LatencyTestImpl_h
#include "OVR_HIDDeviceImpl.h"
namespace OVR {
struct LatencyTestSamplesMessage;
struct LatencyTestButtonMessage;
struct LatencyTestStartedMessage;
struct LatencyTestColorDetectedMessage;
//-------------------------------------------------------------------------------------
// LatencyTestDeviceFactory enumerates Oculus Latency Tester devices.
class LatencyTestDeviceFactory : public DeviceFactory
{
public:
static LatencyTestDeviceFactory Instance;
// Enumerates devices, creating and destroying relevant objects in manager.
virtual void EnumerateDevices(EnumerateVisitor& visitor);
virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const;
virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc);
protected:
DeviceManager* getManager() const { return (DeviceManager*) pManager; }
};
// Describes a single a Oculus Latency Tester device and supports creating its instance.
class LatencyTestDeviceCreateDesc : public HIDDeviceCreateDesc
{
public:
LatencyTestDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc)
: HIDDeviceCreateDesc(factory, Device_LatencyTester, hidDesc) { }
virtual DeviceCreateDesc* Clone() const
{
return new LatencyTestDeviceCreateDesc(*this);
}
virtual DeviceBase* NewDeviceInstance();
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc**) const
{
if ((other.Type == Device_LatencyTester) && (pFactory == other.pFactory))
{
const LatencyTestDeviceCreateDesc& s2 = (const LatencyTestDeviceCreateDesc&) other;
if (MatchHIDDevice(s2.HIDDesc))
return Match_Found;
}
return Match_None;
}
virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const
{
// should paths comparison be case insensitive?
return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) &&
(HIDDesc.SerialNumber == hidDesc.SerialNumber));
}
virtual bool GetDeviceInfo(DeviceInfo* info) const;
};
//-------------------------------------------------------------------------------------
// ***** OVR::LatencyTestDeviceImpl
// Oculus Latency Tester interface.
class LatencyTestDeviceImpl : public HIDDeviceImpl<OVR::LatencyTestDevice>
{
public:
LatencyTestDeviceImpl(LatencyTestDeviceCreateDesc* createDesc);
~LatencyTestDeviceImpl();
// DeviceCommon interface.
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
// DeviceManagerThread::Notifier interface.
virtual void OnInputReport(UByte* pData, UInt32 length);
// LatencyTesterDevice interface
virtual bool SetConfiguration(const OVR::LatencyTestConfiguration& configuration, bool waitFlag = false);
virtual bool GetConfiguration(OVR::LatencyTestConfiguration* configuration);
virtual bool SetCalibrate(const Color& calibrationColor, bool waitFlag = false);
virtual bool SetStartTest(const Color& targetColor, bool waitFlag = false);
virtual bool SetDisplay(const LatencyTestDisplay& display, bool waitFlag = false);
protected:
bool openDevice(const char** errorFormatString);
void closeDevice();
void closeDeviceOnIOError();
bool initializeRead();
bool processReadResult();
bool setConfiguration(const OVR::LatencyTestConfiguration& configuration);
bool getConfiguration(OVR::LatencyTestConfiguration* configuration);
bool setCalibrate(const Color& calibrationColor);
bool setStartTest(const Color& targetColor);
bool setDisplay(const OVR::LatencyTestDisplay& display);
// Called for decoded messages
void onLatencyTestSamplesMessage(LatencyTestSamplesMessage* message);
void onLatencyTestButtonMessage(LatencyTestButtonMessage* message);
void onLatencyTestStartedMessage(LatencyTestStartedMessage* message);
void onLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage* message);
};
} // namespace OVR
#endif // OVR_LatencyTestImpl_h

View file

@ -1,111 +0,0 @@
/************************************************************************************
Filename : OVR_Linux_DeviceManager.h
Content : Linux-specific DeviceManager header.
Created :
Authors :
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_Linux_DeviceManager_h
#define OVR_Linux_DeviceManager_h
#include "OVR_DeviceImpl.h"
#include <unistd.h>
#include <sys/poll.h>
namespace OVR { namespace Linux {
class DeviceManagerThread;
//-------------------------------------------------------------------------------------
// ***** Linux DeviceManager
class DeviceManager : public DeviceManagerImpl
{
public:
DeviceManager();
~DeviceManager();
// Initialize/Shutdowncreate and shutdown manger thread.
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
virtual ThreadCommandQueue* GetThreadQueue();
virtual ThreadId GetThreadId() const;
virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
Ptr<DeviceManagerThread> pThread;
};
//-------------------------------------------------------------------------------------
// ***** Device Manager Background Thread
class DeviceManagerThread : public Thread, public ThreadCommandQueue
{
friend class DeviceManager;
enum { ThreadStackSize = 64 * 1024 };
public:
DeviceManagerThread();
~DeviceManagerThread();
virtual int Run();
// ThreadCommandQueue notifications for CommandEvent handling.
virtual void OnPushNonEmpty_Locked() { write(CommandFd[1], this, 1); }
virtual void OnPopEmpty_Locked() { }
class Notifier
{
public:
// Called when I/O is received
virtual void OnEvent(int i, int fd) = 0;
// Called when timing ticks are updated.
// Returns the largest number of microseconds this function can
// wait till next call.
virtual UInt64 OnTicks(UInt64 ticksMks)
{
OVR_UNUSED1(ticksMks);
return Timer::MksPerSecond * 1000;
}
};
// Add I/O notifier
bool AddSelectFd(Notifier* notify, int fd);
bool RemoveSelectFd(Notifier* notify, int fd);
// Add notifier that will be called at regular intervals.
bool AddTicksNotifier(Notifier* notify);
bool RemoveTicksNotifier(Notifier* notify);
private:
bool threadInitialized() { return CommandFd[0] != 0; }
// pipe used to signal commands
int CommandFd[2];
Array<struct pollfd> PollFds;
Array<Notifier*> FdNotifiers;
Event StartupEvent;
// Ticks notifiers - used for time-dependent events such as keep-alive.
Array<Notifier*> TicksNotifiers;
};
}} // namespace Linux::OVR
#endif // OVR_Linux_DeviceManager_h

View file

@ -1,124 +0,0 @@
/************************************************************************************
Filename : OVR_Linux_HIDDevice.h
Content : Linux HID device implementation.
Created : June 13, 2013
Authors : Brant Lewis
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_LINUX_HIDDevice_h
#define OVR_LINUX_HIDDevice_h
#include "OVR_HIDDevice.h"
#include "OVR_Linux_DeviceManager.h"
#include <libudev.h>
namespace OVR { namespace Linux {
class HIDDeviceManager;
//-------------------------------------------------------------------------------------
// ***** Linux HIDDevice
class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier
{
private:
friend class HIDDeviceManager;
public:
HIDDevice(HIDDeviceManager* manager);
// This is a minimal constructor used during enumeration for us to pass
// a HIDDevice to the visit function (so that it can query feature reports).
HIDDevice(HIDDeviceManager* manager, int device_handle);
virtual ~HIDDevice();
bool HIDInitialize(const String& path);
void HIDShutdown();
virtual bool SetFeatureReport(UByte* data, UInt32 length);
virtual bool GetFeatureReport(UByte* data, UInt32 length);
// DeviceManagerThread::Notifier
void OnEvent(int i, int fd);
UInt64 OnTicks(UInt64 ticksMks);
bool OnDeviceNotification(MessageType messageType,
HIDDeviceDesc* device_info,
bool* error);
private:
bool initInfo();
bool openDevice(const char* dev_path);
void closeDevice(bool wasUnplugged);
void closeDeviceOnIOError();
bool setupDevicePluggedInNotification();
bool InMinimalMode;
HIDDeviceManager* HIDManager;
int DeviceHandle; // file handle to the device
HIDDeviceDesc DevDesc;
enum { ReadBufferSize = 96 };
UByte ReadBuffer[ReadBufferSize];
UInt16 InputReportBufferLength;
UInt16 OutputReportBufferLength;
UInt16 FeatureReportBufferLength;
};
//-------------------------------------------------------------------------------------
// ***** Linux HIDDeviceManager
class HIDDeviceManager : public OVR::HIDDeviceManager, public DeviceManagerThread::Notifier
{
friend class HIDDevice;
public:
HIDDeviceManager(Linux::DeviceManager* Manager);
virtual ~HIDDeviceManager();
virtual bool Initialize();
virtual void Shutdown();
virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor);
virtual OVR::HIDDevice* Open(const String& path);
static HIDDeviceManager* CreateInternal(DeviceManager* manager);
void OnEvent(int i, int fd);
private:
bool initializeManager();
bool initVendorProductVersion(udev_device* device, HIDDeviceDesc* pDevDesc);
bool getPath(udev_device* device, String* pPath);
bool getIntProperty(udev_device* device, const char* key, int32_t* pResult);
bool getStringProperty(udev_device* device,
const char* propertyName,
OVR::String* pResult);
bool getFullDesc(udev_device* device, HIDDeviceDesc* desc);
bool GetDescriptorFromPath(const char* dev_path, HIDDeviceDesc* desc);
bool AddNotificationDevice(HIDDevice* device);
bool RemoveNotificationDevice(HIDDevice* device);
DeviceManager* DevManager;
udev* UdevInstance; // a handle to the udev library instance
udev_monitor* HIDMonitor;
int HIDMonHandle; // the udev_monitor file handle
Array<HIDDevice*> NotificationDevices;
};
}} // namespace OVR::Linux
#endif // OVR_Linux_HIDDevice_h

View file

@ -1,156 +0,0 @@
/************************************************************************************
Filename : OVR_Linux_HMDDevice.h
Content : Linux HMDDevice implementation
Created : June 17, 2013
Authors : Brant Lewis
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_Linux_HMDDevice_h
#define OVR_Linux_HMDDevice_h
#include "OVR_Linux_DeviceManager.h"
#include "OVR_Profile.h"
namespace OVR { namespace Linux {
class HMDDevice;
//-------------------------------------------------------------------------------------
// HMDDeviceFactory enumerates attached Oculus HMD devices.
//
// This is currently done by matching monitor device strings.
class HMDDeviceFactory : public DeviceFactory
{
public:
static HMDDeviceFactory Instance;
// Enumerates devices, creating and destroying relevant objects in manager.
virtual void EnumerateDevices(EnumerateVisitor& visitor);
protected:
DeviceManager* getManager() const { return (DeviceManager*) pManager; }
};
class HMDDeviceCreateDesc : public DeviceCreateDesc
{
friend class HMDDevice;
protected:
enum
{
Contents_Screen = 1,
Contents_Distortion = 2,
Contents_7Inch = 4,
};
String DeviceId;
String DisplayDeviceName;
int DesktopX, DesktopY;
unsigned Contents;
unsigned HResolution, VResolution;
float HScreenSize, VScreenSize;
long DisplayId;
float DistortionK[4];
public:
HMDDeviceCreateDesc(DeviceFactory* factory, const String& displayDeviceName, long dispId);
HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other);
virtual DeviceCreateDesc* Clone() const
{
return new HMDDeviceCreateDesc(*this);
}
virtual DeviceBase* NewDeviceInstance();
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc**) const;
// Matches device by path.
virtual bool MatchDevice(const String& path);
virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
Profile* GetProfileAddRef() const;
ProfileType GetProfileType() const
{
return (HResolution >= 1920) ? Profile_RiftDKHD : Profile_RiftDK1;
}
void SetScreenParameters(int x, int y, unsigned hres, unsigned vres, float hsize, float vsize)
{
DesktopX = x;
DesktopY = y;
HResolution = hres;
VResolution = vres;
HScreenSize = hsize;
VScreenSize = vsize;
Contents |= Contents_Screen;
}
void SetDistortion(const float* dks)
{
for (int i = 0; i < 4; i++)
DistortionK[i] = dks[i];
Contents |= Contents_Distortion;
}
void Set7Inch() { Contents |= Contents_7Inch; }
bool Is7Inch() const;
};
//-------------------------------------------------------------------------------------
// HMDDevice represents an Oculus HMD device unit. An instance of this class
// is typically created from the DeviceManager.
// After HMD device is created, we its sensor data can be obtained by
// first creating a Sensor object and then wrappig it in SensorFusion.
class HMDDevice : public DeviceImpl<OVR::HMDDevice>
{
public:
HMDDevice(HMDDeviceCreateDesc* createDesc);
~HMDDevice();
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
virtual Profile* GetProfile() const;
virtual const char* GetProfileName() const;
virtual bool SetProfileName(const char* name);
// Query associated sensor.
virtual OVR::SensorDevice* GetSensor();
protected:
HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); }
// User name for the profile used with this device.
String ProfileName;
mutable Ptr<Profile> pCachedProfile;
};
}} // namespace OVR::Linux
#endif // OVR_Linux_HMDDevice_h

View file

@ -1,119 +0,0 @@
/************************************************************************************
Filename : OVR_OSX_DeviceManager.h
Content : OSX specific DeviceManager header.
Created : March 14, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_OSX_DeviceManager_h
#define OVR_OSX_DeviceManager_h
#include "OVR_DeviceImpl.h"
#include "Kernel/OVR_Timer.h"
#include <IOKit/hid/IOHIDManager.h>
#include <CoreGraphics/CGDirectDisplay.h>
#include <CoreGraphics/CGDisplayConfiguration.h>
namespace OVR { namespace OSX {
class DeviceManagerThread;
//-------------------------------------------------------------------------------------
// ***** OSX DeviceManager
class DeviceManager : public DeviceManagerImpl
{
public:
DeviceManager();
~DeviceManager();
// Initialize/Shutdown manager thread.
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
virtual ThreadCommandQueue* GetThreadQueue();
virtual ThreadId GetThreadId() const;
virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
protected:
static void displayReconfigurationCallBack (CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo);
public: // data
Ptr<DeviceManagerThread> pThread;
};
//-------------------------------------------------------------------------------------
// ***** Device Manager Background Thread
class DeviceManagerThread : public Thread, public ThreadCommandQueue
{
friend class DeviceManager;
enum { ThreadStackSize = 32 * 1024 };
public:
DeviceManagerThread();
~DeviceManagerThread();
virtual int Run();
// ThreadCommandQueue notifications for CommandEvent handling.
virtual void OnPushNonEmpty_Locked()
{
CFRunLoopSourceSignal(CommandQueueSource);
CFRunLoopWakeUp(RunLoop);
}
virtual void OnPopEmpty_Locked() {}
// Notifier used for different updates (EVENT or regular timing or messages).
class Notifier
{
public:
// Called when timing ticks are updated. // Returns the largest number of microseconds
// this function can wait till next call.
virtual UInt64 OnTicks(UInt64 ticksMks)
{ OVR_UNUSED1(ticksMks); return Timer::MksPerSecond * 1000; }
};
// Add notifier that will be called at regular intervals.
bool AddTicksNotifier(Notifier* notify);
bool RemoveTicksNotifier(Notifier* notify);
CFRunLoopRef GetRunLoop()
{ return RunLoop; }
void Shutdown();
private:
CFRunLoopRef RunLoop;
CFRunLoopSourceRef CommandQueueSource;
static void staticCommandQueueSourceCallback(void* pContext);
void commandQueueSourceCallback();
Event StartupEvent;
// Ticks notifiers. Used for time-dependent events such as keep-alive.
Array<Notifier*> TicksNotifiers;
};
}} // namespace OSX::OVR
#endif // OVR_OSX_DeviceManager_h

View file

@ -1,149 +0,0 @@
/************************************************************************************
Filename : OVR_OSX_HIDDevice.h
Content : OSX HID device implementation.
Created : February 26, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_OSX_HIDDevice_h
#define OVR_OSX_HIDDevice_h
#include "OVR_HIDDevice.h"
#include "OVR_OSX_DeviceManager.h"
#include <IOKit/IOKitLib.h>
namespace OVR { namespace OSX {
class HIDDeviceManager;
//-------------------------------------------------------------------------------------
// ***** OSX HIDDevice
class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier
{
private:
friend class HIDDeviceManager;
public:
HIDDevice(HIDDeviceManager* manager);
// This is a minimal constructor used during enumeration for us to pass
// a HIDDevice to the visit function (so that it can query feature reports).
HIDDevice(HIDDeviceManager* manager, IOHIDDeviceRef device);
virtual ~HIDDevice();
bool HIDInitialize(const String& path);
void HIDShutdown();
virtual bool SetFeatureReport(UByte* data, UInt32 length);
virtual bool GetFeatureReport(UByte* data, UInt32 length);
bool Write(UByte* data, UInt32 length);
bool Read(UByte* pData, UInt32 length, UInt32 timeoutMilliS);
bool ReadBlocking(UByte* pData, UInt32 length);
// DeviceManagerThread::Notifier
UInt64 OnTicks(UInt64 ticksMks);
private:
bool initInfo();
bool openDevice();
void closeDevice(bool wasUnplugged);
bool setupDevicePluggedInNotification();
CFStringRef generateRunLoopModeString(IOHIDDeviceRef device);
static void staticHIDReportCallback(void* pContext,
IOReturn result,
void* pSender,
IOHIDReportType reportType,
uint32_t reportId,
uint8_t* pReport,
CFIndex reportLength);
void hidReportCallback(UByte* pData, UInt32 length);
static void staticDeviceRemovedCallback(void* pContext,
IOReturn result,
void* pSender);
void deviceRemovedCallback();
static void staticDeviceAddedCallback(void* pContext,
io_iterator_t iterator);
void deviceAddedCallback(io_iterator_t iterator);
bool InMinimalMode;
HIDDeviceManager* HIDManager;
IOHIDDeviceRef Device;
HIDDeviceDesc DevDesc;
enum { ReadBufferSize = 96 };
UByte ReadBuffer[ReadBufferSize];
UInt16 InputReportBufferLength;
UInt16 OutputReportBufferLength;
UInt16 FeatureReportBufferLength;
IONotificationPortRef RepluggedNotificationPort;
io_iterator_t RepluggedNotification;
};
//-------------------------------------------------------------------------------------
// ***** OSX HIDDeviceManager
class HIDDeviceManager : public OVR::HIDDeviceManager
{
friend class HIDDevice;
public:
HIDDeviceManager(OSX::DeviceManager* Manager);
virtual ~HIDDeviceManager();
virtual bool Initialize();
virtual void Shutdown();
virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor);
virtual OVR::HIDDevice* Open(const String& path);
static HIDDeviceManager* CreateInternal(DeviceManager* manager);
private:
CFRunLoopRef getRunLoop();
bool initializeManager();
bool initVendorProductVersion(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
bool initUsage(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
bool initStrings(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
bool initSerialNumber(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
bool getVendorId(IOHIDDeviceRef device, UInt16* pResult);
bool getProductId(IOHIDDeviceRef device, UInt16* pResult);
bool getLocationId(IOHIDDeviceRef device, SInt32* pResult);
bool getSerialNumberString(IOHIDDeviceRef device, String* pResult);
bool getPath(IOHIDDeviceRef device, String* pPath);
bool getIntProperty(IOHIDDeviceRef device, CFStringRef key, int32_t* pResult);
bool getStringProperty(IOHIDDeviceRef device, CFStringRef propertyName, String* pResult);
bool getFullDesc(IOHIDDeviceRef device, HIDDeviceDesc* desc);
static void staticDeviceMatchingCallback(void *inContext,
IOReturn inResult,
void *inSender,
IOHIDDeviceRef inIOHIDDeviceRef);
DeviceManager* DevManager;
IOHIDManagerRef HIDManager;
};
}} // namespace OVR::OSX
#endif // OVR_OSX_HIDDevice_h

View file

@ -1,160 +0,0 @@
/************************************************************************************
Filename : OVR_OSX_HMDDevice.h
Content : OSX HMDDevice implementation
Created : September 21, 2012
Authors : Michael Antonov
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_OSX_HMDDevice_h
#define OVR_OSX_HMDDevice_h
#include "OVR_DeviceImpl.h"
#include <Kernel/OVR_String.h>
#include "OVR_Profile.h"
namespace OVR { namespace OSX {
class HMDDevice;
//-------------------------------------------------------------------------------------
// HMDDeviceFactory enumerates attached Oculus HMD devices.
//
// This is currently done by matching monitor device strings.
class HMDDeviceFactory : public DeviceFactory
{
public:
static HMDDeviceFactory Instance;
// Enumerates devices, creating and destroying relevant objects in manager.
virtual void EnumerateDevices(EnumerateVisitor& visitor);
protected:
DeviceManager* getManager() const { return (DeviceManager*) pManager; }
};
class HMDDeviceCreateDesc : public DeviceCreateDesc
{
friend class HMDDevice;
protected:
enum
{
Contents_Screen = 1,
Contents_Distortion = 2,
Contents_7Inch = 4,
};
public:
HMDDeviceCreateDesc(DeviceFactory* factory,
UInt32 vendor, UInt32 product, const String& displayDeviceName, long dispId);
HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other);
virtual DeviceCreateDesc* Clone() const
{
return new HMDDeviceCreateDesc(*this);
}
virtual DeviceBase* NewDeviceInstance();
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc**) const;
virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
Profile* GetProfileAddRef() const;
ProfileType GetProfileType() const
{
return (HResolution >= 1920) ? Profile_RiftDKHD : Profile_RiftDK1;
}
void SetScreenParameters(int x, int y, unsigned hres, unsigned vres, float hsize, float vsize)
{
DesktopX = x;
DesktopY = y;
HResolution = hres;
VResolution = vres;
HScreenSize = hsize;
VScreenSize = vsize;
Contents |= Contents_Screen;
}
void SetDistortion(const float* dks)
{
for (int i = 0; i < 4; i++)
DistortionK[i] = dks[i];
Contents |= Contents_Distortion;
}
void Set7Inch() { Contents |= Contents_7Inch; }
bool Is7Inch() const;
protected:
String DeviceId;
String DisplayDeviceName;
int DesktopX, DesktopY;
unsigned Contents;
unsigned HResolution, VResolution;
float HScreenSize, VScreenSize;
long DisplayId;
float DistortionK[4];
};
//-------------------------------------------------------------------------------------
// HMDDevice represents an Oculus HMD device unit. An instance of this class
// is typically created from the DeviceManager.
// After HMD device is created, we its sensor data can be obtained by
// first creating a Sensor object and then wrappig it in SensorFusion.
class HMDDevice : public DeviceImpl<OVR::HMDDevice>
{
public:
HMDDevice(HMDDeviceCreateDesc* createDesc);
~HMDDevice();
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
virtual Profile* GetProfile() const;
virtual const char* GetProfileName() const;
virtual bool SetProfileName(const char* name);
// Query associated sensor.
virtual OVR::SensorDevice* GetSensor();
protected:
HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); }
// User name for the profile used with this device.
String ProfileName;
mutable Ptr<Profile> pCachedProfile;
};
}} // namespace OVR::OSX
#endif // OVR_OSX_HMDDevice_h

View file

@ -1,243 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_Profile.h
Content : Structs and functions for loading and storing device profile settings
Created : February 14, 2013
Notes :
Profiles are used to store per-user settings that can be transferred and used
across multiple applications. For example, player IPD can be configured once
and reused for a unified experience across games. Configuration and saving of profiles
can be accomplished in game via the Profile API or by the official Oculus Configuration
Utility.
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_Profile_h
#define OVR_Profile_h
#include "Kernel/OVR_String.h"
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_Array.h"
namespace OVR {
// Defines the profile object for each device type
enum ProfileType
{
Profile_Unknown = 0,
Profile_GenericHMD = 10,
Profile_RiftDK1 = 11,
Profile_RiftDKHD = 12,
};
class Profile;
// -----------------------------------------------------------------------------
// ***** ProfileManager
// Profiles are interfaced through a ProfileManager object. Applications should
// create a ProfileManager each time they intend to read or write user profile data.
// The scope of the ProfileManager object defines when disk I/O is performed. Disk
// reads are performed on the first profile access and disk writes are performed when
// the ProfileManager goes out of scope. All profile interactions between these times
// are performed in local memory and are fast. A typical profile interaction might
// look like this:
//
// {
// Ptr<ProfileManager> pm = *ProfileManager::Create();
// Ptr<Profile> profile = pm->LoadProfile(Profile_RiftDK1,
// pm->GetDefaultProfileName(Profile_RiftDK1));
// if (profile)
// { // Retrieve the current profile settings
// }
// } // Profile will be destroyed and any disk I/O completed when going out of scope
class ProfileManager : public RefCountBase<ProfileManager>
{
protected:
// Synchronize ProfileManager access since it may be accessed from multiple threads,
// as it's shared through DeviceManager.
Lock ProfileLock;
Array<Ptr<Profile> > ProfileCache;
ProfileType CacheDevice;
String DefaultProfile;
bool Changed;
char NameBuff[32];
public:
static ProfileManager* Create();
// Static interface functions
int GetProfileCount(ProfileType device);
const char* GetProfileName(ProfileType device, unsigned int index);
bool HasProfile(ProfileType device, const char* name);
Profile* LoadProfile(ProfileType device, unsigned int index);
Profile* LoadProfile(ProfileType device, const char* name);
Profile* GetDeviceDefaultProfile(ProfileType device);
const char* GetDefaultProfileName(ProfileType device);
bool SetDefaultProfileName(ProfileType device, const char* name);
bool Save(const Profile* profile);
bool Delete(const Profile* profile);
protected:
ProfileManager();
~ProfileManager();
void LoadCache(ProfileType device);
void SaveCache();
void ClearCache();
Profile* CreateProfileObject(const char* user,
ProfileType device,
const char** device_name);
};
//-------------------------------------------------------------------
// ***** Profile
// The base profile for all users. This object is not created directly.
// Instead derived device objects provide add specific device members to
// the base profile
class Profile : public RefCountBase<Profile>
{
public:
enum { MaxNameLen = 32 };
enum GenderType
{
Gender_Unspecified = 0,
Gender_Male = 1,
Gender_Female = 2
};
ProfileType Type; // The type of device profile
char Name[MaxNameLen]; // The name given to this profile
protected:
GenderType Gender; // The gender of the user
float PlayerHeight; // The height of the user in meters
float IPD; // Distance between eyes in meters
public:
virtual Profile* Clone() const = 0;
// These are properties which are intrinsic to the user and affect scene setup
GenderType GetGender() { return Gender; };
float GetPlayerHeight() { return PlayerHeight; };
float GetIPD() { return IPD; };
float GetEyeHeight();
void SetGender(GenderType gender) { Gender = gender; };
void SetPlayerHeight(float height) { PlayerHeight = height; };
void SetIPD(float ipd) { IPD = ipd; };
protected:
Profile(ProfileType type, const char* name);
virtual bool ParseProperty(const char* prop, const char* sval);
friend class ProfileManager;
};
//-----------------------------------------------------------------------------
// ***** HMDProfile
// The generic HMD profile is used for properties that are common to all headsets
class HMDProfile : public Profile
{
protected:
// FOV extents in pixels measured by a user
int LL; // left eye outer extent
int LR; // left eye inner extent
int RL; // right eye inner extent
int RR; // right eye outer extent
public:
virtual Profile* Clone() const;
void SetLL(int val) { LL = val; };
void SetLR(int val) { LR = val; };
void SetRL(int val) { RL = val; };
void SetRR(int val) { RR = val; };
int GetLL() { return LL; };
int GetLR() { return LR; };
int GetRL() { return RL; };
int GetRR() { return RR; };
protected:
HMDProfile(ProfileType type, const char* name);
virtual bool ParseProperty(const char* prop, const char* sval);
friend class ProfileManager;
};
// For headsets that use eye cups
enum EyeCupType
{
EyeCup_A = 0,
EyeCup_B = 1,
EyeCup_C = 2
};
//-----------------------------------------------------------------------------
// ***** RiftDK1Profile
// This profile is specific to the Rift Dev Kit 1 and contains overrides specific
// to that device and lens cup settings.
class RiftDK1Profile : public HMDProfile
{
protected:
EyeCupType EyeCups; // Which eye cup does the player use
public:
virtual Profile* Clone() const;
EyeCupType GetEyeCup() { return EyeCups; };
void SetEyeCup(EyeCupType cup) { EyeCups = cup; };
protected:
RiftDK1Profile(const char* name);
virtual bool ParseProperty(const char* prop, const char* sval);
friend class ProfileManager;
};
//-----------------------------------------------------------------------------
// ***** RiftDKHDProfile
// This profile is specific to the Rift HD Dev Kit and contains overrides specific
// to that device and lens cup settings.
class RiftDKHDProfile : public HMDProfile
{
protected:
EyeCupType EyeCups; // Which eye cup does the player use
public:
virtual Profile* Clone() const;
EyeCupType GetEyeCup() { return EyeCups; };
void SetEyeCup(EyeCupType cup) { EyeCups = cup; };
protected:
RiftDKHDProfile(const char* name);
virtual bool ParseProperty(const char* prop, const char* sval);
friend class ProfileManager;
};
String GetBaseOVRPath(bool create_dir);
}
#endif // OVR_Profile_h

View file

@ -1,202 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_SensorFilter.h
Content : Basic filtering of sensor data
Created : March 7, 2013
Authors : Steve LaValle, Anna Yershova, Max Katsev
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_SensorFilter_h
#define OVR_SensorFilter_h
#include "Kernel/OVR_Math.h"
namespace OVR {
// A simple circular buffer data structure that stores last N elements in an array
template <typename T>
class CircularBuffer
{
protected:
enum
{
DefaultFilterCapacity = 20
};
int LastIdx; // The index of the last element that was added to the buffer
int Capacity; // The buffer size (maximum number of elements)
int Count; // Number of elements in the filter
T* Elements;
public:
CircularBuffer(int capacity = DefaultFilterCapacity)
: LastIdx(-1), Capacity(capacity), Count(0)
{
Elements = (T*)OVR_ALLOC(capacity * sizeof(T));
for (int i = 0; i < Capacity; i++)
Elements[i] = T();
}
~CircularBuffer() {
OVR_FREE(Elements);
}
private:
// Make the class non-copyable
CircularBuffer(const CircularBuffer& other);
CircularBuffer& operator=(const CircularBuffer& other);
public:
// Add a new element to the filter
void AddElement (const T &e)
{
LastIdx = (LastIdx + 1) % Capacity;
Elements[LastIdx] = e;
if (Count < Capacity)
Count++;
}
// Get element i. 0 is the most recent, 1 is one step ago, 2 is two steps ago, ...
T GetPrev(int i = 0) const
{
OVR_ASSERT(i >= 0);
if (i >= Count) // return 0 if the filter doesn't have enough elements
return T();
int idx = (LastIdx - i);
if (idx < 0) // Fix the wraparound case
idx += Capacity;
OVR_ASSERT(idx >= 0); // Multiple wraparounds not allowed
return Elements[idx];
}
};
// A base class for filters that maintains a buffer of sensor data taken over time and implements
// various simple filters, most of which are linear functions of the data history.
// Maintains the running sum of its elements for better performance on large capacity values
template <typename T>
class SensorFilterBase : public CircularBuffer<T>
{
protected:
T RunningTotal; // Cached sum of the elements
public:
SensorFilterBase(int capacity = CircularBuffer<T>::DefaultFilterCapacity) : CircularBuffer<T>(capacity), RunningTotal() { };
// Add a new element to the filter
// Updates the running sum value
void AddElement (const T &e)
{
int NextIdx = (this->LastIdx + 1) % this->Capacity;
RunningTotal += (e - this->Elements[NextIdx]);
CircularBuffer<T>::AddElement(e);
if (this->LastIdx == 0)
{
// update the cached total to avoid error accumulation
RunningTotal = T();
for (int i = 0; i < this->Count; i++)
RunningTotal += this->Elements[i];
}
}
// Simple statistics
T Total() const
{
return RunningTotal;
}
T Mean() const
{
return (this->Count == 0) ? T() : (Total() / (float) this->Count);
}
// A popular family of smoothing filters and smoothed derivatives
T SavitzkyGolaySmooth8() const
{
OVR_ASSERT(this->Capacity >= 8);
return this->GetPrev(0)*0.41667f +
this->GetPrev(1)*0.33333f +
this->GetPrev(2)*0.25f +
this->GetPrev(3)*0.16667f +
this->GetPrev(4)*0.08333f -
this->GetPrev(6)*0.08333f -
this->GetPrev(7)*0.16667f;
}
T SavitzkyGolayDerivative4() const
{
OVR_ASSERT(this->Capacity >= 4);
return this->GetPrev(0)*0.3f +
this->GetPrev(1)*0.1f -
this->GetPrev(2)*0.1f -
this->GetPrev(3)*0.3f;
}
T SavitzkyGolayDerivative5() const
{
OVR_ASSERT(this->Capacity >= 5);
return this->GetPrev(0)*0.2f +
this->GetPrev(1)*0.1f -
this->GetPrev(3)*0.1f -
this->GetPrev(4)*0.2f;
}
T SavitzkyGolayDerivative12() const
{
OVR_ASSERT(this->Capacity >= 12);
return this->GetPrev(0)*0.03846f +
this->GetPrev(1)*0.03147f +
this->GetPrev(2)*0.02448f +
this->GetPrev(3)*0.01748f +
this->GetPrev(4)*0.01049f +
this->GetPrev(5)*0.0035f -
this->GetPrev(6)*0.0035f -
this->GetPrev(7)*0.01049f -
this->GetPrev(8)*0.01748f -
this->GetPrev(9)*0.02448f -
this->GetPrev(10)*0.03147f -
this->GetPrev(11)*0.03846f;
}
T SavitzkyGolayDerivativeN(int n) const
{
OVR_ASSERT(this->Capacity >= n);
int m = (n-1)/2;
T result = T();
for (int k = 1; k <= m; k++)
{
int ind1 = m - k;
int ind2 = n - m + k - 1;
result += (this->GetPrev(ind1) - this->GetPrev(ind2)) * (float) k;
}
float coef = 3.0f/(m*(m+1.0f)*(2.0f*m+1.0f));
result = result*coef;
return result;
}
};
// This class maintains a buffer of sensor data taken over time and implements
// various simple filters, most of which are linear functions of the data history.
class SensorFilter : public SensorFilterBase<Vector3f>
{
public:
SensorFilter(int capacity = DefaultFilterCapacity) : SensorFilterBase<Vector3f>(capacity) { };
// Simple statistics
Vector3f Median() const;
Vector3f Variance() const; // The diagonal of covariance matrix
Matrix4f Covariance() const;
Vector3f PearsonCoefficient() const;
};
} //namespace OVR
#endif // OVR_SensorFilter_h

View file

@ -1,253 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : OVR_SensorFusion.h
Content : Methods that determine head orientation from sensor data over time
Created : October 9, 2012
Authors : Michael Antonov, Steve LaValle, Max Katsev
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_SensorFusion_h
#define OVR_SensorFusion_h
#include "OVR_Device.h"
#include "OVR_SensorFilter.h"
#include <time.h>
namespace OVR {
//-------------------------------------------------------------------------------------
// ***** SensorFusion
// SensorFusion class accumulates Sensor notification messages to keep track of
// orientation, which involves integrating the gyro and doing correction with gravity.
// Magnetometer based yaw drift correction is also supported; it is usually enabled
// automatically based on loaded magnetometer configuration.
// Orientation is reported as a quaternion, from which users can obtain either the
// rotation matrix or Euler angles.
//
// The class can operate in two ways:
// - By user manually passing MessageBodyFrame messages to the OnMessage() function.
// - By attaching SensorFusion to a SensorDevice, in which case it will
// automatically handle notifications from that device.
class SensorFusion : public NewOverrideBase
{
enum
{
MagMaxReferences = 1000
};
public:
SensorFusion(SensorDevice* sensor = 0);
~SensorFusion();
// *** Setup
// Attaches this SensorFusion to a sensor device, from which it will receive
// notification messages. If a sensor is attached, manual message notification
// is not necessary. Calling this function also resets SensorFusion state.
bool AttachToSensor(SensorDevice* sensor);
// Returns true if this Sensor fusion object is attached to a sensor.
bool IsAttachedToSensor() const { return Handler.IsHandlerInstalled(); }
// *** State Query
// Obtain the current accumulated orientation. Many apps will want to use GetPredictedOrientation
// instead to reduce latency.
Quatf GetOrientation() const { return lockedGet(&Q); }
// Get predicted orientaion in the near future; predictDt is lookahead amount in seconds.
Quatf GetPredictedOrientation(float predictDt);
Quatf GetPredictedOrientation() { return GetPredictedOrientation(PredictionDT); }
// Obtain the last absolute acceleration reading, in m/s^2.
Vector3f GetAcceleration() const { return lockedGet(&A); }
// Obtain the last angular velocity reading, in rad/s.
Vector3f GetAngularVelocity() const { return lockedGet(&AngV); }
// Obtain the last raw magnetometer reading, in Gauss
Vector3f GetMagnetometer() const { return lockedGet(&RawMag); }
// Obtain the calibrated magnetometer reading (direction and field strength)
Vector3f GetCalibratedMagnetometer() const { OVR_ASSERT(MagCalibrated); return lockedGet(&CalMag); }
// Resets the current orientation.
void Reset();
// *** Configuration
void EnableMotionTracking(bool enable = true) { MotionTrackingEnabled = enable; }
bool IsMotionTrackingEnabled() const { return MotionTrackingEnabled; }
// *** Prediction Control
// Prediction functions.
// Prediction delta specifes how much prediction should be applied in seconds; it should in
// general be under the average rendering latency. Call GetPredictedOrientation() to get
// predicted orientation.
float GetPredictionDelta() const { return PredictionDT; }
void SetPrediction(float dt, bool enable = true) { PredictionDT = dt; EnablePrediction = enable; }
void SetPredictionEnabled(bool enable = true) { EnablePrediction = enable; }
bool IsPredictionEnabled() { return EnablePrediction; }
// *** Accelerometer/Gravity Correction Control
// Enables/disables gravity correction (on by default).
void SetGravityEnabled(bool enableGravity) { EnableGravity = enableGravity; }
bool IsGravityEnabled() const { return EnableGravity;}
// Gain used to correct gyro with accel. Default value is appropriate for typical use.
float GetAccelGain() const { return Gain; }
void SetAccelGain(float ag) { Gain = ag; }
// *** Magnetometer and Yaw Drift Correction Control
// Methods to load and save a mag calibration. Calibrations can optionally
// be specified by name to differentiate multiple calibrations under different conditions
// If LoadMagCalibration succeeds, it will override YawCorrectionEnabled based on
// saved calibration setting.
bool SaveMagCalibration(const char* calibrationName = NULL) const;
bool LoadMagCalibration(const char* calibrationName = NULL);
// Enables/disables magnetometer based yaw drift correction. Must also have mag calibration
// data for this correction to work.
void SetYawCorrectionEnabled(bool enable) { EnableYawCorrection = enable; }
// Determines if yaw correction is enabled.
bool IsYawCorrectionEnabled() const { return EnableYawCorrection;}
// Store the calibration matrix for the magnetometer
void SetMagCalibration(const Matrix4f& m)
{
MagCalibrationMatrix = m;
time(&MagCalibrationTime); // time stamp the calibration
MagCalibrated = true;
}
// Retrieves the magnetometer calibration matrix
Matrix4f GetMagCalibration() const { return MagCalibrationMatrix; }
// Retrieve the time of the calibration
time_t GetMagCalibrationTime() const { return MagCalibrationTime; }
// True only if the mag has calibration values stored
bool HasMagCalibration() const { return MagCalibrated;}
// Force the mag into the uncalibrated state
void ClearMagCalibration() { MagCalibrated = false; }
// These refer to reference points that associate mag readings with orientations
void ClearMagReferences() { MagNumReferences = 0; }
Vector3f GetCalibratedMagValue(const Vector3f& rawMag) const;
// *** Message Handler Logic
// Notifies SensorFusion object about a new BodyFrame message from a sensor.
// Should be called by user if not attaching to a sensor.
void OnMessage(const MessageBodyFrame& msg)
{
OVR_ASSERT(!IsAttachedToSensor());
handleMessage(msg);
}
void SetDelegateMessageHandler(MessageHandler* handler)
{ pDelegate = handler; }
private:
SensorFusion* getThis() { return this; }
// Helper used to read and return value within a Lock.
template<class C>
C lockedGet(const C* p) const
{
Lock::Locker lockScope(Handler.GetHandlerLock());
return *p;
}
// Internal handler for messages; bypasses error checking.
void handleMessage(const MessageBodyFrame& msg);
// Set the magnetometer's reference orientation for use in yaw correction
// The supplied mag is an uncalibrated value
void setMagReference(const Quatf& q, const Vector3f& rawMag);
// Default to current HMD orientation
void setMagReference() { setMagReference(Q, RawMag); }
class BodyFrameHandler : public MessageHandler
{
SensorFusion* pFusion;
public:
BodyFrameHandler(SensorFusion* fusion) : pFusion(fusion) { }
~BodyFrameHandler();
virtual void OnMessage(const Message& msg);
virtual bool SupportsMessageType(MessageType type) const;
};
SensorInfo CachedSensorInfo;
Quatf Q;
Quatf QUncorrected;
Vector3f A;
Vector3f AngV;
Vector3f CalMag;
Vector3f RawMag;
unsigned int Stage;
float RunningTime;
float DeltaT;
BodyFrameHandler Handler;
MessageHandler* pDelegate;
float Gain;
volatile bool EnableGravity;
bool EnablePrediction;
float PredictionDT;
float PredictionTimeIncrement;
SensorFilter FRawMag;
SensorFilter FAngV;
Vector3f GyroOffset;
SensorFilterBase<float> TiltAngleFilter;
bool EnableYawCorrection;
bool MagCalibrated;
Matrix4f MagCalibrationMatrix;
time_t MagCalibrationTime;
int MagNumReferences;
Vector3f MagRefsInBodyFrame[MagMaxReferences];
Vector3f MagRefsInWorldFrame[MagMaxReferences];
int MagRefIdx;
int MagRefScore;
bool MotionTrackingEnabled;
};
} // namespace OVR
#endif

View file

@ -1,254 +0,0 @@
/************************************************************************************
Filename : OVR_SensorImpl.h
Content : Sensor device specific implementation.
Created : March 7, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_SensorImpl_h
#define OVR_SensorImpl_h
#include "OVR_HIDDeviceImpl.h"
namespace OVR {
struct TrackerMessage;
class ExternalVisitor;
//-------------------------------------------------------------------------------------
// SensorDeviceFactory enumerates Oculus Sensor devices.
class SensorDeviceFactory : public DeviceFactory
{
public:
static SensorDeviceFactory Instance;
// Enumerates devices, creating and destroying relevant objects in manager.
virtual void EnumerateDevices(EnumerateVisitor& visitor);
virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const;
virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc);
protected:
DeviceManager* getManager() const { return (DeviceManager*) pManager; }
};
// Describes a single a Oculus Sensor device and supports creating its instance.
class SensorDeviceCreateDesc : public HIDDeviceCreateDesc
{
public:
SensorDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc)
: HIDDeviceCreateDesc(factory, Device_Sensor, hidDesc) { }
virtual DeviceCreateDesc* Clone() const
{
return new SensorDeviceCreateDesc(*this);
}
virtual DeviceBase* NewDeviceInstance();
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc**) const
{
if ((other.Type == Device_Sensor) && (pFactory == other.pFactory))
{
const SensorDeviceCreateDesc& s2 = (const SensorDeviceCreateDesc&) other;
if (MatchHIDDevice(s2.HIDDesc))
return Match_Found;
}
return Match_None;
}
virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const
{
// should paths comparison be case insensitive?
return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) &&
(HIDDesc.SerialNumber == hidDesc.SerialNumber) &&
(HIDDesc.VersionNumber == hidDesc.VersionNumber));
}
virtual bool GetDeviceInfo(DeviceInfo* info) const;
};
// A simple stub for notification of a sensor in Boot Loader mode
// This descriptor does not support the creation of a device, only the detection
// of its existence to warn apps that the sensor device needs firmware.
// The Boot Loader descriptor reuses and is created by the Sensor device factory
// but in the future may use a dedicated factory
class BootLoaderDeviceCreateDesc : public HIDDeviceCreateDesc
{
public:
BootLoaderDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc)
: HIDDeviceCreateDesc(factory, Device_BootLoader, hidDesc) { }
virtual DeviceCreateDesc* Clone() const
{
return new BootLoaderDeviceCreateDesc(*this);
}
// Boot Loader device creation is not allowed
virtual DeviceBase* NewDeviceInstance() { return NULL; };
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc**) const
{
if ((other.Type == Device_BootLoader) && (pFactory == other.pFactory))
{
const BootLoaderDeviceCreateDesc& s2 = (const BootLoaderDeviceCreateDesc&) other;
if (MatchHIDDevice(s2.HIDDesc))
return Match_Found;
}
return Match_None;
}
virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const
{
// should paths comparison be case insensitive?
return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) &&
(HIDDesc.SerialNumber == hidDesc.SerialNumber));
}
virtual bool GetDeviceInfo(DeviceInfo* info) const
{
OVR_UNUSED(info);
return false;
}
};
//-------------------------------------------------------------------------------------
// ***** OVR::SensorDisplayInfoImpl
// DisplayInfo obtained from sensor; these values are used to report distortion
// settings and other coefficients.
// Older SensorDisplayInfo will have all zeros, causing the library to apply hard-coded defaults.
// Currently, only resolutions and sizes are used.
struct SensorDisplayInfoImpl
{
enum { PacketSize = 56 };
UByte Buffer[PacketSize];
enum
{
Mask_BaseFmt = 0x0f,
Mask_OptionFmts = 0xf0,
Base_None = 0,
Base_ScreenOnly = 1,
Base_Distortion = 2,
};
UInt16 CommandId;
UByte DistortionType;
UInt16 HResolution, VResolution;
float HScreenSize, VScreenSize;
float VCenter;
float LensSeparation;
float EyeToScreenDistance[2];
float DistortionK[6];
SensorDisplayInfoImpl();
void Unpack();
};
//-------------------------------------------------------------------------------------
// ***** OVR::SensorDeviceImpl
// Oculus Sensor interface.
class SensorDeviceImpl : public HIDDeviceImpl<OVR::SensorDevice>
{
public:
SensorDeviceImpl(SensorDeviceCreateDesc* createDesc);
~SensorDeviceImpl();
// DeviceCommaon interface
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
virtual void SetMessageHandler(MessageHandler* handler);
// HIDDevice::Notifier interface.
virtual void OnInputReport(UByte* pData, UInt32 length);
virtual UInt64 OnTicks(UInt64 ticksMks);
// HMD-Mounted sensor has a different coordinate frame.
virtual void SetCoordinateFrame(CoordinateFrame coordframe);
virtual CoordinateFrame GetCoordinateFrame() const;
// SensorDevice interface
virtual bool SetRange(const SensorRange& range, bool waitFlag);
virtual void GetRange(SensorRange* range) const;
// Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call).
// Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be
// called twice or thrice at the same 'tick'.
// If the rate is < 333 then the OnMessage / MessageBodyFrame will be called three
// times for each 'tick': the first call will contain averaged values, the second
// and third calls will provide with most recent two recorded samples.
virtual void SetReportRate(unsigned rateHz);
// Returns currently set report rate, in Hz. If 0 - error occurred.
// Note, this value may be different from the one provided for SetReportRate. The return
// value will contain the actual rate.
virtual unsigned GetReportRate() const;
// Hack to create HMD device from sensor display info.
static void EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo,
DeviceFactory::EnumerateVisitor& visitor);
protected:
void openDevice();
void closeDeviceOnError();
Void setCoordinateFrame(CoordinateFrame coordframe);
bool setRange(const SensorRange& range);
Void setReportRate(unsigned rateHz);
// Called for decoded messages
void onTrackerMessage(TrackerMessage* message);
// Helpers to reduce casting.
/*
SensorDeviceCreateDesc* getCreateDesc() const
{ return (SensorDeviceCreateDesc*)pCreateDesc.GetPtr(); }
HIDDeviceDesc* getHIDDesc() const
{ return &getCreateDesc()->HIDDesc; }
*/
// Set if the sensor is located on the HMD.
// Older prototype firmware doesn't support changing HW coordinates,
// so we track its state.
CoordinateFrame Coordinates;
CoordinateFrame HWCoordinates;
UInt64 NextKeepAliveTicks;
bool SequenceValid;
SInt16 LastTimestamp;
UByte LastSampleCount;
float LastTemperature;
Vector3f LastAcceleration;
Vector3f LastRotationRate;
Vector3f LastMagneticField;
// Current sensor range obtained from device.
SensorRange MaxValidRange;
SensorRange CurrentRange;
UInt16 OldCommandId;
};
} // namespace OVR
#endif // OVR_SensorImpl_h

View file

@ -1,308 +0,0 @@
/************************************************************************************
PublicHeader: None
Filename : OVR_ThreadCommandQueue.h
Content : Command queue for operations executed on a thread
Created : October 29, 2012
Author : Michael Antonov
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
************************************************************************************/
#ifndef OVR_ThreadCommandQueue_h
#define OVR_ThreadCommandQueue_h
#include "Kernel/OVR_Types.h"
#include "Kernel/OVR_List.h"
#include "Kernel/OVR_Atomic.h"
#include "Kernel/OVR_Threads.h"
namespace OVR {
class ThreadCommand;
class ThreadCommandQueue;
//-------------------------------------------------------------------------------------
// ***** ThreadCommand
// ThreadCommand is a base class implementation for commands stored in ThreadCommandQueue.
class ThreadCommand
{
public:
// NotifyEvent is used by ThreadCommandQueue::PushCallAndWait to notify the
// calling (producer) thread when command is completed or queue slot is available.
class NotifyEvent : public ListNode<NotifyEvent>, public NewOverrideBase
{
Event E;
public:
NotifyEvent() { }
void Wait() { E.Wait(); }
void PulseEvent() { E.PulseEvent(); }
};
// ThreadCommand::PopBuffer is temporary storage for a command popped off
// by ThreadCommandQueue::PopCommand.
class PopBuffer
{
enum { MaxSize = 256 };
UPInt Size;
union {
UByte Buffer[MaxSize];
UPInt Align;
};
ThreadCommand* toCommand() const { return (ThreadCommand*)Buffer; }
public:
PopBuffer() : Size(0) { }
~PopBuffer();
void InitFromBuffer(void* data);
bool HasCommand() const { return Size != 0; }
UPInt GetSize() const { return Size; }
bool NeedsWait() const { return toCommand()->NeedsWait(); }
NotifyEvent* GetEvent() const { return toCommand()->pEvent; }
// Execute the command and also notifies caller to finish waiting,
// if necessary.
void Execute();
};
UInt16 Size;
bool WaitFlag;
bool ExitFlag; // Marks the last exit command.
NotifyEvent* pEvent;
ThreadCommand(UPInt size, bool waitFlag, bool exitFlag = false)
: Size((UInt16)size), WaitFlag(waitFlag), ExitFlag(exitFlag), pEvent(0) { }
virtual ~ThreadCommand() { }
bool NeedsWait() const { return WaitFlag; }
UPInt GetSize() const { return Size; }
virtual void Execute() const = 0;
// Copy constructor used for serializing this to memory buffer.
virtual ThreadCommand* CopyConstruct(void* p) const = 0;
};
//-------------------------------------------------------------------------------------
// CleanType is a template that strips 'const' and '&' modifiers from the argument type;
// for example, typename CleanType<A&>::Type is equivalent to A.
template<class T> struct CleanType { typedef T Type; };
template<class T> struct CleanType<T&> { typedef T Type; };
template<class T> struct CleanType<const T> { typedef T Type; };
template<class T> struct CleanType<const T&> { typedef T Type; };
// SelfType is a template that yields the argument type. This helps avoid conflicts with
// automatic template argument deduction for function calls when identical argument
// is already defined.
template<class T> struct SelfType { typedef T Type; };
//-------------------------------------------------------------------------------------
// ThreadCommand specializations for member functions with different number of
// arguments and argument types.
// Used to return nothing from a ThreadCommand, to avoid problems with 'void'.
struct Void
{
Void() {}
Void(int) {}
};
// ThreadCommand for member function with 0 arguments.
template<class C, class R>
class ThreadCommandMF0 : public ThreadCommand
{
typedef R (C::*FnPtr)();
C* pClass;
FnPtr pFn;
R* pRet;
void executeImpl() const
{
pRet ? (void)(*pRet = (pClass->*pFn)()) :
(void)(pClass->*pFn)();
}
public:
ThreadCommandMF0(C* pclass, FnPtr fn, R* ret, bool needsWait)
: ThreadCommand(sizeof(ThreadCommandMF0), needsWait),
pClass(pclass), pFn(fn), pRet(ret) { }
virtual void Execute() const { executeImpl(); }
virtual ThreadCommand* CopyConstruct(void* p) const
{ return Construct<ThreadCommandMF0>(p, *this); }
};
// ThreadCommand for member function with 1 argument.
template<class C, class R, class A0>
class ThreadCommandMF1 : public ThreadCommand
{
typedef R (C::*FnPtr)(A0);
C* pClass;
FnPtr pFn;
R* pRet;
typename CleanType<A0>::Type AVal0;
void executeImpl() const
{
pRet ? (void)(*pRet = (pClass->*pFn)(AVal0)) :
(void)(pClass->*pFn)(AVal0);
}
public:
ThreadCommandMF1(C* pclass, FnPtr fn, R* ret, A0 a0, bool needsWait)
: ThreadCommand(sizeof(ThreadCommandMF1), needsWait),
pClass(pclass), pFn(fn), pRet(ret), AVal0(a0) { }
virtual void Execute() const { executeImpl(); }
virtual ThreadCommand* CopyConstruct(void* p) const
{ return Construct<ThreadCommandMF1>(p, *this); }
};
// ThreadCommand for member function with 2 arguments.
template<class C, class R, class A0, class A1>
class ThreadCommandMF2 : public ThreadCommand
{
typedef R (C::*FnPtr)(A0, A1);
C* pClass;
FnPtr pFn;
R* pRet;
typename CleanType<A0>::Type AVal0;
typename CleanType<A1>::Type AVal1;
void executeImpl() const
{
pRet ? (void)(*pRet = (pClass->*pFn)(AVal0, AVal1)) :
(void)(pClass->*pFn)(AVal0, AVal1);
}
public:
ThreadCommandMF2(C* pclass, FnPtr fn, R* ret, A0 a0, A1 a1, bool needsWait)
: ThreadCommand(sizeof(ThreadCommandMF2), needsWait),
pClass(pclass), pFn(fn), pRet(ret), AVal0(a0), AVal1(a1) { }
virtual void Execute() const { executeImpl(); }
virtual ThreadCommand* CopyConstruct(void* p) const
{ return Construct<ThreadCommandMF2>(p, *this); }
};
//-------------------------------------------------------------------------------------
// ***** ThreadCommandQueue
// ThreadCommandQueue is a queue of executable function-call commands intended to be
// serviced by a single consumer thread. Commands are added to the queue with PushCall
// and removed with PopCall; they are processed in FIFO order. Multiple producer threads
// are supported and will be blocked if internal data buffer is full.
class ThreadCommandQueue
{
public:
ThreadCommandQueue();
virtual ~ThreadCommandQueue();
// Pops the next command from the thread queue, if any is available.
// The command should be executed by calling popBuffer->Execute().
// Returns 'false' if no command is available at the time of the call.
bool PopCommand(ThreadCommand::PopBuffer* popBuffer);
// Generic implementaion of PushCommand; enqueues a command for execution.
// Returns 'false' if push failed, usually indicating thread shutdown.
bool PushCommand(const ThreadCommand& command);
//
void PushExitCommand(bool wait);
// Returns 'true' once ExitCommand has been processed, so the thread can shut down.
bool IsExiting() const;
// These two virtual functions serve as notifications for derived
// thread waiting.
virtual void OnPushNonEmpty_Locked() { }
virtual void OnPopEmpty_Locked() { }
// *** PushCall with no result
// Enqueue a member function of 'this' class to be called on consumer thread.
// By default the function returns immediately; set 'wait' argument to 'true' to
// wait for completion.
template<class C, class R>
bool PushCall(R (C::*fn)(), bool wait = false)
{ return PushCommand(ThreadCommandMF0<C,R>(static_cast<C*>(this), fn, 0, wait)); }
template<class C, class R, class A0>
bool PushCall(R (C::*fn)(A0), typename SelfType<A0>::Type a0, bool wait = false)
{ return PushCommand(ThreadCommandMF1<C,R,A0>(static_cast<C*>(this), fn, 0, a0, wait)); }
template<class C, class R, class A0, class A1>
bool PushCall(R (C::*fn)(A0, A1),
typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1, bool wait = false)
{ return PushCommand(ThreadCommandMF2<C,R,A0,A1>(static_cast<C*>(this), fn, 0, a0, a1, wait)); }
// Enqueue a specified member function call of class C.
// By default the function returns immediately; set 'wait' argument to 'true' to
// wait for completion.
template<class C, class R>
bool PushCall(C* p, R (C::*fn)(), bool wait = false)
{ return PushCommand(ThreadCommandMF0<C,R>(p, fn, 0, wait)); }
template<class C, class R, class A0>
bool PushCall(C* p, R (C::*fn)(A0), typename SelfType<A0>::Type a0, bool wait = false)
{ return PushCommand(ThreadCommandMF1<C,R,A0>(p, fn, 0, a0, wait)); }
template<class C, class R, class A0, class A1>
bool PushCall(C* p, R (C::*fn)(A0, A1),
typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1, bool wait = false)
{ return PushCommand(ThreadCommandMF2<C,R,A0,A1>(p, fn, 0, a0, a1, wait)); }
// *** PushCall with Result
// Enqueue a member function of 'this' class call and wait for call to complete
// on consumer thread before returning.
template<class C, class R>
bool PushCallAndWaitResult(R (C::*fn)(), R* ret)
{ return PushCommand(ThreadCommandMF0<C,R>(static_cast<C*>(this), fn, ret, true)); }
template<class C, class R, class A0>
bool PushCallAndWaitResult(R (C::*fn)(A0), R* ret, typename SelfType<A0>::Type a0)
{ return PushCommand(ThreadCommandMF1<C,R,A0>(static_cast<C*>(this), fn, ret, a0, true)); }
template<class C, class R, class A0, class A1>
bool PushCallAndWaitResult(R (C::*fn)(A0, A1), R* ret,
typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1)
{ return PushCommand(ThreadCommandMF2<C,R,A0,A1>(static_cast<C*>(this), fn, ret, a0, a1, true)); }
// Enqueue a member function call for class C and wait for the call to complete
// on consumer thread before returning.
template<class C, class R>
bool PushCallAndWaitResult(C* p, R (C::*fn)(), R* ret)
{ return PushCommand(ThreadCommandMF0<C,R>(p, fn, ret, true)); }
template<class C, class R, class A0>
bool PushCallAndWaitResult(C* p, R (C::*fn)(A0), R* ret, typename SelfType<A0>::Type a0)
{ return PushCommand(ThreadCommandMF1<C,R,A0>(p, fn, ret, a0, true)); }
template<class C, class R, class A0, class A1>
bool PushCallAndWaitResult(C* p, R (C::*fn)(A0, A1), R* ret,
typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1)
{ return PushCommand(ThreadCommandMF2<C,R,A0,A1>(p, fn, ret, a0, a1, true)); }
private:
class ThreadCommandQueueImpl* pImpl;
};
}
#endif // OVR_ThreadCommandQueue_h

View file

@ -1,146 +0,0 @@
/************************************************************************************
Filename : OVR_Win32_DeviceManager.h
Content : Win32-specific DeviceManager header.
Created : September 21, 2012
Authors : Michael Antonov
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_Win32_DeviceManager_h
#define OVR_Win32_DeviceManager_h
#include "OVR_DeviceImpl.h"
#include "OVR_Win32_DeviceStatus.h"
#include "Kernel/OVR_Timer.h"
namespace OVR { namespace Win32 {
class DeviceManagerThread;
//-------------------------------------------------------------------------------------
// ***** Win32 DeviceManager
class DeviceManager : public DeviceManagerImpl
{
public:
DeviceManager();
~DeviceManager();
// Initialize/Shutdowncreate and shutdown manger thread.
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
virtual ThreadCommandQueue* GetThreadQueue();
virtual ThreadId GetThreadId() const;
virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
// Fills HIDDeviceDesc by using the path.
// Returns 'true' if successful, 'false' otherwise.
bool GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const;
Ptr<DeviceManagerThread> pThread;
};
//-------------------------------------------------------------------------------------
// ***** Device Manager Background Thread
class DeviceManagerThread : public Thread, public ThreadCommandQueue, public DeviceStatus::Notifier
{
friend class DeviceManager;
enum { ThreadStackSize = 32 * 1024 };
public:
DeviceManagerThread(DeviceManager* pdevMgr);
~DeviceManagerThread();
virtual int Run();
// ThreadCommandQueue notifications for CommandEvent handling.
virtual void OnPushNonEmpty_Locked() { ::SetEvent(hCommandEvent); }
virtual void OnPopEmpty_Locked() { ::ResetEvent(hCommandEvent); }
// Notifier used for different updates (EVENT or regular timing or messages).
class Notifier
{
public:
// Called when overlapped I/O handle is signaled.
virtual void OnOverlappedEvent(HANDLE hevent) { OVR_UNUSED1(hevent); }
// Called when timing ticks are updated.
// Returns the largest number of microseconds this function can
// wait till next call.
virtual UInt64 OnTicks(UInt64 ticksMks)
{ OVR_UNUSED1(ticksMks); return Timer::MksPerSecond * 1000; }
enum DeviceMessageType
{
DeviceMessage_DeviceAdded = 0,
DeviceMessage_DeviceRemoved = 1,
};
// Called to notify device object.
virtual bool OnDeviceMessage(DeviceMessageType messageType,
const String& devicePath,
bool* error)
{ OVR_UNUSED3(messageType, devicePath, error); return false; }
};
// Adds device's OVERLAPPED structure for I/O.
// After it's added, Overlapped object will be signaled if a message arrives.
bool AddOverlappedEvent(Notifier* notify, HANDLE hevent);
bool RemoveOverlappedEvent(Notifier* notify, HANDLE hevent);
// Add notifier that will be called at regular intervals.
bool AddTicksNotifier(Notifier* notify);
bool RemoveTicksNotifier(Notifier* notify);
bool AddMessageNotifier(Notifier* notify);
bool RemoveMessageNotifier(Notifier* notify);
// DeviceStatus::Notifier interface.
bool OnMessage(MessageType type, const String& devicePath);
void DetachDeviceManager();
private:
bool threadInitialized() { return hCommandEvent != 0; }
// Event used to wake us up thread commands are enqueued.
HANDLE hCommandEvent;
// Event notifications for devices whose OVERLAPPED I/O we service.
// This list is modified through AddDeviceOverlappedEvent.
// WaitHandles[0] always == hCommandEvent, with null device.
Array<HANDLE> WaitHandles;
Array<Notifier*> WaitNotifiers;
// Ticks notifiers - used for time-dependent events such as keep-alive.
Array<Notifier*> TicksNotifiers;
// Message notifiers.
Array<Notifier*> MessageNotifiers;
// Object that manages notifications originating from Windows messages.
Ptr<DeviceStatus> pStatusObject;
Lock DevMgrLock;
// pDeviceMgr should be accessed under DevMgrLock
DeviceManager* pDeviceMgr; // back ptr, no addref.
};
}} // namespace Win32::OVR
#endif // OVR_Win32_DeviceManager_h

View file

@ -1,101 +0,0 @@
/************************************************************************************
Filename : OVR_Win32_DeviceStatus.h
Content : Win32-specific DeviceStatus header.
Created : January 24, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_Win32_DeviceStatus_h
#define OVR_Win32_DeviceStatus_h
#include <windows.h>
#include "Kernel/OVR_String.h"
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_Array.h"
namespace OVR { namespace Win32 {
//-------------------------------------------------------------------------------------
// ***** DeviceStatus
//
// DeviceStatus abstracts the handling of windows messages of interest for
// example the WM_DEVICECHANGED message which occurs when a device is plugged/unplugged.
// The device manager thread creates an instance of this class and passes its pointer
// in the constructor. That thread is also responsible for periodically calling 'ProcessMessages'
// to process queued windows messages. The client is notified via the 'OnMessage' method
// declared in the 'DeviceMessages::Notifier' interface.
class DeviceStatus : public RefCountBase<DeviceStatus>
{
public:
// Notifier used for device messages.
class Notifier
{
public:
enum MessageType
{
DeviceAdded = 0,
DeviceRemoved = 1,
};
virtual bool OnMessage(MessageType type, const String& devicePath)
{ OVR_UNUSED2(type, devicePath); return true; }
};
DeviceStatus(Notifier* const pClient);
~DeviceStatus();
void operator = (const DeviceStatus&); // No assignment implementation.
bool Initialize();
void ShutDown();
void ProcessMessages();
private:
enum
{
MaxUSBRecoveryAttempts = 20,
USBRecoveryTimeInterval = 500 // ms
};
struct RecoveryTimerDesc
{
UINT_PTR TimerId;
String DevicePath;
unsigned NumAttempts;
};
static LRESULT CALLBACK WindowsMessageCallback( HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
bool MessageCallback(WORD messageType, const String& devicePath);
void CleanupRecoveryTimer(UPInt index);
RecoveryTimerDesc* FindRecoveryTimer(UINT_PTR timerId, UPInt* pindex);
void FindAndCleanupRecoveryTimer(const String& devicePath);
private: // data
Notifier* const pNotificationClient; // Don't reference count a back-pointer.
HWND hMessageWindow;
HDEVNOTIFY hDeviceNotify;
UINT_PTR LastTimerId;
Array<RecoveryTimerDesc> RecoveryTimers;
GUID HidGuid;
};
}} // namespace OVR::Win32
#endif // OVR_Win32_DeviceStatus_h

View file

@ -1,194 +0,0 @@
/************************************************************************************
Filename : OVR_Win32_HIDDevice.h
Content : Win32 HID device implementation.
Created : February 22, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_Win32_HIDDevice_h
#define OVR_Win32_HIDDevice_h
#include "OVR_HIDDevice.h"
#include "OVR_Win32_DeviceManager.h"
#include <windows.h>
#include <setupapi.h>
//-------------------------------------------------------------------------------------
// Define needed "hidsdi.h" functionality to avoid requiring DDK installation.
// #include "hidsdi.h"
#ifndef _HIDSDI_H
#define _HIDSDI_H
#include <pshpack4.h>
#define HIDP_STATUS_SUCCESS (0x11 << 16)
struct HIDP_PREPARSED_DATA;
struct HIDD_ATTRIBUTES
{
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
};
struct HIDP_CAPS
{
USHORT Usage;
USHORT UsagePage;
USHORT InputReportByteLength;
USHORT OutputReportByteLength;
USHORT FeatureReportByteLength;
USHORT Reserved[17];
USHORT NumberLinkCollectionNodes;
USHORT NumberInputButtonCaps;
USHORT NumberInputValueCaps;
USHORT NumberInputDataIndices;
USHORT NumberOutputButtonCaps;
USHORT NumberOutputValueCaps;
USHORT NumberOutputDataIndices;
USHORT NumberFeatureButtonCaps;
USHORT NumberFeatureValueCaps;
USHORT NumberFeatureDataIndices;
};
#include <poppack.h>
#endif
namespace OVR { namespace Win32 {
class HIDDeviceManager;
class DeviceManager;
//-------------------------------------------------------------------------------------
// ***** Win32 HIDDevice
class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier
{
public:
HIDDevice(HIDDeviceManager* manager);
// This is a minimal constructor used during enumeration for us to pass
// a HIDDevice to the visit function (so that it can query feature reports).
HIDDevice(HIDDeviceManager* manager, HANDLE device);
~HIDDevice();
bool HIDInitialize(const String& path);
void HIDShutdown();
// OVR::HIDDevice
bool SetFeatureReport(UByte* data, UInt32 length);
bool GetFeatureReport(UByte* data, UInt32 length);
// DeviceManagerThread::Notifier
void OnOverlappedEvent(HANDLE hevent);
UInt64 OnTicks(UInt64 ticksMks);
bool OnDeviceMessage(DeviceMessageType messageType, const String& devicePath, bool* error);
private:
bool openDevice();
bool initInfo();
bool initializeRead();
bool processReadResult();
void closeDevice();
void closeDeviceOnIOError();
bool inMinimalMode;
HIDDeviceManager* HIDManager;
HANDLE Device;
HIDDeviceDesc DevDesc;
OVERLAPPED ReadOverlapped;
bool ReadRequested;
enum { ReadBufferSize = 96 };
UByte ReadBuffer[ReadBufferSize];
UInt16 InputReportBufferLength;
UInt16 OutputReportBufferLength;
UInt16 FeatureReportBufferLength;
};
//-------------------------------------------------------------------------------------
// ***** Win32 HIDDeviceManager
class HIDDeviceManager : public OVR::HIDDeviceManager
{
friend class HIDDevice;
public:
HIDDeviceManager(DeviceManager* manager);
virtual ~HIDDeviceManager();
virtual bool Initialize();
virtual void Shutdown();
virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor);
virtual OVR::HIDDevice* Open(const String& path);
// Fills HIDDeviceDesc by using the path.
// Returns 'true' if successful, 'false' otherwise.
bool GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const;
GUID GetHIDGuid() { return HidGuid; }
static HIDDeviceManager* CreateInternal(DeviceManager* manager);
private:
DeviceManager* Manager; // Back pointer can just be a raw pointer.
HMODULE hHidLib;
GUID HidGuid;
// Macros to declare and resolve needed functions from library.
#define OVR_DECLARE_HIDFUNC(func, rettype, args) \
typedef rettype (__stdcall *PFn_##func) args; \
PFn_##func func;
#define OVR_RESOLVE_HIDFUNC(func) \
func = (PFn_##func)::GetProcAddress(hHidLib, #func)
OVR_DECLARE_HIDFUNC(HidD_GetHidGuid, void, (GUID *hidGuid));
OVR_DECLARE_HIDFUNC(HidD_SetNumInputBuffers, BOOLEAN, (HANDLE hidDev, ULONG numberBuffers));
OVR_DECLARE_HIDFUNC(HidD_GetFeature, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength));
OVR_DECLARE_HIDFUNC(HidD_SetFeature, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength));
OVR_DECLARE_HIDFUNC(HidD_GetAttributes, BOOLEAN, (HANDLE hidDev, HIDD_ATTRIBUTES *attributes));
OVR_DECLARE_HIDFUNC(HidD_GetManufacturerString, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength));
OVR_DECLARE_HIDFUNC(HidD_GetProductString, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength));
OVR_DECLARE_HIDFUNC(HidD_GetSerialNumberString, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength));
OVR_DECLARE_HIDFUNC(HidD_GetPreparsedData, BOOLEAN, (HANDLE hidDev, HIDP_PREPARSED_DATA **preparsedData));
OVR_DECLARE_HIDFUNC(HidD_FreePreparsedData, BOOLEAN, (HIDP_PREPARSED_DATA *preparsedData));
OVR_DECLARE_HIDFUNC(HidP_GetCaps, NTSTATUS,(HIDP_PREPARSED_DATA *preparsedData, HIDP_CAPS* caps));
HANDLE CreateHIDFile(const char* path, bool exclusiveAccess = true) const
{
return ::CreateFileA(path, GENERIC_WRITE|GENERIC_READ,
(!exclusiveAccess) ? (FILE_SHARE_READ|FILE_SHARE_WRITE) : 0x0,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
}
// Helper functions to fill in HIDDeviceDesc from open device handle.
bool initVendorProductVersion(HANDLE hidDev, HIDDeviceDesc* desc) const;
bool initUsage(HANDLE hidDev, HIDDeviceDesc* desc) const;
void initStrings(HANDLE hidDev, HIDDeviceDesc* desc) const;
bool getFullDesc(HANDLE hidDev, HIDDeviceDesc* desc) const;
};
}} // namespace OVR::Win32
#endif // OVR_Win32_HIDDevice_h

View file

@ -1,157 +0,0 @@
/************************************************************************************
Filename : OVR_Win32_HMDDevice.h
Content : Win32 HMDDevice implementation
Created : September 21, 2012
Authors : Michael Antonov
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_Win32_HMDDevice_h
#define OVR_Win32_HMDDevice_h
#include "OVR_Win32_DeviceManager.h"
#include "OVR_Profile.h"
namespace OVR { namespace Win32 {
class HMDDevice;
//-------------------------------------------------------------------------------------
// HMDDeviceFactory enumerates attached Oculus HMD devices.
//
// This is currently done by matching monitor device strings.
class HMDDeviceFactory : public DeviceFactory
{
public:
static HMDDeviceFactory Instance;
// Enumerates devices, creating and destroying relevant objects in manager.
virtual void EnumerateDevices(EnumerateVisitor& visitor);
protected:
DeviceManager* getManager() const { return (DeviceManager*) pManager; }
};
class HMDDeviceCreateDesc : public DeviceCreateDesc
{
friend class HMDDevice;
protected:
enum
{
Contents_Screen = 1,
Contents_Distortion = 2,
Contents_7Inch = 4,
};
String DeviceId;
String DisplayDeviceName;
int DesktopX, DesktopY;
unsigned Contents;
unsigned HResolution, VResolution;
float HScreenSize, VScreenSize;
float DistortionK[4];
public:
HMDDeviceCreateDesc(DeviceFactory* factory,
const String& deviceId, const String& displayDeviceName);
HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other);
virtual DeviceCreateDesc* Clone() const
{
return new HMDDeviceCreateDesc(*this);
}
virtual DeviceBase* NewDeviceInstance();
virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
DeviceCreateDesc**) const;
// Matches device by path.
virtual bool MatchDevice(const String& path);
virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL);
virtual bool GetDeviceInfo(DeviceInfo* info) const;
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
Profile* GetProfileAddRef() const;
ProfileType GetProfileType() const
{
return (HResolution >= 1920) ? Profile_RiftDKHD : Profile_RiftDK1;
}
void SetScreenParameters(int x, int y, unsigned hres, unsigned vres, float hsize, float vsize)
{
DesktopX = x;
DesktopY = y;
HResolution = hres;
VResolution = vres;
HScreenSize = hsize;
VScreenSize = vsize;
Contents |= Contents_Screen;
}
void SetDistortion(const float* dks)
{
for (int i = 0; i < 4; i++)
DistortionK[i] = dks[i];
Contents |= Contents_Distortion;
}
void Set7Inch() { Contents |= Contents_7Inch; }
bool Is7Inch() const;
};
//-------------------------------------------------------------------------------------
// HMDDevice represents an Oculus HMD device unit. An instance of this class
// is typically created from the DeviceManager.
// After HMD device is created, we its sensor data can be obtained by
// first creating a Sensor object and then wrappig it in SensorFusion.
class HMDDevice : public DeviceImpl<OVR::HMDDevice>
{
public:
HMDDevice(HMDDeviceCreateDesc* createDesc);
~HMDDevice();
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
virtual Profile* GetProfile() const;
virtual const char* GetProfileName() const;
virtual bool SetProfileName(const char* name);
// Query associated sensor.
virtual OVR::SensorDevice* GetSensor();
protected:
HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); }
// User name for the profile used with this device.
String ProfileName;
mutable Ptr<Profile> pCachedProfile;
};
}} // namespace OVR::Win32
#endif // OVR_Win32_HMDDevice_h

View file

@ -1,24 +0,0 @@
/************************************************************************************
Filename : OVR_Win32_SensorDevice.h
Content : Win32 SensorDevice implementation
Created : March 12, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_Win32_SensorDevice_h
#define OVR_Win32_SensorDevice_h
namespace OVR { namespace Win32 {
}} // namespace OVR::Win32
#endif // OVR_Win32_SensorDevice_h

View file

@ -1,160 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : Util_LatencyTest.h
Content : Wraps the lower level LatencyTesterDevice and adds functionality.
Created : February 14, 2013
Authors : Lee Cooper
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_Util_LatencyTest_h
#define OVR_Util_LatencyTest_h
#include "../OVR_Device.h"
#include "../Kernel/OVR_String.h"
#include "../Kernel/OVR_List.h"
namespace OVR { namespace Util {
//-------------------------------------------------------------------------------------
// ***** LatencyTest
//
// LatencyTest utility class wraps the low level LatencyTestDevice and manages the scheduling
// of a latency test. A single test is composed of a series of individual latency measurements
// which are used to derive min, max, and an average latency value.
//
// Developers are required to call the following methods:
// SetDevice - Sets the LatencyTestDevice to be used for the tests.
// ProcessInputs - This should be called at the same place in the code where the game engine
// reads the headset orientation from LibOVR (typically done by calling
// 'GetOrientation' on the SensorFusion object). Calling this at the right time
// enables us to measure the same latency that occurs for headset orientation
// changes.
// DisplayScreenColor - The latency tester works by sensing the color of the pixels directly
// beneath it. The color of these pixels can be set by drawing a small
// quad at the end of the rendering stage. The quad should be small
// such that it doesn't significantly impact the rendering of the scene,
// but large enough to be 'seen' by the sensor. See the SDK
// documentation for more information.
// GetResultsString - Call this to get a string containing the most recent results.
// If the string has already been gotten then NULL will be returned.
// The string pointer will remain valid until the next time this
// method is called.
//
class LatencyTest : public NewOverrideBase
{
public:
LatencyTest(LatencyTestDevice* device = NULL);
~LatencyTest();
// Set the Latency Tester device that we'll use to send commands to and receive
// notification messages from.
bool SetDevice(LatencyTestDevice* device);
// Returns true if this LatencyTestUtil has a Latency Tester device.
bool HasDevice() const
{ return Handler.IsHandlerInstalled(); }
void ProcessInputs();
bool DisplayScreenColor(Color& colorToDisplay);
const char* GetResultsString();
// Begin test. Equivalent to pressing the button on the latency tester.
void BeginTest();
private:
LatencyTest* getThis() { return this; }
enum LatencyTestMessageType
{
LatencyTest_None,
LatencyTest_Timer,
LatencyTest_ProcessInputs,
};
UInt32 getRandomComponent(UInt32 range);
void handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage = LatencyTest_None);
void reset();
void setTimer(UInt32 timeMilliS);
void clearTimer();
class LatencyTestHandler : public MessageHandler
{
LatencyTest* pLatencyTestUtil;
public:
LatencyTestHandler(LatencyTest* latencyTester) : pLatencyTestUtil(latencyTester) { }
~LatencyTestHandler();
virtual void OnMessage(const Message& msg);
};
bool areResultsComplete();
void processResults();
void updateForTimeouts();
Ptr<LatencyTestDevice> Device;
LatencyTestHandler Handler;
enum TesterState
{
State_WaitingForButton,
State_WaitingForSettlePreCalibrationColorBlack,
State_WaitingForSettlePostCalibrationColorBlack,
State_WaitingForSettlePreCalibrationColorWhite,
State_WaitingForSettlePostCalibrationColorWhite,
State_WaitingToTakeMeasurement,
State_WaitingForTestStarted,
State_WaitingForColorDetected,
State_WaitingForSettlePostMeasurement
};
TesterState State;
bool HaveOldTime;
UInt32 OldTime;
UInt32 ActiveTimerMilliS;
Color RenderColor;
struct MeasurementResult : public ListNode<MeasurementResult>, public NewOverrideBase
{
MeasurementResult()
: DeviceMeasuredElapsedMilliS(0),
TimedOutWaitingForTestStarted(false),
TimedOutWaitingForColorDetected(false),
StartTestTicksMicroS(0),
TestStartedTicksMicroS(0)
{}
Color TargetColor;
UInt32 DeviceMeasuredElapsedMilliS;
bool TimedOutWaitingForTestStarted;
bool TimedOutWaitingForColorDetected;
UInt64 StartTestTicksMicroS;
UInt64 TestStartedTicksMicroS;
};
List<MeasurementResult> Results;
void clearMeasurementResults();
MeasurementResult* getActiveResult();
StringBuffer ResultsString;
String ReturnedResultString;
};
}} // namespace OVR::Util
#endif // OVR_Util_LatencyTest_h

View file

@ -1,300 +0,0 @@
/************************************************************************************
PublicHeader: OVR.h
Filename : Util_Render_Stereo.h
Content : Sample stereo rendering configuration classes.
Created : October 22, 2012
Authors : Michael Antonov
Copyright : Copyright 2012 Oculus, Inc. All Rights reserved.
Use of this software is subject to the terms of the Oculus Inc license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
*************************************************************************************/
#ifndef OVR_Util_Render_Stereo_h
#define OVR_Util_Render_Stereo_h
#include "../OVR_Device.h"
namespace OVR { namespace Util { namespace Render {
//-----------------------------------------------------------------------------------
// ***** Stereo Enumerations
// StereoMode describes rendering modes that can be used by StereoConfig.
// These modes control whether stereo rendering is used or not (Stereo_None),
// and how it is implemented.
enum StereoMode
{
Stereo_None = 0,
Stereo_LeftRight_Multipass = 1
};
// StereoEye specifies which eye we are rendering for; it is used to
// retrieve StereoEyeParams.
enum StereoEye
{
StereoEye_Center,
StereoEye_Left,
StereoEye_Right
};
//-----------------------------------------------------------------------------------
// ***** Viewport
// Viewport describes a rectangular area used for rendering, in pixels.
struct Viewport
{
int x, y;
int w, h;
Viewport() {}
Viewport(int x1, int y1, int w1, int h1) : x(x1), y(y1), w(w1), h(h1) { }
bool operator == (const Viewport& vp) const
{ return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); }
bool operator != (const Viewport& vp) const
{ return !operator == (vp); }
};
//-----------------------------------------------------------------------------------
// ***** DistortionConfig
// DistortionConfig Provides controls for the distortion shader.
// - K[0] - K[3] are coefficients for the distortion function.
// - XCenterOffset is the offset of lens distortion center from the
// center of one-eye screen half. [-1, 1] Range.
// - Scale is a factor of how much larger will the input image be,
// with a factor of 1.0f being no scaling. An inverse of this
// value is applied to sampled UV coordinates (1/Scale).
// - ChromaticAberration is an array of parameters for controlling
// additional Red and Blue scaling in order to reduce chromatic aberration
// caused by the Rift lenses.
class DistortionConfig
{
public:
DistortionConfig(float k0 = 1.0f, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
: XCenterOffset(0), YCenterOffset(0), Scale(1.0f)
{
SetCoefficients(k0, k1, k2, k3);
SetChromaticAberration();
}
void SetCoefficients(float k0, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
{ K[0] = k0; K[1] = k1; K[2] = k2; K[3] = k3; }
void SetChromaticAberration(float red1 = 1.0f, float red2 = 0.0f, float blue1 = 1.0f, float blue2 = 0.0f)
{ ChromaticAberration[0] = red1; ChromaticAberration[1] = red2; ChromaticAberration[2] = blue1; ChromaticAberration[3] = blue2; }
// DistortionFn applies distortion equation to the argument. The returned
// value should match distortion equation used in shader.
float DistortionFn(float r) const
{
float rsq = r * r;
float scale = r * (K[0] + K[1] * rsq + K[2] * rsq * rsq + K[3] * rsq * rsq * rsq);
return scale;
}
// DistortionFnInverse computes the inverse of the distortion function on an argument.
float DistortionFnInverse(float r);
float K[4];
float XCenterOffset, YCenterOffset;
float Scale;
float ChromaticAberration[4]; // Additional per-channel scaling is applied after distortion:
// Index [0] - Red channel constant coefficient.
// Index [1] - Red channel r^2 coefficient.
// Index [2] - Blue channel constant coefficient.
// Index [3] - Blue channel r^2 coefficient.
};
//-----------------------------------------------------------------------------------
// ***** StereoEyeParams
// StereoEyeParams describes RenderDevice configuration needed to render
// the scene for one eye.
class StereoEyeParams
{
public:
StereoEye Eye;
Viewport VP; // Viewport that we are rendering to
const DistortionConfig* pDistortion;
Matrix4f ViewAdjust; // Translation to be applied to view matrix.
Matrix4f Projection; // Projection matrix used with this eye.
Matrix4f OrthoProjection; // Orthographic projection used with this eye.
void Init(StereoEye eye, const Viewport &vp, float vofs,
const Matrix4f& proj, const Matrix4f& orthoProj,
const DistortionConfig* distortion = 0)
{
Eye = eye;
VP = vp;
ViewAdjust = Matrix4f::Translation(Vector3f(vofs,0,0));
Projection = proj;
OrthoProjection = orthoProj;
pDistortion = distortion;
}
};
//-----------------------------------------------------------------------------------
// ***** StereoConfig
// StereoConfig maintains a scene stereo state and allow switching between different
// stereo rendering modes. To support rendering, StereoConfig keeps track of HMD
// variables such as screen size, eye-to-screen distance and distortion, and computes
// extra data such as FOV and distortion center offsets based on it. Rendering
// parameters are returned though StereoEyeParams for each eye.
//
// Beyond regular 3D projection, this class supports rendering a 2D orthographic
// surface for UI and text. The 2D surface will be defined as fitting within a 2D
// field of view (85 degrees by default) and used [-1,1] coordinate system with
// square pixels. The (0,0) coordinate corresponds to eye center location
// that is properly adjusted during rendering through SterepRenderParams::Adjust2D.
// Genreally speaking, text outside [-1,1] coordinate range will not be readable.
class StereoConfig
{
public:
StereoConfig(StereoMode mode = Stereo_LeftRight_Multipass,
const Viewport& fullViewport = Viewport(0,0, 1280,800));
// *** Modifiable State Access
// Sets a stereo rendering mode and updates internal cached
// state (matrices, per-eye view) based on it.
void SetStereoMode(StereoMode mode) { Mode = mode; DirtyFlag = true; }
StereoMode GetStereoMode() const { return Mode; }
// Sets HMD parameters; also initializes distortion coefficients.
void SetHMDInfo(const HMDInfo& hmd);
const HMDInfo& GetHMDInfo() const { return HMD; }
// Query physical eye-to-screen distance in meters, which combines screen-to-lens and
// and lens-to-eye pupil distances. Modifying this value adjusts FOV.
float GetEyeToScreenDistance() const { return HMD.EyeToScreenDistance; }
void SetEyeToScreenDistance(float esd) { HMD.EyeToScreenDistance = esd; DirtyFlag = true; }
// Interpupillary distance used for stereo, in meters. Default is 0.064m (64 mm).
void SetIPD(float ipd) { InterpupillaryDistance = ipd; IPDOverride = DirtyFlag = true; }
float GetIPD() const { return InterpupillaryDistance; }
// Set full render target viewport; for HMD this includes both eyes.
void SetFullViewport(const Viewport& vp);
const Viewport& GetFullViewport() const { return FullView; }
// Aspect ratio defaults to ((w/h)*multiplier) computed per eye.
// Aspect multiplier allows adjusting aspect ratio consistently for Stereo/NoStereo.
void SetAspectMultiplier(float m) { AspectMultiplier = m; DirtyFlag = true; }
float GetAspectMultiplier() const { return AspectMultiplier; }
// For the distorted image to fill rendered viewport, input texture render target needs to be
// scaled by DistortionScale before sampling. The scale factor is computed by fitting a point
// on of specified radius from a distortion center, more easily specified as a coordinate.
// SetDistortionFitPointVP sets the (x,y) coordinate of the point that scale will be "fit" to,
// assuming [-1,1] coordinate range for full left-eye viewport. A fit point is a location
// where source (pre-distortion) and target (post-distortion) image match each other.
// For the right eye, the interpretation of 'u' will be inverted.
void SetDistortionFitPointVP(float x, float y);
// SetDistortionFitPointPixels sets the (x,y) coordinate of the point that scale will be "fit" to,
// specified in pixeld for full left-eye texture.
void SetDistortionFitPointPixels(float x, float y);
// Changes all distortion settings.
// Note that setting HMDInfo also changes Distortion coefficients.
void SetDistortionConfig(const DistortionConfig& d) { Distortion = d; DirtyFlag = true; }
// Modify distortion coefficients; useful for adjustment tweaking.
void SetDistortionK(int i, float k) { Distortion.K[i] = k; DirtyFlag = true; }
float GetDistortionK(int i) const { return Distortion.K[i]; }
// Sets the fieldOfView that the 2D coordinate area stretches to.
void Set2DAreaFov(float fovRadians);
// *** Computed State
// Return current aspect ratio.
float GetAspect() { updateIfDirty(); return Aspect; }
// Return computed vertical FOV in radians/degrees.
float GetYFOVRadians() { updateIfDirty(); return YFov; }
float GetYFOVDegrees() { return RadToDegree(GetYFOVRadians()); }
// Query horizontal projection center offset as a distance away from the
// one-eye [-1,1] unit viewport.
// Positive return value should be used for left eye, negative for right eye.
float GetProjectionCenterOffset() { updateIfDirty(); return ProjectionCenterOffset; }
// GetDistortionConfig isn't const because XCenterOffset bay need to be recomputed.
const DistortionConfig& GetDistortionConfig() { updateIfDirty(); return Distortion; }
// Returns DistortionScale factor by which input texture size is increased to make
// post-distortion result distortion fit the viewport.
float GetDistortionScale() { updateIfDirty(); return Distortion.Scale; }
// Returns the size of a pixel within 2D coordinate system.
float Get2DUnitPixel() { updateIfDirty(); return (2.0f / (FovPixels * Distortion.Scale)); }
// Returns full set of Stereo rendering parameters for the specified eye.
const StereoEyeParams& GetEyeRenderParams(StereoEye eye);
private:
void updateIfDirty() { if (DirtyFlag) updateComputedState(); }
void updateComputedState();
void updateDistortionOffsetAndScale();
void updateProjectionOffset();
void update2D();
void updateEyeParams();
// *** Modifiable State
StereoMode Mode;
float InterpupillaryDistance;
float AspectMultiplier; // Multiplied into aspect ratio to change it.
HMDInfo HMD;
DistortionConfig Distortion;
float DistortionFitX, DistortionFitY; // In [-1,1] half-screen viewport units.
Viewport FullView; // Entire window viewport.
float Area2DFov; // FOV range mapping to [-1, 1] 2D area.
// *** Computed State
bool DirtyFlag; // Set when any if the modifiable state changed.
bool IPDOverride; // True after SetIPD was called.
float YFov; // Vertical FOV.
float Aspect; // Aspect ratio: (w/h)*AspectMultiplier.
float ProjectionCenterOffset;
StereoEyeParams EyeRenderParams[2];
// ** 2D Rendering
// Number of 2D pixels in the FOV. This defines [-1,1] coordinate range for 2D.
float FovPixels;
Matrix4f OrthoCenter;
float OrthoPixelOffset;
};
}}} // OVR::Util::Render
#endif

10
interface/external/oculus/readme.txt vendored Normal file
View file

@ -0,0 +1,10 @@
Instructions for adding the Oculus library (LibOVR) to Interface
Stephen Birarda, March 6, 2014
You can download the Oculus SDK from https://developer.oculusvr.com/ (account creation required). Interface has been tested with SDK version 0.2.5.
1. Copy the Oculus SDK folders from the LibOVR directory (Lib, Include, Src) into the interface/externals/oculus folder.
This readme.txt should be there as well.
2. Clear your build directory, run cmake and build, and you should be all set.