From ab6683fdb2805f0f041bda7eccde49be661c5bfa Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 7 Nov 2023 16:29:54 +0100 Subject: foo --- .gitignore | 9 +- .gitmodules | 7 + RSSDK-R2/.gitignore | 1 + eigen | 2 +- libusb | 2 +- libusb-msvc-x86/libusb-1.0.lib | Bin 2118142 -> 2270252 bytes libusb-msvc-x86/libusb-1.0.pdb | Bin 217088 -> 200704 bytes libusb-msvc-x86/libusb.h | 774 +- onnxruntime | 2 +- opencv | 1 + oscpack | 1 + ovr_sdk_win_23.0.0/.msvc/PathHacks.targets | 51 + ovr_sdk_win_23.0.0/.msvc/common.props | 151 + ovr_sdk_win_23.0.0/.ovrsource_root.props | 8 + ovr_sdk_win_23.0.0/3rdParty/TinyXml/tinyxml2.cpp | 2101 +++++ ovr_sdk_win_23.0.0/3rdParty/TinyXml/tinyxml2.h | 1911 +++++ ovr_sdk_win_23.0.0/LICENSE.txt | 3 + .../LibOVR/Include/Extras/OVR_CAPI_Util.h | 283 + .../LibOVR/Include/Extras/OVR_Math.h | 4526 ++++++++++ .../LibOVR/Include/Extras/OVR_StereoProjection.h | 71 + ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI.h | 3715 ++++++++ ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Audio.h | 85 + ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_D3D.h | 203 + ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_GL.h | 137 + ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Keys.h | 49 + ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Vk.h | 285 + ovr_sdk_win_23.0.0/LibOVR/Include/OVR_ErrorCode.h | 330 + ovr_sdk_win_23.0.0/LibOVR/Include/OVR_Version.h | 42 + .../Lib/Windows/Win32/Release/VS2015/LibOVR.lib | Bin 0 -> 516528 bytes .../Lib/Windows/Win32/Release/VS2017/LibOVR.lib | Bin 0 -> 536242 bytes .../Lib/Windows/x64/Release/VS2015/LibOVR.lib | Bin 0 -> 553942 bytes .../Lib/Windows/x64/Release/VS2017/LibOVR.lib | Bin 0 -> 561962 bytes .../LibOVR/Projects/Windows/LibOVR.props | 30 + .../LibOVR/Projects/Windows/VS2015/LibOVR.vcxproj | 456 + .../Projects/Windows/VS2015/LibOVR.vcxproj.filters | 54 + .../LibOVR/Projects/Windows/VS2017/LibOVR.vcxproj | 463 + .../Projects/Windows/VS2017/LibOVR.vcxproj.filters | 57 + ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c | 1961 +++++ .../LibOVR/Shim/OVR_CAPI_Prototypes.h | 171 + ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPI_Util.cpp | 430 + .../LibOVR/Shim/OVR_StereoProjection.cpp | 202 + .../Projects/Windows/VS2015/LibOVRKernel.vcxproj | 1386 +++ .../Windows/VS2015/LibOVRKernel.vcxproj.filters | 292 + .../Projects/Windows/VS2017/LibOVRKernel.vcxproj | 784 ++ .../Windows/VS2017/LibOVRKernel.vcxproj.filters | 279 + .../Windows/VS2017/LibOVRKernel_internal.props | 17 + .../LibOVRKernel/Src/GL/CAPI_GLE.cpp | 8935 ++++++++++++++++++++ ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE.h | 2733 ++++++ .../LibOVRKernel/Src/GL/CAPI_GLE_GL.h | 5776 +++++++++++++ .../LibOVRKernel/Src/Kernel/OVR_Alg.cpp | 53 + .../LibOVRKernel/Src/Kernel/OVR_Alg.h | 1385 +++ .../LibOVRKernel/Src/Kernel/OVR_Allocator.cpp | 3717 ++++++++ .../LibOVRKernel/Src/Kernel/OVR_Allocator.h | 1453 ++++ .../LibOVRKernel/Src/Kernel/OVR_Array.h | 854 ++ .../LibOVRKernel/Src/Kernel/OVR_Atomic.cpp | 67 + .../LibOVRKernel/Src/Kernel/OVR_Atomic.h | 196 + .../LibOVRKernel/Src/Kernel/OVR_Callbacks.cpp | 42 + .../LibOVRKernel/Src/Kernel/OVR_Callbacks.h | 282 + .../Src/Kernel/OVR_CallbacksInternal.h | 338 + .../LibOVRKernel/Src/Kernel/OVR_Color.h | 68 + .../LibOVRKernel/Src/Kernel/OVR_Compiler.h | 1525 ++++ .../Src/Kernel/OVR_ContainerAllocator.h | 244 + .../LibOVRKernel/Src/Kernel/OVR_DLLHelper.h | 87 + .../LibOVRKernel/Src/Kernel/OVR_DebugHelp.cpp | 4036 +++++++++ .../LibOVRKernel/Src/Kernel/OVR_DebugHelp.h | 723 ++ .../LibOVRKernel/Src/Kernel/OVR_Delegates.h | 468 + .../LibOVRKernel/Src/Kernel/OVR_Deque.h | 287 + .../LibOVRKernel/Src/Kernel/OVR_Error.cpp | 886 ++ .../LibOVRKernel/Src/Kernel/OVR_Error.h | 795 ++ .../LibOVRKernel/Src/Kernel/OVR_File.cpp | 521 ++ .../LibOVRKernel/Src/Kernel/OVR_File.h | 695 ++ .../LibOVRKernel/Src/Kernel/OVR_FileFILE.cpp | 575 ++ .../LibOVRKernel/Src/Kernel/OVR_Hash.h | 1261 +++ .../LibOVRKernel/Src/Kernel/OVR_JSON.cpp | 1202 +++ .../LibOVRKernel/Src/Kernel/OVR_JSON.h | 228 + .../LibOVRKernel/Src/Kernel/OVR_KeyCodes.h | 281 + .../LibOVRKernel/Src/Kernel/OVR_List.h | 389 + .../LibOVRKernel/Src/Kernel/OVR_Lockless.h | 202 + .../LibOVRKernel/Src/Kernel/OVR_NewOverride.inl | 207 + .../LibOVRKernel/Src/Kernel/OVR_Nullptr.h | 159 + .../LibOVRKernel/Src/Kernel/OVR_RefCount.cpp | 90 + .../LibOVRKernel/Src/Kernel/OVR_RefCount.h | 495 ++ .../LibOVRKernel/Src/Kernel/OVR_SharedMemory.cpp | 695 ++ .../LibOVRKernel/Src/Kernel/OVR_SharedMemory.h | 229 + .../LibOVRKernel/Src/Kernel/OVR_Std.cpp | 1225 +++ .../LibOVRKernel/Src/Kernel/OVR_Std.h | 523 ++ .../LibOVRKernel/Src/Kernel/OVR_String.cpp | 372 + .../LibOVRKernel/Src/Kernel/OVR_String.h | 597 ++ .../LibOVRKernel/Src/Kernel/OVR_StringHash.h | 91 + .../Src/Kernel/OVR_String_FormatUtil.cpp | 77 + .../Src/Kernel/OVR_String_PathUtil.cpp | 183 + .../LibOVRKernel/Src/Kernel/OVR_SysFile.cpp | 157 + .../LibOVRKernel/Src/Kernel/OVR_SysFile.h | 105 + .../LibOVRKernel/Src/Kernel/OVR_System.cpp | 214 + .../LibOVRKernel/Src/Kernel/OVR_System.h | 181 + .../LibOVRKernel/Src/Kernel/OVR_Threads.h | 217 + .../LibOVRKernel/Src/Kernel/OVR_ThreadsPthread.cpp | 234 + .../LibOVRKernel/Src/Kernel/OVR_ThreadsWinAPI.cpp | 319 + .../LibOVRKernel/Src/Kernel/OVR_Timer.cpp | 453 + .../LibOVRKernel/Src/Kernel/OVR_Timer.h | 143 + .../LibOVRKernel/Src/Kernel/OVR_Types.h | 1167 +++ .../LibOVRKernel/Src/Kernel/OVR_UTF8Util.cpp | 390 + .../LibOVRKernel/Src/Kernel/OVR_UTF8Util.h | 130 + .../Src/Kernel/OVR_Win32_IncludeWindows.h | 209 + .../LibOVRKernel/Src/Kernel/WindowsAFunctions.h | 4887 +++++++++++ .../LibOVRKernel/Src/Tracing/LibOVREvents.h | 3327 ++++++++ .../LibOVRKernel/Src/Tracing/LibOVREvents.man | 523 ++ .../LibOVRKernel/Src/Tracing/LibOVREvents.rc | 3 + .../LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN | Bin 0 -> 38210 bytes .../Src/Tracing/LibOVREvents_MSG00001.bin | Bin 0 -> 2120 bytes .../LibOVRKernel/Src/Tracing/README.md | 55 + .../LibOVRKernel/Src/Tracing/Tracing.h | 437 + .../LibOVRKernel/Src/Tracing/build.cmd | 16 + .../LibOVRKernel/Src/Tracing/clean.cmd | 6 + .../LibOVRKernel/Src/Tracing/install.cmd | 105 + .../LibOVRKernel/Src/Util/Shaders/Blt_ps.hlsl | 8 + .../LibOVRKernel/Src/Util/Shaders/Blt_ps_ms2.hlsl | 14 + .../LibOVRKernel/Src/Util/Shaders/Blt_vs.hlsl | 8 + .../LibOVRKernel/Src/Util/Shaders/GrayBlt_ps.hlsl | 9 + .../LibOVRKernel/Src/Util/Util_D3D11_Blitter.cpp | 687 ++ .../LibOVRKernel/Src/Util/Util_D3D11_Blitter.h | 145 + .../LibOVRKernel/Src/Util/Util_Direct3D.cpp | 94 + .../LibOVRKernel/Src/Util/Util_Direct3D.h | 161 + .../LibOVRKernel/Src/Util/Util_GL_Blitter.cpp | 269 + .../LibOVRKernel/Src/Util/Util_GL_Blitter.h | 70 + .../LibOVRKernel/Src/Util/Util_ImageWindow.cpp | 536 ++ .../LibOVRKernel/Src/Util/Util_ImageWindow.h | 234 + .../LibOVRKernel/Src/Util/Util_LongPollThread.cpp | 86 + .../LibOVRKernel/Src/Util/Util_LongPollThread.h | 76 + .../LibOVRKernel/Src/Util/Util_SystemGUI.cpp | 288 + .../LibOVRKernel/Src/Util/Util_SystemGUI.h | 43 + .../LibOVRKernel/Src/Util/Util_SystemInfo.cpp | 2329 +++++ .../LibOVRKernel/Src/Util/Util_SystemInfo.h | 490 ++ .../LibOVRKernel/Src/Util/Util_Watchdog.cpp | 335 + .../LibOVRKernel/Src/Util/Util_Watchdog.h | 166 + ovr_sdk_win_23.0.0/Logging/Logging/Logging-fwd.h | 58 + .../Logging/Logging/Logging_Library.h | 1262 +++ .../Logging/Logging/Logging_OutputPlugins.h | 105 + ovr_sdk_win_23.0.0/Logging/Logging/Logging_Tools.h | 230 + .../Logging/PCSDK_Logging_dependency.props | 21 + .../Projects/Windows/VS2015/PCSDK_Logging.vcxproj | 170 + .../Windows/VS2015/PCSDK_Logging.vcxproj.filters | 40 + .../Windows/VS2015/PCSDK_Logging_internal.props | 8 + .../Projects/Windows/VS2017/PCSDK_Logging.vcxproj | 171 + .../Windows/VS2017/PCSDK_Logging.vcxproj.filters | 43 + .../Windows/VS2017/PCSDK_Logging_internal.props | 8 + ovr_sdk_win_23.0.0/Logging/src/Logging_Library.cpp | 1537 ++++ .../Logging/src/Logging_OutputPlugins.cpp | 289 + ovr_sdk_win_23.0.0/Logging/src/Logging_Tools.cpp | 255 + ovr_sdk_win_23.0.0/OVRRootPath.props | 32 + ovr_sdk_win_23.0.0/Oculus World Demo.lnk | Bin 0 -> 2351 bytes ovr_sdk_win_23.0.0/THIRD_PARTY_NOTICES.txt | 5712 +++++++++++++ ovr_sdk_win_23.0.0/Windows10SDKPaths.props | 41 + ovr_sdk_win_23.0.0/common.props | 8 + steamvr | 2 +- tobii.streamengine.native.2.2.2.363/.gitignore | 1 + tobii.streamengine.native.2.2.2.363/.gitkeep | 0 tobii.streamengine.native.2.2.2.363/URL.txt | 3 + trackhat-c-library-driver | 2 +- 159 files changed, 95630 insertions(+), 273 deletions(-) create mode 100644 RSSDK-R2/.gitignore mode change 160000 => 120000 onnxruntime create mode 120000 opencv create mode 160000 oscpack create mode 100644 ovr_sdk_win_23.0.0/.msvc/PathHacks.targets create mode 100644 ovr_sdk_win_23.0.0/.msvc/common.props create mode 100644 ovr_sdk_win_23.0.0/.ovrsource_root.props create mode 100644 ovr_sdk_win_23.0.0/3rdParty/TinyXml/tinyxml2.cpp create mode 100644 ovr_sdk_win_23.0.0/3rdParty/TinyXml/tinyxml2.h create mode 100644 ovr_sdk_win_23.0.0/LICENSE.txt create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_CAPI_Util.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_Math.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_StereoProjection.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Audio.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_D3D.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_GL.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Keys.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Vk.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/OVR_ErrorCode.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Include/OVR_Version.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/Win32/Release/VS2015/LibOVR.lib create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/Win32/Release/VS2017/LibOVR.lib create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/x64/Release/VS2015/LibOVR.lib create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/x64/Release/VS2017/LibOVR.lib create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/LibOVR.props create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2015/LibOVR.vcxproj create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2015/LibOVR.vcxproj.filters create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2017/LibOVR.vcxproj create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2017/LibOVR.vcxproj.filters create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPI_Prototypes.h create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPI_Util.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_StereoProjection.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2015/LibOVRKernel.vcxproj create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2015/LibOVRKernel.vcxproj.filters create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel.vcxproj create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel.vcxproj.filters create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel_internal.props create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE_GL.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Alg.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Alg.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Allocator.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Allocator.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Array.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Callbacks.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Callbacks.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_CallbacksInternal.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Color.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Compiler.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ContainerAllocator.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DLLHelper.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DebugHelp.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DebugHelp.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Delegates.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Deque.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Error.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Error.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_File.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_File.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_FileFILE.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Hash.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_JSON.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_JSON.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_KeyCodes.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_List.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Lockless.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_NewOverride.inl create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Nullptr.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_RefCount.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_RefCount.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SharedMemory.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SharedMemory.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Std.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Std.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_StringHash.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String_FormatUtil.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String_PathUtil.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SysFile.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SysFile.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Threads.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ThreadsPthread.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ThreadsWinAPI.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Timer.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Timer.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Types.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_UTF8Util.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_UTF8Util.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Win32_IncludeWindows.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/WindowsAFunctions.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.man create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.rc create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents_MSG00001.bin create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/README.md create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/Tracing.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/build.cmd create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/clean.cmd create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/install.cmd create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_ps.hlsl create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_ps_ms2.hlsl create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_vs.hlsl create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/GrayBlt_ps.hlsl create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_D3D11_Blitter.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_D3D11_Blitter.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Direct3D.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Direct3D.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_GL_Blitter.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_GL_Blitter.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_ImageWindow.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_ImageWindow.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_LongPollThread.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_LongPollThread.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemInfo.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemInfo.h create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Watchdog.cpp create mode 100644 ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Watchdog.h create mode 100644 ovr_sdk_win_23.0.0/Logging/Logging/Logging-fwd.h create mode 100644 ovr_sdk_win_23.0.0/Logging/Logging/Logging_Library.h create mode 100644 ovr_sdk_win_23.0.0/Logging/Logging/Logging_OutputPlugins.h create mode 100644 ovr_sdk_win_23.0.0/Logging/Logging/Logging_Tools.h create mode 100644 ovr_sdk_win_23.0.0/Logging/PCSDK_Logging_dependency.props create mode 100644 ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging.vcxproj create mode 100644 ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging.vcxproj.filters create mode 100644 ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging_internal.props create mode 100644 ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging.vcxproj create mode 100644 ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging.vcxproj.filters create mode 100644 ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging_internal.props create mode 100644 ovr_sdk_win_23.0.0/Logging/src/Logging_Library.cpp create mode 100644 ovr_sdk_win_23.0.0/Logging/src/Logging_OutputPlugins.cpp create mode 100644 ovr_sdk_win_23.0.0/Logging/src/Logging_Tools.cpp create mode 100644 ovr_sdk_win_23.0.0/OVRRootPath.props create mode 100644 ovr_sdk_win_23.0.0/Oculus World Demo.lnk create mode 100644 ovr_sdk_win_23.0.0/THIRD_PARTY_NOTICES.txt create mode 100644 ovr_sdk_win_23.0.0/Windows10SDKPaths.props create mode 100644 ovr_sdk_win_23.0.0/common.props create mode 100644 tobii.streamengine.native.2.2.2.363/.gitignore create mode 100644 tobii.streamengine.native.2.2.2.363/.gitkeep create mode 100644 tobii.streamengine.native.2.2.2.363/URL.txt diff --git a/.gitignore b/.gitignore index cf2db59..5b15689 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ -/opencv/ -/RSSDK-R2/ -/eigen/ -/onnxruntime*/ -/libusb/ +/onnxruntime-?*/ +/*.7z +/*.tar +/opentrack.wiki diff --git a/.gitmodules b/.gitmodules index 6d030bd..ba48bad 100755 --- a/.gitmodules +++ b/.gitmodules @@ -21,3 +21,10 @@ path = trackhat-c-library-driver url = https://github.com/opentrack/trackhat-c-library-driver.git branch = fixes3 +[submodule "oscpack"] + path = oscpack + url = https://github.com/CINPLA/oscpack +[submodule "opencv"] + path = opencv + url = https://github.com/opencv/opencv.git + branch = 4.x diff --git a/RSSDK-R2/.gitignore b/RSSDK-R2/.gitignore new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/RSSDK-R2/.gitignore @@ -0,0 +1 @@ +* diff --git a/eigen b/eigen index c5b896c..6f9ad7d 160000 --- a/eigen +++ b/eigen @@ -1 +1 @@ -Subproject commit c5b896c5a3eb35ed0c08a9be5e6f10cc0a465b81 +Subproject commit 6f9ad7da6122fdb4197c0b43dfec09ec3525305e diff --git a/libusb b/libusb index f3619c4..6bf2db6 160000 --- a/libusb +++ b/libusb @@ -1 +1 @@ -Subproject commit f3619c4078a921c3d6bf3238ff7a8dc70d60e40e +Subproject commit 6bf2db6feaf3b611c9adedb6c4962a07f5cb07ae diff --git a/libusb-msvc-x86/libusb-1.0.lib b/libusb-msvc-x86/libusb-1.0.lib index 1d563b2..e82e107 100644 Binary files a/libusb-msvc-x86/libusb-1.0.lib and b/libusb-msvc-x86/libusb-1.0.lib differ diff --git a/libusb-msvc-x86/libusb-1.0.pdb b/libusb-msvc-x86/libusb-1.0.pdb index 7715376..f75b39f 100644 Binary files a/libusb-msvc-x86/libusb-1.0.pdb and b/libusb-msvc-x86/libusb-1.0.pdb differ diff --git a/libusb-msvc-x86/libusb.h b/libusb-msvc-x86/libusb.h index 8a6b0bf..99cc017 100644 --- a/libusb-msvc-x86/libusb.h +++ b/libusb-msvc-x86/libusb.h @@ -3,7 +3,8 @@ * Copyright © 2001 Johannes Erdfelt * Copyright © 2007-2008 Daniel Drake * Copyright © 2012 Pete Batard - * Copyright © 2012-2018 Nathan Hjelm + * Copyright © 2012-2023 Nathan Hjelm + * Copyright © 2014-2020 Chris Dickens * For more information, please visit: http://libusb.info * * This library is free software; you can redistribute it and/or @@ -24,55 +25,42 @@ #ifndef LIBUSB_H #define LIBUSB_H -#ifdef _MSC_VER +#if defined(_MSC_VER) +#pragma warning(push) +/* Disable: warning C4200: nonstandard extension used : zero-sized array in struct/union */ +#pragma warning(disable:4200) /* on MS environments, the inline keyword is available in C++ only */ #if !defined(__cplusplus) #define inline __inline #endif -/* ssize_t is also not available (copy/paste from MinGW) */ +/* ssize_t is also not available */ #ifndef _SSIZE_T_DEFINED #define _SSIZE_T_DEFINED -#undef ssize_t -#ifdef _WIN64 - typedef __int64 ssize_t; -#else - typedef int ssize_t; -#endif /* _WIN64 */ +#include +typedef SSIZE_T ssize_t; #endif /* _SSIZE_T_DEFINED */ #endif /* _MSC_VER */ -/* stdint.h is not available on older MSVC */ -#if defined(_MSC_VER) && (_MSC_VER < 1600) && (!defined(_STDINT)) && (!defined(_STDINT_H)) -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -#else +#include #include -#endif - -#if !defined(_WIN32_WCE) #include -#endif - -#if defined(__linux__) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__HAIKU__) +#if !defined(_MSC_VER) #include #endif - #include -#include #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) #define ZERO_SIZED_ARRAY /* [] - valid C99 code */ #else #define ZERO_SIZED_ARRAY 0 /* [0] - non-standard, but usually working code */ -#endif +#endif /* __STDC_VERSION__ */ /* 'interface' might be defined as a macro on Windows, so we need to * undefine it so as not to break the current libusb API, because * libusb_config_descriptor has an 'interface' member * As this can be problematic if you include windows.h after libusb.h * in your sources, we force windows.h to be included first. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#if defined(_WIN32) || defined(__CYGWIN__) #include #if defined(interface) #undef interface @@ -80,17 +68,24 @@ typedef unsigned __int32 uint32_t; #if !defined(__CYGWIN__) #include #endif -#endif - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -#define LIBUSB_DEPRECATED_FOR(f) \ - __attribute__((deprecated("Use " #f " instead"))) -#elif __GNUC__ >= 3 -#define LIBUSB_DEPRECATED_FOR(f) __attribute__((deprecated)) +#endif /* _WIN32 || __CYGWIN__ */ + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +#define LIBUSB_DEPRECATED_FOR(f) __attribute__ ((deprecated ("Use " #f " instead"))) +#elif defined(__GNUC__) && (__GNUC__ >= 3) +#define LIBUSB_DEPRECATED_FOR(f) __attribute__ ((deprecated)) +#elif defined(_MSC_VER) +#define LIBUSB_DEPRECATED_FOR(f) __declspec(deprecated("Use " #f " instead")) #else #define LIBUSB_DEPRECATED_FOR(f) #endif /* __GNUC__ */ +#if defined(__GNUC__) +#define LIBUSB_PACKED __attribute__ ((packed)) +#else +#define LIBUSB_PACKED +#endif /* __GNUC__ */ + /** \def LIBUSB_CALL * \ingroup libusb_misc * libusb's Windows calling convention. @@ -123,11 +118,13 @@ typedef unsigned __int32 uint32_t; * return type, before the function name. See internal documentation for * API_EXPORTED. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#if defined(_WIN32) || defined(__CYGWIN__) #define LIBUSB_CALL WINAPI +#define LIBUSB_CALLV WINAPIV #else #define LIBUSB_CALL -#endif +#define LIBUSB_CALLV +#endif /* _WIN32 || __CYGWIN__ */ /** \def LIBUSB_API_VERSION * \ingroup libusb_misc @@ -149,12 +146,12 @@ typedef unsigned __int32 uint32_t; * Internally, LIBUSB_API_VERSION is defined as follows: * (libusb major << 24) | (libusb minor << 16) | (16 bit incremental) */ -#define LIBUSB_API_VERSION 0x01000107 +#define LIBUSB_API_VERSION 0x0100010A /* The following is kept for compatibility, but will be deprecated in the future */ #define LIBUSBX_API_VERSION LIBUSB_API_VERSION -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif @@ -196,35 +193,35 @@ enum libusb_class_code { * this bDeviceClass value indicates that each interface specifies its * own class information and all interfaces operate independently. */ - LIBUSB_CLASS_PER_INTERFACE = 0, + LIBUSB_CLASS_PER_INTERFACE = 0x00, /** Audio class */ - LIBUSB_CLASS_AUDIO = 1, + LIBUSB_CLASS_AUDIO = 0x01, /** Communications class */ - LIBUSB_CLASS_COMM = 2, + LIBUSB_CLASS_COMM = 0x02, /** Human Interface Device class */ - LIBUSB_CLASS_HID = 3, + LIBUSB_CLASS_HID = 0x03, /** Physical */ - LIBUSB_CLASS_PHYSICAL = 5, - - /** Printer class */ - LIBUSB_CLASS_PRINTER = 7, + LIBUSB_CLASS_PHYSICAL = 0x05, /** Image class */ - LIBUSB_CLASS_PTP = 6, /* legacy name from libusb-0.1 usb.h */ - LIBUSB_CLASS_IMAGE = 6, + LIBUSB_CLASS_IMAGE = 0x06, + LIBUSB_CLASS_PTP = 0x06, /* legacy name from libusb-0.1 usb.h */ + + /** Printer class */ + LIBUSB_CLASS_PRINTER = 0x07, /** Mass storage class */ - LIBUSB_CLASS_MASS_STORAGE = 8, + LIBUSB_CLASS_MASS_STORAGE = 0x08, /** Hub class */ - LIBUSB_CLASS_HUB = 9, + LIBUSB_CLASS_HUB = 0x09, /** Data class */ - LIBUSB_CLASS_DATA = 10, + LIBUSB_CLASS_DATA = 0x0a, /** Smart Card */ LIBUSB_CLASS_SMART_CARD = 0x0b, @@ -244,6 +241,9 @@ enum libusb_class_code { /** Wireless class */ LIBUSB_CLASS_WIRELESS = 0xe0, + /** Miscellaneous class */ + LIBUSB_CLASS_MISCELLANEOUS = 0xef, + /** Application class */ LIBUSB_CLASS_APPLICATION = 0xfe, @@ -269,6 +269,10 @@ enum libusb_descriptor_type { /** Endpoint descriptor. See libusb_endpoint_descriptor. */ LIBUSB_DT_ENDPOINT = 0x05, + /** Interface Association Descriptor. + * See libusb_interface_association_descriptor */ + LIBUSB_DT_INTERFACE_ASSOCIATION = 0x0b, + /** BOS descriptor */ LIBUSB_DT_BOS = 0x0f, @@ -309,14 +313,16 @@ enum libusb_descriptor_type { #define LIBUSB_BT_USB_2_0_EXTENSION_SIZE 7 #define LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE 10 #define LIBUSB_BT_CONTAINER_ID_SIZE 20 +#define LIBUSB_BT_PLATFORM_DESCRIPTOR_MIN_SIZE 20 /* We unwrap the BOS => define its max size */ -#define LIBUSB_DT_BOS_MAX_SIZE ((LIBUSB_DT_BOS_SIZE) +\ - (LIBUSB_BT_USB_2_0_EXTENSION_SIZE) +\ - (LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) +\ - (LIBUSB_BT_CONTAINER_ID_SIZE)) +#define LIBUSB_DT_BOS_MAX_SIZE \ + (LIBUSB_DT_BOS_SIZE + \ + LIBUSB_BT_USB_2_0_EXTENSION_SIZE + \ + LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE + \ + LIBUSB_BT_CONTAINER_ID_SIZE) -#define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ #define LIBUSB_ENDPOINT_DIR_MASK 0x80 /** \ingroup libusb_desc @@ -324,34 +330,31 @@ enum libusb_descriptor_type { * \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme. */ enum libusb_endpoint_direction { - /** In: device-to-host */ - LIBUSB_ENDPOINT_IN = 0x80, - /** Out: host-to-device */ - LIBUSB_ENDPOINT_OUT = 0x00 + LIBUSB_ENDPOINT_OUT = 0x00, + + /** In: device-to-host */ + LIBUSB_ENDPOINT_IN = 0x80 }; -#define LIBUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */ +#define LIBUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */ /** \ingroup libusb_desc * Endpoint transfer type. Values for bits 0:1 of the * \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field. */ -enum libusb_transfer_type { +enum libusb_endpoint_transfer_type { /** Control endpoint */ - LIBUSB_TRANSFER_TYPE_CONTROL = 0, + LIBUSB_ENDPOINT_TRANSFER_TYPE_CONTROL = 0x0, /** Isochronous endpoint */ - LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1, + LIBUSB_ENDPOINT_TRANSFER_TYPE_ISOCHRONOUS = 0x1, /** Bulk endpoint */ - LIBUSB_TRANSFER_TYPE_BULK = 2, + LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK = 0x2, /** Interrupt endpoint */ - LIBUSB_TRANSFER_TYPE_INTERRUPT = 3, - - /** Stream endpoint */ - LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4, + LIBUSB_ENDPOINT_TRANSFER_TYPE_INTERRUPT = 0x3 }; /** \ingroup libusb_misc @@ -386,20 +389,20 @@ enum libusb_standard_request { LIBUSB_REQUEST_SET_CONFIGURATION = 0x09, /** Return the selected alternate setting for the specified interface */ - LIBUSB_REQUEST_GET_INTERFACE = 0x0A, + LIBUSB_REQUEST_GET_INTERFACE = 0x0a, /** Select an alternate interface for the specified interface */ - LIBUSB_REQUEST_SET_INTERFACE = 0x0B, + LIBUSB_REQUEST_SET_INTERFACE = 0x0b, /** Set then report an endpoint's synchronization frame */ - LIBUSB_REQUEST_SYNCH_FRAME = 0x0C, + LIBUSB_REQUEST_SYNCH_FRAME = 0x0c, /** Sets both the U1 and U2 Exit Latency */ LIBUSB_REQUEST_SET_SEL = 0x30, /** Delay from the time a host transmits a packet to the time it is * received by the device. */ - LIBUSB_SET_ISOCH_DELAY = 0x31, + LIBUSB_SET_ISOCH_DELAY = 0x31 }; /** \ingroup libusb_misc @@ -435,10 +438,10 @@ enum libusb_request_recipient { LIBUSB_RECIPIENT_ENDPOINT = 0x02, /** Other */ - LIBUSB_RECIPIENT_OTHER = 0x03, + LIBUSB_RECIPIENT_OTHER = 0x03 }; -#define LIBUSB_ISO_SYNC_TYPE_MASK 0x0C +#define LIBUSB_ISO_SYNC_TYPE_MASK 0x0c /** \ingroup libusb_desc * Synchronization type for isochronous endpoints. Values for bits 2:3 of the @@ -447,19 +450,19 @@ enum libusb_request_recipient { */ enum libusb_iso_sync_type { /** No synchronization */ - LIBUSB_ISO_SYNC_TYPE_NONE = 0, + LIBUSB_ISO_SYNC_TYPE_NONE = 0x0, /** Asynchronous */ - LIBUSB_ISO_SYNC_TYPE_ASYNC = 1, + LIBUSB_ISO_SYNC_TYPE_ASYNC = 0x1, /** Adaptive */ - LIBUSB_ISO_SYNC_TYPE_ADAPTIVE = 2, + LIBUSB_ISO_SYNC_TYPE_ADAPTIVE = 0x2, /** Synchronous */ - LIBUSB_ISO_SYNC_TYPE_SYNC = 3 + LIBUSB_ISO_SYNC_TYPE_SYNC = 0x3 }; -#define LIBUSB_ISO_USAGE_TYPE_MASK 0x30 +#define LIBUSB_ISO_USAGE_TYPE_MASK 0x30 /** \ingroup libusb_desc * Usage type for isochronous endpoints. Values for bits 4:5 of the @@ -468,13 +471,71 @@ enum libusb_iso_sync_type { */ enum libusb_iso_usage_type { /** Data endpoint */ - LIBUSB_ISO_USAGE_TYPE_DATA = 0, + LIBUSB_ISO_USAGE_TYPE_DATA = 0x0, /** Feedback endpoint */ - LIBUSB_ISO_USAGE_TYPE_FEEDBACK = 1, + LIBUSB_ISO_USAGE_TYPE_FEEDBACK = 0x1, /** Implicit feedback Data endpoint */ - LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2, + LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 0x2 +}; + +/** \ingroup libusb_desc + * Supported speeds (wSpeedSupported) bitfield. Indicates what + * speeds the device supports. + */ +enum libusb_supported_speed { + /** Low speed operation supported (1.5MBit/s). */ + LIBUSB_LOW_SPEED_OPERATION = (1 << 0), + + /** Full speed operation supported (12MBit/s). */ + LIBUSB_FULL_SPEED_OPERATION = (1 << 1), + + /** High speed operation supported (480MBit/s). */ + LIBUSB_HIGH_SPEED_OPERATION = (1 << 2), + + /** Superspeed operation supported (5000MBit/s). */ + LIBUSB_SUPER_SPEED_OPERATION = (1 << 3) +}; + +/** \ingroup libusb_desc + * Masks for the bits of the + * \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field + * of the USB 2.0 Extension descriptor. + */ +enum libusb_usb_2_0_extension_attributes { + /** Supports Link Power Management (LPM) */ + LIBUSB_BM_LPM_SUPPORT = (1 << 1) +}; + +/** \ingroup libusb_desc + * Masks for the bits of the + * \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field + * field of the SuperSpeed USB Device Capability descriptor. + */ +enum libusb_ss_usb_device_capability_attributes { + /** Supports Latency Tolerance Messages (LTM) */ + LIBUSB_BM_LTM_SUPPORT = (1 << 1) +}; + +/** \ingroup libusb_desc + * USB capability types + */ +enum libusb_bos_type { + /** Wireless USB device capability */ + LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = 0x01, + + /** USB 2.0 extensions */ + LIBUSB_BT_USB_2_0_EXTENSION = 0x02, + + /** SuperSpeed USB device capability */ + LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 0x03, + + /** Container ID type */ + LIBUSB_BT_CONTAINER_ID = 0x04, + + /** Platform descriptor */ + LIBUSB_BT_PLATFORM_DESCRIPTOR = 0x05 }; /** \ingroup libusb_desc @@ -547,17 +608,15 @@ struct libusb_endpoint_descriptor { /** The address of the endpoint described by this descriptor. Bits 0:3 are * the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction, - * see \ref libusb_endpoint_direction. - */ + * see \ref libusb_endpoint_direction. */ uint8_t bEndpointAddress; /** Attributes which apply to the endpoint when it is configured using * the bConfigurationValue. Bits 0:1 determine the transfer type and - * correspond to \ref libusb_transfer_type. Bits 2:3 are only used for - * isochronous endpoints and correspond to \ref libusb_iso_sync_type. + * correspond to \ref libusb_endpoint_transfer_type. Bits 2:3 are only used + * for isochronous endpoints and correspond to \ref libusb_iso_sync_type. * Bits 4:5 are also only used for isochronous endpoints and correspond to - * \ref libusb_iso_usage_type. Bits 6:7 are reserved. - */ + * \ref libusb_iso_usage_type. Bits 6:7 are reserved. */ uint8_t bmAttributes; /** Maximum packet size this endpoint is capable of sending/receiving. */ @@ -581,6 +640,65 @@ struct libusb_endpoint_descriptor { int extra_length; }; +/** \ingroup libusb_desc + * A structure representing the standard USB interface association descriptor. + * This descriptor is documented in section 9.6.4 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_interface_association_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_INTERFACE_ASSOCIATION + * LIBUSB_DT_INTERFACE_ASSOCIATION in this context. */ + uint8_t bDescriptorType; + + /** Interface number of the first interface that is associated + * with this function */ + uint8_t bFirstInterface; + + /** Number of contiguous interfaces that are associated with + * this function */ + uint8_t bInterfaceCount; + + /** USB-IF class code for this function. + * A value of zero is not allowed in this descriptor. + * If this field is 0xff, the function class is vendor-specific. + * All other values are reserved for assignment by the USB-IF. + */ + uint8_t bFunctionClass; + + /** USB-IF subclass code for this function. + * If this field is not set to 0xff, all values are reserved + * for assignment by the USB-IF + */ + uint8_t bFunctionSubClass; + + /** USB-IF protocol code for this function. + * These codes are qualified by the values of the bFunctionClass + * and bFunctionSubClass fields. + */ + uint8_t bFunctionProtocol; + + /** Index of string descriptor describing this function */ + uint8_t iFunction; +}; + +/** \ingroup libusb_desc + * Structure containing an array of 0 or more interface association + * descriptors + */ +struct libusb_interface_association_descriptor_array { + /** Array of interface association descriptors. The size of this array + * is determined by the length field. + */ + const struct libusb_interface_association_descriptor *iad; + + /** Number of interface association descriptors contained. Read-only. */ + int length; +}; + /** \ingroup libusb_desc * A structure representing the standard USB interface descriptor. This * descriptor is documented in section 9.6.5 of the USB 3.0 specification. @@ -698,7 +816,6 @@ struct libusb_config_descriptor { * host-endian format. */ struct libusb_ss_endpoint_companion_descriptor { - /** Size of this descriptor (in bytes) */ uint8_t bLength; @@ -707,19 +824,18 @@ struct libusb_ss_endpoint_companion_descriptor { * this context. */ uint8_t bDescriptorType; - /** The maximum number of packets the endpoint can send or * receive as part of a burst. */ uint8_t bMaxBurst; - /** In bulk EP: bits 4:0 represents the maximum number of - * streams the EP supports. In isochronous EP: bits 1:0 - * represents the Mult - a zero based value that determines - * the maximum number of packets within a service interval */ + /** In bulk EP: bits 4:0 represents the maximum number of + * streams the EP supports. In isochronous EP: bits 1:0 + * represents the Mult - a zero based value that determines + * the maximum number of packets within a service interval */ uint8_t bmAttributes; - /** The total number of bytes this EP will transfer every - * service interval. valid only for periodic EPs. */ + /** The total number of bytes this EP will transfer every + * service interval. Valid only for periodic EPs. */ uint16_t wBytesPerInterval; }; @@ -730,15 +846,18 @@ struct libusb_ss_endpoint_companion_descriptor { */ struct libusb_bos_dev_capability_descriptor { /** Size of this descriptor (in bytes) */ - uint8_t bLength; + uint8_t bLength; + /** Descriptor type. Will have value * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ - uint8_t bDescriptorType; + uint8_t bDescriptorType; + /** Device Capability type */ - uint8_t bDevCapabilityType; + uint8_t bDevCapabilityType; + /** Device Capability data (bLength - 3 bytes) */ - uint8_t dev_capability_data[ZERO_SIZED_ARRAY]; + uint8_t dev_capability_data[ZERO_SIZED_ARRAY]; }; /** \ingroup libusb_desc @@ -789,7 +908,7 @@ struct libusb_usb_2_0_extension_descriptor { * A value of one in a bit location indicates a feature is * supported; a value of zero indicates it is not supported. * See \ref libusb_usb_2_0_extension_attributes. */ - uint32_t bmAttributes; + uint32_t bmAttributes; }; /** \ingroup libusb_desc @@ -854,14 +973,45 @@ struct libusb_container_id_descriptor { uint8_t bDevCapabilityType; /** Reserved field */ - uint8_t bReserved; + uint8_t bReserved; /** 128 bit UUID */ uint8_t ContainerID[16]; }; +/** \ingroup libusb_desc + * A structure representing a Platform descriptor. + * This descriptor is documented in section 9.6.2.4 of the USB 3.2 specification. + */ +struct libusb_platform_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_PLATFORM_DESCRIPTOR + * LIBUSB_BT_CONTAINER_ID in this context. */ + uint8_t bDevCapabilityType; + + /** Reserved field */ + uint8_t bReserved; + + /** 128 bit UUID */ + uint8_t PlatformCapabilityUUID[16]; + + /** Capability data (bLength - 20) */ + uint8_t CapabilityData[ZERO_SIZED_ARRAY]; +}; + /** \ingroup libusb_asyncio * Setup packet for control transfers. */ +#if defined(_MSC_VER) || defined(__WATCOMC__) +#pragma pack(push, 1) +#endif struct libusb_control_setup { /** Request type. Bits 0:4 determine recipient, see * \ref libusb_request_recipient. Bits 5:6 determine type, see @@ -886,7 +1036,10 @@ struct libusb_control_setup { /** Number of bytes to transfer */ uint16_t wLength; -}; +} LIBUSB_PACKED; +#if defined(_MSC_VER) || defined(__WATCOMC__) +#pragma pack(pop) +#endif #define LIBUSB_CONTROL_SETUP_SIZE (sizeof(struct libusb_control_setup)) @@ -916,7 +1069,7 @@ struct libusb_version { const char *rc; /** For ABI compatibility only. */ - const char* describe; + const char *describe; }; /** \ingroup libusb_lib @@ -931,8 +1084,9 @@ struct libusb_version { * Sessions are created by libusb_init() and destroyed through libusb_exit(). * If your application is guaranteed to only ever include a single libusb * user (i.e. you), you do not have to worry about contexts: pass NULL in - * every function call where a context is required. The default context - * will be used. + * every function call where a context is required, and the default context + * will be used. Note that libusb_set_option(NULL, ...) is special, and adds + * an option to a list of default options for new contexts. * * For more information, see \ref libusb_contexts. */ @@ -941,7 +1095,7 @@ typedef struct libusb_context libusb_context; /** \ingroup libusb_dev * Structure representing a USB device detected on the system. This is an * opaque type for which you are only ever provided with a pointer, usually - * originating from libusb_get_device_list(). + * originating from libusb_get_device_list() or libusb_hotplug_register_callback(). * * Certain operations can be performed on a device, but in order to do any * I/O you will have to first obtain a device handle using libusb_open(). @@ -986,62 +1140,7 @@ enum libusb_speed { LIBUSB_SPEED_SUPER = 4, /** The device is operating at super speed plus (10000MBit/s). */ - LIBUSB_SPEED_SUPER_PLUS = 5, -}; - -/** \ingroup libusb_dev - * Supported speeds (wSpeedSupported) bitfield. Indicates what - * speeds the device supports. - */ -enum libusb_supported_speed { - /** Low speed operation supported (1.5MBit/s). */ - LIBUSB_LOW_SPEED_OPERATION = 1, - - /** Full speed operation supported (12MBit/s). */ - LIBUSB_FULL_SPEED_OPERATION = 2, - - /** High speed operation supported (480MBit/s). */ - LIBUSB_HIGH_SPEED_OPERATION = 4, - - /** Superspeed operation supported (5000MBit/s). */ - LIBUSB_SUPER_SPEED_OPERATION = 8, -}; - -/** \ingroup libusb_dev - * Masks for the bits of the - * \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field - * of the USB 2.0 Extension descriptor. - */ -enum libusb_usb_2_0_extension_attributes { - /** Supports Link Power Management (LPM) */ - LIBUSB_BM_LPM_SUPPORT = 2, -}; - -/** \ingroup libusb_dev - * Masks for the bits of the - * \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field - * field of the SuperSpeed USB Device Capability descriptor. - */ -enum libusb_ss_usb_device_capability_attributes { - /** Supports Latency Tolerance Messages (LTM) */ - LIBUSB_BM_LTM_SUPPORT = 2, -}; - -/** \ingroup libusb_dev - * USB capability types - */ -enum libusb_bos_type { - /** Wireless USB device capability */ - LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = 1, - - /** USB 2.0 extensions */ - LIBUSB_BT_USB_2_0_EXTENSION = 2, - - /** SuperSpeed USB device capability */ - LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 3, - - /** Container ID type */ - LIBUSB_BT_CONTAINER_ID = 4, + LIBUSB_SPEED_SUPER_PLUS = 5 }; /** \ingroup libusb_misc @@ -1095,12 +1194,31 @@ enum libusb_error { message strings in strerror.c when adding new error codes here. */ /** Other error */ - LIBUSB_ERROR_OTHER = -99, + LIBUSB_ERROR_OTHER = -99 }; /* Total number of error codes in enum libusb_error */ #define LIBUSB_ERROR_COUNT 14 +/** \ingroup libusb_asyncio + * Transfer type */ +enum libusb_transfer_type { + /** Control transfer */ + LIBUSB_TRANSFER_TYPE_CONTROL = 0U, + + /** Isochronous transfer */ + LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1U, + + /** Bulk transfer */ + LIBUSB_TRANSFER_TYPE_BULK = 2U, + + /** Interrupt transfer */ + LIBUSB_TRANSFER_TYPE_INTERRUPT = 3U, + + /** Bulk stream transfer */ + LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4U +}; + /** \ingroup libusb_asyncio * Transfer status codes */ enum libusb_transfer_status { @@ -1125,7 +1243,7 @@ enum libusb_transfer_status { LIBUSB_TRANSFER_NO_DEVICE, /** Device sent more data than requested */ - LIBUSB_TRANSFER_OVERFLOW, + LIBUSB_TRANSFER_OVERFLOW /* NB! Remember to update libusb_error_name() when adding new status codes here. */ @@ -1135,19 +1253,19 @@ enum libusb_transfer_status { * libusb_transfer.flags values */ enum libusb_transfer_flags { /** Report short frames as errors */ - LIBUSB_TRANSFER_SHORT_NOT_OK = 1U << 0, + LIBUSB_TRANSFER_SHORT_NOT_OK = (1U << 0), /** Automatically free() transfer buffer during libusb_free_transfer(). * Note that buffers allocated with libusb_dev_mem_alloc() should not * be attempted freed in this way, since free() is not an appropriate * way to release such memory. */ - LIBUSB_TRANSFER_FREE_BUFFER = 1U << 1, + LIBUSB_TRANSFER_FREE_BUFFER = (1U << 1), /** Automatically call libusb_free_transfer() after callback returns. * If this flag is set, it is illegal to call libusb_free_transfer() * from your transfer callback, as this will result in a double-free * when this flag is acted upon. */ - LIBUSB_TRANSFER_FREE_TRANSFER = 1U << 2, + LIBUSB_TRANSFER_FREE_TRANSFER = (1U << 2), /** Terminate transfers that are a multiple of the endpoint's * wMaxPacketSize with an extra zero length packet. This is useful @@ -1168,11 +1286,12 @@ enum libusb_transfer_flags { * * This flag is currently only supported on Linux. * On other systems, libusb_submit_transfer() will return - * LIBUSB_ERROR_NOT_SUPPORTED for every transfer where this flag is set. + * \ref LIBUSB_ERROR_NOT_SUPPORTED for every transfer where this + * flag is set. * * Available since libusb-1.0.9. */ - LIBUSB_TRANSFER_ADD_ZERO_PACKET = 1U << 3, + LIBUSB_TRANSFER_ADD_ZERO_PACKET = (1U << 3) }; /** \ingroup libusb_asyncio @@ -1217,7 +1336,7 @@ struct libusb_transfer { /** Address of the endpoint where this transfer will be sent. */ unsigned char endpoint; - /** Type of the endpoint from \ref libusb_transfer_type */ + /** Type of the transfer from \ref libusb_transfer_type */ unsigned char type; /** Timeout for this transfer in milliseconds. A value of 0 indicates no @@ -1245,7 +1364,16 @@ struct libusb_transfer { * fails, or is cancelled. */ libusb_transfer_cb_fn callback; - /** User context data to pass to the callback function. */ + /** User context data. Useful for associating specific data to a transfer + * that can be accessed from within the callback function. + * + * This field may be set manually or is taken as the `user_data` parameter + * of the following functions: + * - libusb_fill_bulk_transfer() + * - libusb_fill_bulk_stream_transfer() + * - libusb_fill_control_transfer() + * - libusb_fill_interrupt_transfer() + * - libusb_fill_iso_transfer() */ void *user_data; /** Data buffer */ @@ -1266,46 +1394,158 @@ struct libusb_transfer { */ enum libusb_capability { /** The libusb_has_capability() API is available. */ - LIBUSB_CAP_HAS_CAPABILITY = 0x0000, + LIBUSB_CAP_HAS_CAPABILITY = 0x0000U, + /** Hotplug support is available on this platform. */ - LIBUSB_CAP_HAS_HOTPLUG = 0x0001, + LIBUSB_CAP_HAS_HOTPLUG = 0x0001U, + /** The library can access HID devices without requiring user intervention. * Note that before being able to actually access an HID device, you may * still have to call additional libusb functions such as * \ref libusb_detach_kernel_driver(). */ - LIBUSB_CAP_HAS_HID_ACCESS = 0x0100, - /** The library supports detaching of the default USB driver, using + LIBUSB_CAP_HAS_HID_ACCESS = 0x0100U, + + /** The library supports detaching of the default USB driver, using * \ref libusb_detach_kernel_driver(), if one is set by the OS kernel */ - LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101 + LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101U }; /** \ingroup libusb_lib * Log message levels. - * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) - * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr - * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr - * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stderr - * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr */ enum libusb_log_level { + /** (0) : No messages ever emitted by the library (default) */ LIBUSB_LOG_LEVEL_NONE = 0, + + /** (1) : Error messages are emitted */ LIBUSB_LOG_LEVEL_ERROR = 1, + + /** (2) : Warning and error messages are emitted */ LIBUSB_LOG_LEVEL_WARNING = 2, + + /** (3) : Informational, warning and error messages are emitted */ LIBUSB_LOG_LEVEL_INFO = 3, - LIBUSB_LOG_LEVEL_DEBUG = 4, + + /** (4) : All messages are emitted */ + LIBUSB_LOG_LEVEL_DEBUG = 4 }; /** \ingroup libusb_lib * Log callback mode. + * + * Since version 1.0.23, \ref LIBUSB_API_VERSION >= 0x01000107 + * * \see libusb_set_log_cb() */ enum libusb_log_cb_mode { + /** Callback function handling all log messages. */ + LIBUSB_LOG_CB_GLOBAL = (1 << 0), + + /** Callback function handling context related log messages. */ + LIBUSB_LOG_CB_CONTEXT = (1 << 1) +}; + +/** \ingroup libusb_lib + * Available option values for libusb_set_option() and libusb_init_context(). + */ +enum libusb_option { + /** Set the log message verbosity. + * + * The default level is LIBUSB_LOG_LEVEL_NONE, which means no messages are ever + * printed. If you choose to increase the message verbosity level, ensure + * that your application does not close the stderr file descriptor. + * + * You are advised to use level LIBUSB_LOG_LEVEL_WARNING. libusb is conservative + * with its message logging and most of the time, will only log messages that + * explain error conditions and other oddities. This will help you debug + * your software. + * + * If the LIBUSB_DEBUG environment variable was set when libusb was + * initialized, this function does nothing: the message verbosity is fixed + * to the value in the environment variable. + * + * If libusb was compiled without any message logging, this function does + * nothing: you'll never get any messages. + * + * If libusb was compiled with verbose debug message logging, this function + * does nothing: you'll always get messages from all levels. + */ + LIBUSB_OPTION_LOG_LEVEL = 0, + + /** Use the UsbDk backend for a specific context, if available. + * + * This option should be set immediately after calling libusb_init(), or set at + * initialization with libusb_init_context() otherwise unspecified behavior + * may occur. + * + * Only valid on Windows. Ignored on all other platforms. + */ + LIBUSB_OPTION_USE_USBDK = 1, + + /** Do not scan for devices + * + * With this option set, libusb will skip scanning devices in + * libusb_init_context(). + * + * Hotplug functionality will also be deactivated. + * + * The option is useful in combination with libusb_wrap_sys_device(), + * which can access a device directly without prior device scanning. + * + * This is typically needed on Android, where access to USB devices + * is limited. + * + * Only valid on Linux. Ignored on all other platforms. + */ + LIBUSB_OPTION_NO_DEVICE_DISCOVERY = 2, - /** Callback function handling all log mesages. */ - LIBUSB_LOG_CB_GLOBAL = 1 << 0, +#define LIBUSB_OPTION_WEAK_AUTHORITY LIBUSB_OPTION_NO_DEVICE_DISCOVERY - /** Callback function handling context related log mesages. */ - LIBUSB_LOG_CB_CONTEXT = 1 << 1 + /** Enable or disable WinUSB RAW_IO mode on an endpoint + * + * Requires four additional arguments of: + * + * libusb_device_handle *dev_handle + * unsigned int endpoint_address + * unsigned int enable + * unsigned int *max_transfer_size_ptr + * + * The dev_handle and endpoint_address parameters must identify a valid + * IN endpoint on an open device. If enable is nonzero, RAW_IO is + * enabled, otherwise it is disabled. Unless max_transfer_size_ptr is + * NULL, then on a successful call to enable RAW_IO, it will be written + * with the MAXIMUM_TRANSFER_SIZE value for the endpoint. + * + * Whilst RAW_IO is enabled for an endpoint, all transfers on that endpoint + * must meet the following two requirements: + * + * * The buffer length must be a multiple of the maximum endpoint packet size. + * + * * The length must be less than or equal to the MAXIMUM_TRANSFER_SIZE value. + * + * This option should not be changed when any transfer is in progress on the + * specified endpoint. + * + * This option only affects the WinUSB backend. On other backends it is ignored + * and returns LIBUSB_OPTION_NOT_SUPPORTED, without modifying the value pointed + * to by max_transfer_size_ptr. + * + * Since version 1.0.27, \ref LIBUSB_API_VERSION >= 0x0100010A + */ + LIBUSB_OPTION_WINUSB_RAW_IO = 3, + + /** Set the context log callback functon. + * + * Set the log callback function either on a context or globally. This + * option must be provided an argument of type libusb_log_cb. Using this + * option with a NULL context is equivalent to calling libusb_set_log_cb + * with mode LIBUSB_LOG_CB_GLOBAL. Using it with a non-NULL context is + * equivalent to calling libusb_set_log_cb with mode + * LIBUSB_LOG_CB_CONTEXT. + */ + LIBUSB_OPTION_LOG_CB = 4, + + LIBUSB_OPTION_MAX = 5 }; /** \ingroup libusb_lib @@ -1314,21 +1554,39 @@ enum libusb_log_cb_mode { * is a global log message * \param level the log level, see \ref libusb_log_level for a description * \param str the log message + * + * Since version 1.0.23, \ref LIBUSB_API_VERSION >= 0x01000107 + * * \see libusb_set_log_cb() */ typedef void (LIBUSB_CALL *libusb_log_cb)(libusb_context *ctx, enum libusb_log_level level, const char *str); +/** \ingroup libusb_lib + * Structure used for setting options through \ref libusb_init_context. + * + */ +struct libusb_init_option { + /** Which option to set */ + enum libusb_option option; + /** An integer value used by the option (if applicable). */ + union { + int64_t ival; + libusb_log_cb log_cbval; + } value; +}; + int LIBUSB_CALL libusb_init(libusb_context **ctx); +int LIBUSB_CALL libusb_init_context(libusb_context **ctx, const struct libusb_init_option options[], int num_options); void LIBUSB_CALL libusb_exit(libusb_context *ctx); -LIBUSB_DEPRECATED_FOR(libusb_set_option) void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level); +/* may be deprecated in the future in favor of lubusb_init_context()+libusb_set_option() */ void LIBUSB_CALL libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb, int mode); const struct libusb_version * LIBUSB_CALL libusb_get_version(void); int LIBUSB_CALL libusb_has_capability(uint32_t capability); const char * LIBUSB_CALL libusb_error_name(int errcode); int LIBUSB_CALL libusb_setlocale(const char *locale); -const char * LIBUSB_CALL libusb_strerror(enum libusb_error errcode); +const char * LIBUSB_CALL libusb_strerror(int errcode); ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, libusb_device ***list); @@ -1350,7 +1608,7 @@ int LIBUSB_CALL libusb_get_config_descriptor_by_value(libusb_device *dev, void LIBUSB_CALL libusb_free_config_descriptor( struct libusb_config_descriptor *config); int LIBUSB_CALL libusb_get_ss_endpoint_companion_descriptor( - struct libusb_context *ctx, + libusb_context *ctx, const struct libusb_endpoint_descriptor *endpoint, struct libusb_ss_endpoint_companion_descriptor **ep_comp); void LIBUSB_CALL libusb_free_ss_endpoint_companion_descriptor( @@ -1359,27 +1617,32 @@ int LIBUSB_CALL libusb_get_bos_descriptor(libusb_device_handle *dev_handle, struct libusb_bos_descriptor **bos); void LIBUSB_CALL libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos); int LIBUSB_CALL libusb_get_usb_2_0_extension_descriptor( - struct libusb_context *ctx, + libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension); void LIBUSB_CALL libusb_free_usb_2_0_extension_descriptor( struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension); int LIBUSB_CALL libusb_get_ss_usb_device_capability_descriptor( - struct libusb_context *ctx, + libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap); void LIBUSB_CALL libusb_free_ss_usb_device_capability_descriptor( struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap); -int LIBUSB_CALL libusb_get_container_id_descriptor(struct libusb_context *ctx, +int LIBUSB_CALL libusb_get_container_id_descriptor(libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_container_id_descriptor **container_id); void LIBUSB_CALL libusb_free_container_id_descriptor( struct libusb_container_id_descriptor *container_id); +int LIBUSB_CALL libusb_get_platform_descriptor(libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_platform_descriptor **platform_descriptor); +void LIBUSB_CALL libusb_free_platform_descriptor( + struct libusb_platform_descriptor *platform_descriptor); uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev); uint8_t LIBUSB_CALL libusb_get_port_number(libusb_device *dev); -int LIBUSB_CALL libusb_get_port_numbers(libusb_device *dev, uint8_t* port_numbers, int port_numbers_len); +int LIBUSB_CALL libusb_get_port_numbers(libusb_device *dev, uint8_t *port_numbers, int port_numbers_len); LIBUSB_DEPRECATED_FOR(libusb_get_port_numbers) -int LIBUSB_CALL libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t* path, uint8_t path_length); +int LIBUSB_CALL libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t *path, uint8_t path_length); libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev); uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev); int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev); @@ -1387,6 +1650,15 @@ int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint); int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev, unsigned char endpoint); +int LIBUSB_CALL libusb_get_max_alt_packet_size(libusb_device *dev, + int interface_number, int alternate_setting, unsigned char endpoint); + +int LIBUSB_CALL libusb_get_interface_association_descriptors(libusb_device *dev, + uint8_t config_index, struct libusb_interface_association_descriptor_array **iad_array); +int LIBUSB_CALL libusb_get_active_interface_association_descriptors(libusb_device *dev, + struct libusb_interface_association_descriptor_array **iad_array); +void LIBUSB_CALL libusb_free_interface_association_descriptors( + struct libusb_interface_association_descriptor_array *iad_array); int LIBUSB_CALL libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev, libusb_device_handle **dev_handle); int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **dev_handle); @@ -1463,7 +1735,7 @@ static inline unsigned char *libusb_control_transfer_get_data( static inline struct libusb_control_setup *libusb_control_transfer_get_setup( struct libusb_transfer *transfer) { - return (struct libusb_control_setup *)(void *) transfer->buffer; + return (struct libusb_control_setup *)(void *)transfer->buffer; } /** \ingroup libusb_asyncio @@ -1493,7 +1765,7 @@ static inline void libusb_fill_control_setup(unsigned char *buffer, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) { - struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *)buffer; setup->bmRequestType = bmRequestType; setup->bRequest = bRequest; setup->wValue = libusb_cpu_to_le16(wValue); @@ -1543,7 +1815,7 @@ static inline void libusb_fill_control_transfer( unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) { - struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *)buffer; transfer->dev_handle = dev_handle; transfer->endpoint = 0; transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; @@ -1682,6 +1954,7 @@ static inline void libusb_set_iso_packet_lengths( struct libusb_transfer *transfer, unsigned int length) { int i; + for (i = 0; i < transfer->num_iso_packets; i++) transfer->iso_packet_desc[i].length = length; } @@ -1896,7 +2169,7 @@ void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx, * Callbacks handles are generated by libusb_hotplug_register_callback() * and can be used to deregister callbacks. Callback handles are unique * per libusb_context and it is safe to call libusb_hotplug_deregister_callback() - * on an already deregisted callback. + * on an already deregistered callback. * * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 * @@ -1908,29 +2181,30 @@ typedef int libusb_hotplug_callback_handle; * * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 * - * Flags for hotplug events */ + * Hotplug events */ typedef enum { - /** Default value when not using any flags. */ - LIBUSB_HOTPLUG_NO_FLAGS = 0U, + /** A device has been plugged in and is ready to use */ + LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED = (1 << 0), - /** Arm the callback and fire it for all matching currently attached devices. */ - LIBUSB_HOTPLUG_ENUMERATE = 1U << 0, -} libusb_hotplug_flag; + /** A device has left and is no longer available. + * It is the user's responsibility to call libusb_close on any handle associated with a disconnected device. + * It is safe to call libusb_get_device_descriptor on a device that has left */ + LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = (1 << 1) +} libusb_hotplug_event; /** \ingroup libusb_hotplug * * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 * - * Hotplug events */ + * Hotplug flags */ typedef enum { - /** A device has been plugged in and is ready to use */ - LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED = 0x01U, + /** Arm the callback and fire it for all matching currently attached devices. */ + LIBUSB_HOTPLUG_ENUMERATE = (1 << 0) +} libusb_hotplug_flag; - /** A device has left and is no longer available. - * It is the user's responsibility to call libusb_close on any handle associated with a disconnected device. - * It is safe to call libusb_get_device_descriptor on a device that has left */ - LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = 0x02U, -} libusb_hotplug_event; +/** \ingroup libusb_hotplug + * Convenience macro when not using any flags */ +#define LIBUSB_HOTPLUG_NO_FLAGS 0 /** \ingroup libusb_hotplug * Wildcard matching for hotplug events */ @@ -1959,9 +2233,7 @@ typedef enum { * returning 1 will cause this callback to be deregistered */ typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx, - libusb_device *device, - libusb_hotplug_event event, - void *user_data); + libusb_device *device, libusb_hotplug_event event, void *user_data); /** \ingroup libusb_hotplug * Register a hotplug callback function @@ -1986,25 +2258,23 @@ typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx, * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 * * \param[in] ctx context to register this callback with - * \param[in] events bitwise or of events that will trigger this callback. See \ref - * libusb_hotplug_event - * \param[in] flags hotplug callback flags. See \ref libusb_hotplug_flag + * \param[in] events bitwise or of hotplug events that will trigger this callback. + * See \ref libusb_hotplug_event + * \param[in] flags bitwise or of hotplug flags that affect registration. + * See \ref libusb_hotplug_flag * \param[in] vendor_id the vendor id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY * \param[in] product_id the product id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY * \param[in] dev_class the device class to match or \ref LIBUSB_HOTPLUG_MATCH_ANY * \param[in] cb_fn the function to be invoked on a matching event/device * \param[in] user_data user data to pass to the callback function * \param[out] callback_handle pointer to store the handle of the allocated callback (can be NULL) - * \returns LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure + * \returns \ref LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure */ int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx, - libusb_hotplug_event events, - libusb_hotplug_flag flags, - int vendor_id, int product_id, - int dev_class, - libusb_hotplug_callback_fn cb_fn, - void *user_data, - libusb_hotplug_callback_handle *callback_handle); + int events, int flags, + int vendor_id, int product_id, int dev_class, + libusb_hotplug_callback_fn cb_fn, void *user_data, + libusb_hotplug_callback_handle *callback_handle); /** \ingroup libusb_hotplug * Deregisters a hotplug callback. @@ -2018,48 +2288,26 @@ int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx, * \param[in] callback_handle the handle of the callback to deregister */ void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx, - libusb_hotplug_callback_handle callback_handle); + libusb_hotplug_callback_handle callback_handle); -/** \ingroup libusb_lib - * Available option values for libusb_set_option(). +/** \ingroup libusb_hotplug + * Gets the user_data associated with a hotplug callback. + * + * Since version v1.0.24 \ref LIBUSB_API_VERSION >= 0x01000108 + * + * \param[in] ctx context this callback is registered with + * \param[in] callback_handle the handle of the callback to get the user_data of */ -enum libusb_option { - /** Set the log message verbosity. - * - * The default level is LIBUSB_LOG_LEVEL_NONE, which means no messages are ever - * printed. If you choose to increase the message verbosity level, ensure - * that your application does not close the stderr file descriptor. - * - * You are advised to use level LIBUSB_LOG_LEVEL_WARNING. libusb is conservative - * with its message logging and most of the time, will only log messages that - * explain error conditions and other oddities. This will help you debug - * your software. - * - * If the LIBUSB_DEBUG environment variable was set when libusb was - * initialized, this function does nothing: the message verbosity is fixed - * to the value in the environment variable. - * - * If libusb was compiled without any message logging, this function does - * nothing: you'll never get any messages. - * - * If libusb was compiled with verbose debug message logging, this function - * does nothing: you'll always get messages from all levels. - */ - LIBUSB_OPTION_LOG_LEVEL, +void * LIBUSB_CALL libusb_hotplug_get_user_data(libusb_context *ctx, + libusb_hotplug_callback_handle callback_handle); - /** Use the UsbDk backend for a specific context, if available. - * - * This option should be set immediately after calling libusb_init(), otherwise - * unspecified behavior may occur. - * - * Only valid on Windows. - */ - LIBUSB_OPTION_USE_USBDK, -}; +int LIBUSB_CALLV libusb_set_option(libusb_context *ctx, enum libusb_option option, ...); -int LIBUSB_CALL libusb_set_option(libusb_context *ctx, enum libusb_option option, ...); +#ifdef _MSC_VER +#pragma warning(pop) +#endif -#ifdef __cplusplus +#if defined(__cplusplus) } #endif diff --git a/onnxruntime b/onnxruntime deleted file mode 160000 index 7048164..0000000 --- a/onnxruntime +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 70481649e3c2dba0f0e1728d15a00e440084a217 diff --git a/onnxruntime b/onnxruntime new file mode 120000 index 0000000..123a799 --- /dev/null +++ b/onnxruntime @@ -0,0 +1 @@ +/home/sthalik/repos/onnxruntime \ No newline at end of file diff --git a/opencv b/opencv new file mode 120000 index 0000000..19fa14c --- /dev/null +++ b/opencv @@ -0,0 +1 @@ +/home/sthalik/repos/opencv \ No newline at end of file diff --git a/oscpack b/oscpack new file mode 160000 index 0000000..3e7e3a1 --- /dev/null +++ b/oscpack @@ -0,0 +1 @@ +Subproject commit 3e7e3a102e316d75fe176885a6dd08f216f2eac0 diff --git a/ovr_sdk_win_23.0.0/.msvc/PathHacks.targets b/ovr_sdk_win_23.0.0/.msvc/PathHacks.targets new file mode 100644 index 0000000..9e8cde6 --- /dev/null +++ b/ovr_sdk_win_23.0.0/.msvc/PathHacks.targets @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + $(IntDir)$([MSBuild]::MakeRelative($(ovrsource_root), %(ClCompile.RootDir)%(ClCompile.Directory)))/ + + + + + + + + + $(IntDir)$([System.String]::new('%(ClCompile.ObjectFileName)').GetHashCode())/ + + + + + + + + + PathHacks; + $(ComputeCompileInputsTargets); + + MakeDirsForCl; + + + diff --git a/ovr_sdk_win_23.0.0/.msvc/common.props b/ovr_sdk_win_23.0.0/.msvc/common.props new file mode 100644 index 0000000..2f9f8a3 --- /dev/null +++ b/ovr_sdk_win_23.0.0/.msvc/common.props @@ -0,0 +1,151 @@ + + + + + $(ovrsource_root).build/bin + $(ovrsource_root).build/obj + msvc-$(PlatformToolset)-$(Platform)-$(Configuration) + + $(ovrsource_root).build\gen\$(BuildConfig)\$(ProjectName)\ + VS2017 + VS2015 + + + + $(OutRoot)/$(BuildConfig)/ + $(ObjRoot)/$(BuildConfig)/$(ProjectName)/ + + + + + $(GenDir);%(AdditionalIncludeDirectories) + OldStyle + SyncCThrow + true + false + true + true + true + + + + + + Disabled + _DEBUG;%(PreprocessorDefinitions) + MultiThreadedDebug + + + + + + MaxSpeed + true + NDEBUG;%(PreprocessorDefinitions) + MultiThreaded + false + + + true + true + + + + + + MultiThreadedDebugDll + + + + + MultiThreadedDll + + + + + + + <__ovrsource_common>true + + + + + + + + diff --git a/ovr_sdk_win_23.0.0/.ovrsource_root.props b/ovr_sdk_win_23.0.0/.ovrsource_root.props new file mode 100644 index 0000000..389bdd8 --- /dev/null +++ b/ovr_sdk_win_23.0.0/.ovrsource_root.props @@ -0,0 +1,8 @@ + + + + $(MSBuildThisFileDirectory) + + $(SourcePath);$(ovrsource_root) + + diff --git a/ovr_sdk_win_23.0.0/3rdParty/TinyXml/tinyxml2.cpp b/ovr_sdk_win_23.0.0/3rdParty/TinyXml/tinyxml2.cpp new file mode 100644 index 0000000..6af1435 --- /dev/null +++ b/ovr_sdk_win_23.0.0/3rdParty/TinyXml/tinyxml2.cpp @@ -0,0 +1,2101 @@ +/* +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "tinyxml2.h" + +#include // yes, this one new style header, is in the Android SDK. +# ifdef ANDROID_NDK +# include +#else +# include +#endif + +static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF +static const char LF = LINE_FEED; +static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out +static const char CR = CARRIAGE_RETURN; +static const char SINGLE_QUOTE = '\''; +static const char DOUBLE_QUOTE = '\"'; + +// Bunch of unicode info at: +// http://www.unicode.org/faq/utf_bom.html +// ef bb bf (Microsoft "lead bytes") - designates UTF-8 + +static const unsigned char TIXML_UTF_LEAD_0 = 0xefU; +static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; +static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + + +#define DELETE_NODE( node ) { \ + if ( node ) { \ + MemPool* pool = node->_memPool; \ + node->~XMLNode(); \ + pool->Free( node ); \ + } \ + } +#define DELETE_ATTRIBUTE( attrib ) { \ + if ( attrib ) { \ + MemPool* pool = attrib->_memPool; \ + attrib->~XMLAttribute(); \ + pool->Free( attrib ); \ + } \ + } + +namespace tinyxml2 +{ + +struct Entity { + const char* pattern; + int length; + char value; +}; + +static const int NUM_ENTITIES = 5; +static const Entity entities[NUM_ENTITIES] = { + { "quot", 4, DOUBLE_QUOTE }, + { "amp", 3, '&' }, + { "apos", 4, SINGLE_QUOTE }, + { "lt", 2, '<' }, + { "gt", 2, '>' } +}; + + +StrPair::~StrPair() +{ + Reset(); +} + + +void StrPair::Reset() +{ + if ( _flags & NEEDS_DELETE ) { + delete [] _start; + } + _flags = 0; + _start = 0; + _end = 0; +} + + +void StrPair::SetStr( const char* str, int flags ) +{ + Reset(); + size_t len = strlen( str ); + _start = new char[ len+1 ]; + memcpy( _start, str, len+1 ); + _end = _start + len; + _flags = flags | NEEDS_DELETE; +} + + +char* StrPair::ParseText( char* p, const char* endTag, int strFlags ) +{ + TIXMLASSERT( endTag && *endTag ); + + char* start = p; // fixme: hides a member + char endChar = *endTag; + size_t length = strlen( endTag ); + + // Inner loop of text parsing. + while ( *p ) { + if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { + Set( start, p, strFlags ); + return p + length; + } + ++p; + } + return 0; +} + + +char* StrPair::ParseName( char* p ) +{ + char* start = p; + + if ( !start || !(*start) ) { + return 0; + } + + while( *p && ( + XMLUtil::IsAlphaNum( (unsigned char) *p ) + || *p == '_' + || *p == ':' + || (*p == '-' && p>start ) // can be in a name, but not lead it. + || (*p == '.' && p>start ) )) { // can be in a name, but not lead it. + ++p; + } + + if ( p > start ) { + Set( start, p, 0 ); + return p; + } + return 0; +} + + +void StrPair::CollapseWhitespace() +{ + // Trim leading space. + _start = XMLUtil::SkipWhiteSpace( _start ); + + if ( _start && *_start ) { + char* p = _start; // the read pointer + char* q = _start; // the write pointer + + while( *p ) { + if ( XMLUtil::IsWhiteSpace( *p )) { + p = XMLUtil::SkipWhiteSpace( p ); + if ( *p == 0 ) { + break; // don't write to q; this trims the trailing space. + } + *q = ' '; + ++q; + } + *q = *p; + ++q; + ++p; + } + *q = 0; + } +} + + +const char* StrPair::GetStr() +{ + if ( _flags & NEEDS_FLUSH ) { + *_end = 0; + _flags ^= NEEDS_FLUSH; + + if ( _flags ) { + char* p = _start; // the read pointer + char* q = _start; // the write pointer + + while( p < _end ) { + if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) { + // CR-LF pair becomes LF + // CR alone becomes LF + // LF-CR becomes LF + if ( *(p+1) == LF ) { + p += 2; + } + else { + ++p; + } + *q++ = LF; + } + else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { + if ( *(p+1) == CR ) { + p += 2; + } + else { + ++p; + } + *q++ = LF; + } + else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { + // Entities handled by tinyXML2: + // - special entities in the entity table [in/out] + // - numeric character reference [in] + // 中 or 中 + + if ( *(p+1) == '#' ) { + char buf[10] = { 0 }; + int len; + p = const_cast( XMLUtil::GetCharacterRef( p, buf, &len ) ); + for( int i=0; i(p); + // Check for BOM: + if ( *(pu+0) == TIXML_UTF_LEAD_0 + && *(pu+1) == TIXML_UTF_LEAD_1 + && *(pu+2) == TIXML_UTF_LEAD_2 ) { + *bom = true; + p += 3; + } + return p; +} + + +void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +{ + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) { + *length = 1; + } + else if ( input < 0x800 ) { + *length = 2; + } + else if ( input < 0x10000 ) { + *length = 3; + } + else if ( input < 0x200000 ) { + *length = 4; + } + else { + *length = 0; // This code won't covert this correctly anyway. + return; + } + + output += *length; + + // Scary scary fall throughs. + switch (*length) { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + default: + break; + } +} + + +const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) +{ + // Presume an entity, and pull it out. + *length = 0; + + if ( *(p+1) == '#' && *(p+2) ) { + unsigned long ucs = 0; + ptrdiff_t delta = 0; + unsigned mult = 1; + + if ( *(p+2) == 'x' ) { + // Hexadecimal. + if ( !*(p+3) ) { + return 0; + } + + const char* q = p+3; + q = strchr( q, ';' ); + + if ( !q || !*q ) { + return 0; + } + + delta = q-p; + --q; + + while ( *q != 'x' ) { + if ( *q >= '0' && *q <= '9' ) { + ucs += mult * (*q - '0'); + } + else if ( *q >= 'a' && *q <= 'f' ) { + ucs += mult * (*q - 'a' + 10); + } + else if ( *q >= 'A' && *q <= 'F' ) { + ucs += mult * (*q - 'A' + 10 ); + } + else { + return 0; + } + mult *= 16; + --q; + } + } + else { + // Decimal. + if ( !*(p+2) ) { + return 0; + } + + const char* q = p+2; + q = strchr( q, ';' ); + + if ( !q || !*q ) { + return 0; + } + + delta = q-p; + --q; + + while ( *q != '#' ) { + if ( *q >= '0' && *q <= '9' ) { + ucs += mult * (*q - '0'); + } + else { + return 0; + } + mult *= 10; + --q; + } + } + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + return p + delta + 1; + } + return p+1; +} + + +void XMLUtil::ToStr( int v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); +} + + +void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%u", v ); +} + + +void XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 ); +} + + +void XMLUtil::ToStr( float v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%g", v ); +} + + +void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%g", v ); +} + + +bool XMLUtil::ToInt( const char* str, int* value ) +{ + if ( TIXML_SSCANF( str, "%d", value ) == 1 ) { + return true; + } + return false; +} + +bool XMLUtil::ToUnsigned( const char* str, unsigned *value ) +{ + if ( TIXML_SSCANF( str, "%u", value ) == 1 ) { + return true; + } + return false; +} + +bool XMLUtil::ToBool( const char* str, bool* value ) +{ + int ival = 0; + if ( ToInt( str, &ival )) { + *value = (ival==0) ? false : true; + return true; + } + if ( StringEqual( str, "true" ) ) { + *value = true; + return true; + } + else if ( StringEqual( str, "false" ) ) { + *value = false; + return true; + } + return false; +} + + +bool XMLUtil::ToFloat( const char* str, float* value ) +{ + if ( TIXML_SSCANF( str, "%f", value ) == 1 ) { + return true; + } + return false; +} + +bool XMLUtil::ToDouble( const char* str, double* value ) +{ + if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { + return true; + } + return false; +} + + +char* XMLDocument::Identify( char* p, XMLNode** node ) +{ + XMLNode* returnNode = 0; + char* start = p; + p = XMLUtil::SkipWhiteSpace( p ); + if( !p || !*p ) { + return p; + } + + // What is this thing? + // - Elements start with a letter or underscore, but xml is reserved. + // - Comments: + // + // With a special case: + // + // + // + // + // Where the closing element (/foo) *must* be the next thing after the opening + // element, and the names must match. BUT the tricky bit is that the closing + // element will be read by the child. + // + // 'endTag' is the end tag for this node, it is returned by a call to a child. + // 'parentEnd' is the end tag for the parent, which is filled in and returned. + + while( p && *p ) { + XMLNode* node = 0; + + p = _document->Identify( p, &node ); + if ( p == 0 || node == 0 ) { + break; + } + + StrPair endTag; + p = node->ParseDeep( p, &endTag ); + if ( !p ) { + DELETE_NODE( node ); + node = 0; + if ( !_document->Error() ) { + _document->SetError( XML_ERROR_PARSING, 0, 0 ); + } + break; + } + + // We read the end tag. Return it to the parent. + if ( node->ToElement() && node->ToElement()->ClosingType() == XMLElement::CLOSING ) { + if ( parentEnd ) { + *parentEnd = static_cast(node)->_value; + } + node->_memPool->SetTracked(); // created and then immediately deleted. + DELETE_NODE( node ); + return p; + } + + // Handle an end tag returned to this level. + // And handle a bunch of annoying errors. + XMLElement* ele = node->ToElement(); + if ( ele ) { + if ( endTag.Empty() && ele->ClosingType() == XMLElement::OPEN ) { + _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); + p = 0; + } + else if ( !endTag.Empty() && ele->ClosingType() != XMLElement::OPEN ) { + _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); + p = 0; + } + else if ( !endTag.Empty() ) { + if ( !XMLUtil::StringEqual( endTag.GetStr(), node->Value() )) { + _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); + p = 0; + } + } + } + if ( p == 0 ) { + DELETE_NODE( node ); + node = 0; + } + if ( node ) { + this->InsertEndChild( node ); + } + } + return 0; +} + +// --------- XMLText ---------- // +char* XMLText::ParseDeep( char* p, StrPair* ) +{ + const char* start = p; + if ( this->CData() ) { + p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_CDATA, start, 0 ); + } + return p; + } + else { + int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; + if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) { + flags |= StrPair::COLLAPSE_WHITESPACE; + } + + p = _value.ParseText( p, "<", flags ); + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_TEXT, start, 0 ); + } + if ( p && *p ) { + return p-1; + } + } + return 0; +} + + +XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern? + text->SetCData( this->CData() ); + return text; +} + + +bool XMLText::ShallowEqual( const XMLNode* compare ) const +{ + return ( compare->ToText() && XMLUtil::StringEqual( compare->ToText()->Value(), Value() )); +} + + +bool XMLText::Accept( XMLVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +// --------- XMLComment ---------- // + +XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLComment::~XMLComment() +{ +} + + +char* XMLComment::ParseDeep( char* p, StrPair* ) +{ + // Comment parses as text. + const char* start = p; + p = _value.ParseText( p, "-->", StrPair::COMMENT ); + if ( p == 0 ) { + _document->SetError( XML_ERROR_PARSING_COMMENT, start, 0 ); + } + return p; +} + + +XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern? + return comment; +} + + +bool XMLComment::ShallowEqual( const XMLNode* compare ) const +{ + return ( compare->ToComment() && XMLUtil::StringEqual( compare->ToComment()->Value(), Value() )); +} + + +bool XMLComment::Accept( XMLVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + + +// --------- XMLDeclaration ---------- // + +XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLDeclaration::~XMLDeclaration() +{ + //printf( "~XMLDeclaration\n" ); +} + + +char* XMLDeclaration::ParseDeep( char* p, StrPair* ) +{ + // Declaration parses as text. + const char* start = p; + p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); + if ( p == 0 ) { + _document->SetError( XML_ERROR_PARSING_DECLARATION, start, 0 ); + } + return p; +} + + +XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern? + return dec; +} + + +bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const +{ + return ( compare->ToDeclaration() && XMLUtil::StringEqual( compare->ToDeclaration()->Value(), Value() )); +} + + + +bool XMLDeclaration::Accept( XMLVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + +// --------- XMLUnknown ---------- // + +XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLUnknown::~XMLUnknown() +{ +} + + +char* XMLUnknown::ParseDeep( char* p, StrPair* ) +{ + // Unknown parses as text. + const char* start = p; + + p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION ); + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_UNKNOWN, start, 0 ); + } + return p; +} + + +XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern? + return text; +} + + +bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const +{ + return ( compare->ToUnknown() && XMLUtil::StringEqual( compare->ToUnknown()->Value(), Value() )); +} + + +bool XMLUnknown::Accept( XMLVisitor* visitor ) const +{ + return visitor->Visit( *this ); +} + +// --------- XMLAttribute ---------- // +char* XMLAttribute::ParseDeep( char* p, bool processEntities ) +{ + // Parse using the name rules: bug fix, was using ParseText before + p = _name.ParseName( p ); + if ( !p || !*p ) { + return 0; + } + + // Skip white space before = + p = XMLUtil::SkipWhiteSpace( p ); + if ( !p || *p != '=' ) { + return 0; + } + + ++p; // move up to opening quote + p = XMLUtil::SkipWhiteSpace( p ); + if ( *p != '\"' && *p != '\'' ) { + return 0; + } + + char endTag[2] = { *p, 0 }; + ++p; // move past opening quote + + p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES ); + return p; +} + + +void XMLAttribute::SetName( const char* n ) +{ + _name.SetStr( n ); +} + + +XMLError XMLAttribute::QueryIntValue( int* value ) const +{ + if ( XMLUtil::ToInt( Value(), value )) { + return XML_NO_ERROR; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const +{ + if ( XMLUtil::ToUnsigned( Value(), value )) { + return XML_NO_ERROR; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryBoolValue( bool* value ) const +{ + if ( XMLUtil::ToBool( Value(), value )) { + return XML_NO_ERROR; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryFloatValue( float* value ) const +{ + if ( XMLUtil::ToFloat( Value(), value )) { + return XML_NO_ERROR; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryDoubleValue( double* value ) const +{ + if ( XMLUtil::ToDouble( Value(), value )) { + return XML_NO_ERROR; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +void XMLAttribute::SetAttribute( const char* v ) +{ + _value.SetStr( v ); +} + + +void XMLAttribute::SetAttribute( int v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +void XMLAttribute::SetAttribute( unsigned v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +void XMLAttribute::SetAttribute( bool v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + +void XMLAttribute::SetAttribute( double v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + +void XMLAttribute::SetAttribute( float v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +// --------- XMLElement ---------- // +XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), + _closingType( 0 ), + _rootAttribute( 0 ) +{ +} + + +XMLElement::~XMLElement() +{ + while( _rootAttribute ) { + XMLAttribute* next = _rootAttribute->_next; + DELETE_ATTRIBUTE( _rootAttribute ); + _rootAttribute = next; + } +} + + +XMLAttribute* XMLElement::FindAttribute( const char* name ) +{ + XMLAttribute* a = 0; + for( a=_rootAttribute; a; a = a->_next ) { + if ( XMLUtil::StringEqual( a->Name(), name ) ) { + return a; + } + } + return 0; +} + + +const XMLAttribute* XMLElement::FindAttribute( const char* name ) const +{ + XMLAttribute* a = 0; + for( a=_rootAttribute; a; a = a->_next ) { + if ( XMLUtil::StringEqual( a->Name(), name ) ) { + return a; + } + } + return 0; +} + + +const char* XMLElement::Attribute( const char* name, const char* value ) const +{ + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return 0; + } + if ( !value || XMLUtil::StringEqual( a->Value(), value )) { + return a->Value(); + } + return 0; +} + + +const char* XMLElement::GetText() const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + return FirstChild()->ToText()->Value(); + } + return 0; +} + + +XMLError XMLElement::QueryIntText( int* ival ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->ToText()->Value(); + if ( XMLUtil::ToInt( t, ival ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->ToText()->Value(); + if ( XMLUtil::ToUnsigned( t, uval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryBoolText( bool* bval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->ToText()->Value(); + if ( XMLUtil::ToBool( t, bval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryDoubleText( double* dval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->ToText()->Value(); + if ( XMLUtil::ToDouble( t, dval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryFloatText( float* fval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->ToText()->Value(); + if ( XMLUtil::ToFloat( t, fval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + + +XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) +{ + XMLAttribute* last = 0; + XMLAttribute* attrib = 0; + for( attrib = _rootAttribute; + attrib; + last = attrib, attrib = attrib->_next ) { + if ( XMLUtil::StringEqual( attrib->Name(), name ) ) { + break; + } + } + if ( !attrib ) { + attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); + attrib->_memPool = &_document->_attributePool; + if ( last ) { + last->_next = attrib; + } + else { + _rootAttribute = attrib; + } + attrib->SetName( name ); + attrib->_memPool->SetTracked(); // always created and linked. + } + return attrib; +} + + +void XMLElement::DeleteAttribute( const char* name ) +{ + XMLAttribute* prev = 0; + for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) { + if ( XMLUtil::StringEqual( name, a->Name() ) ) { + if ( prev ) { + prev->_next = a->_next; + } + else { + _rootAttribute = a->_next; + } + DELETE_ATTRIBUTE( a ); + break; + } + prev = a; + } +} + + +char* XMLElement::ParseAttributes( char* p ) +{ + const char* start = p; + XMLAttribute* prevAttribute = 0; + + // Read the attributes. + while( p ) { + p = XMLUtil::SkipWhiteSpace( p ); + if ( !p || !(*p) ) { + _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); + return 0; + } + + // attribute. + if ( XMLUtil::IsAlpha( *p ) ) { + XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); + attrib->_memPool = &_document->_attributePool; + attrib->_memPool->SetTracked(); + + p = attrib->ParseDeep( p, _document->ProcessEntities() ); + if ( !p || Attribute( attrib->Name() ) ) { + DELETE_ATTRIBUTE( attrib ); + _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); + return 0; + } + // There is a minor bug here: if the attribute in the source xml + // document is duplicated, it will not be detected and the + // attribute will be doubly added. However, tracking the 'prevAttribute' + // avoids re-scanning the attribute list. Preferring performance for + // now, may reconsider in the future. + if ( prevAttribute ) { + prevAttribute->_next = attrib; + } + else { + _rootAttribute = attrib; + } + prevAttribute = attrib; + } + // end of the tag + else if ( *p == '/' && *(p+1) == '>' ) { + _closingType = CLOSED; + return p+2; // done; sealed element. + } + // end of the tag + else if ( *p == '>' ) { + ++p; + break; + } + else { + _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); + return 0; + } + } + return p; +} + + +// +// +// foobar +// +char* XMLElement::ParseDeep( char* p, StrPair* strPair ) +{ + // Read the element name. + p = XMLUtil::SkipWhiteSpace( p ); + if ( !p ) { + return 0; + } + + // The closing element is the form. It is + // parsed just like a regular element then deleted from + // the DOM. + if ( *p == '/' ) { + _closingType = CLOSING; + ++p; + } + + p = _value.ParseName( p ); + if ( _value.Empty() ) { + return 0; + } + + p = ParseAttributes( p ); + if ( !p || !*p || _closingType ) { + return p; + } + + p = XMLNode::ParseDeep( p, strPair ); + return p; +} + + + +XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern? + for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) { + element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern? + } + return element; +} + + +bool XMLElement::ShallowEqual( const XMLNode* compare ) const +{ + const XMLElement* other = compare->ToElement(); + if ( other && XMLUtil::StringEqual( other->Value(), Value() )) { + + const XMLAttribute* a=FirstAttribute(); + const XMLAttribute* b=other->FirstAttribute(); + + while ( a && b ) { + if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) { + return false; + } + a = a->Next(); + b = b->Next(); + } + if ( a || b ) { + // different count + return false; + } + return true; + } + return false; +} + + +bool XMLElement::Accept( XMLVisitor* visitor ) const +{ + if ( visitor->VisitEnter( *this, _rootAttribute ) ) { + for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { + if ( !node->Accept( visitor ) ) { + break; + } + } + } + return visitor->VisitExit( *this ); +} + + +// --------- XMLDocument ----------- // +XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) : + XMLNode( 0 ), + _writeBOM( false ), + _processEntities( processEntities ), + _errorID( XML_NO_ERROR ), + _whitespace( whitespace ), + _errorStr1( 0 ), + _errorStr2( 0 ), + _charBuffer( 0 ) +{ + _document = this; // avoid warning about 'this' in initializer list +} + + +XMLDocument::~XMLDocument() +{ + DeleteChildren(); + delete [] _charBuffer; + +#if 0 + textPool.Trace( "text" ); + elementPool.Trace( "element" ); + commentPool.Trace( "comment" ); + attributePool.Trace( "attribute" ); +#endif + +#ifdef DEBUG + if ( Error() == false ) { + TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); + TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); + TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() ); + TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() ); + } +#endif +} + + +void XMLDocument::InitDocument() +{ + _errorID = XML_NO_ERROR; + _errorStr1 = 0; + _errorStr2 = 0; + + delete [] _charBuffer; + _charBuffer = 0; +} + + +XMLElement* XMLDocument::NewElement( const char* name ) +{ + XMLElement* ele = new (_elementPool.Alloc()) XMLElement( this ); + ele->_memPool = &_elementPool; + ele->SetName( name ); + return ele; +} + + +XMLComment* XMLDocument::NewComment( const char* str ) +{ + XMLComment* comment = new (_commentPool.Alloc()) XMLComment( this ); + comment->_memPool = &_commentPool; + comment->SetValue( str ); + return comment; +} + + +XMLText* XMLDocument::NewText( const char* str ) +{ + XMLText* text = new (_textPool.Alloc()) XMLText( this ); + text->_memPool = &_textPool; + text->SetValue( str ); + return text; +} + + +XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) +{ + XMLDeclaration* dec = new (_commentPool.Alloc()) XMLDeclaration( this ); + dec->_memPool = &_commentPool; + dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); + return dec; +} + + +XMLUnknown* XMLDocument::NewUnknown( const char* str ) +{ + XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this ); + unk->_memPool = &_commentPool; + unk->SetValue( str ); + return unk; +} + + +XMLError XMLDocument::LoadFile( const char* filename ) +{ + DeleteChildren(); + InitDocument(); + FILE* fp = 0; + +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + errno_t err = fopen_s(&fp, filename, "rb" ); + if ( !fp || err) { +#else + fp = fopen( filename, "rb" ); + if ( !fp) { +#endif + SetError( XML_ERROR_FILE_NOT_FOUND, filename, 0 ); + return _errorID; + } + LoadFile( fp ); + fclose( fp ); + return _errorID; +} + + +XMLError XMLDocument::LoadFile( FILE* fp ) +{ + DeleteChildren(); + InitDocument(); + + fseek( fp, 0, SEEK_END ); + size_t size = ftell( fp ); + fseek( fp, 0, SEEK_SET ); + + if ( size == 0 ) { + return _errorID; + } + + _charBuffer = new char[size+1]; + size_t read = fread( _charBuffer, 1, size, fp ); + if ( read != size ) { + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + + _charBuffer[size] = 0; + + const char* p = _charBuffer; + p = XMLUtil::SkipWhiteSpace( p ); + p = XMLUtil::ReadBOM( p, &_writeBOM ); + if ( !p || !*p ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + + ParseDeep( _charBuffer + (p-_charBuffer), 0 ); + return _errorID; +} + + +XMLError XMLDocument::SaveFile( const char* filename, bool compact ) +{ + FILE* fp = 0; +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + errno_t err = fopen_s(&fp, filename, "w" ); + if ( !fp || err) { +#else + fp = fopen( filename, "w" ); + if ( !fp) { +#endif + SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 ); + return _errorID; + } + SaveFile(fp, compact); + fclose( fp ); + return _errorID; +} + + +XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) +{ + XMLPrinter stream( fp, compact ); + Print( &stream ); + return _errorID; +} + + +XMLError XMLDocument::Parse( const char* p, size_t len ) +{ + DeleteChildren(); + InitDocument(); + + if ( !p || !*p ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + if ( len == (size_t)(-1) ) { + len = strlen( p ); + } + _charBuffer = new char[ len+1 ]; + memcpy( _charBuffer, p, len ); + _charBuffer[len] = 0; + + p = XMLUtil::SkipWhiteSpace( p ); + p = XMLUtil::ReadBOM( p, &_writeBOM ); + if ( !p || !*p ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + + ParseDeep( _charBuffer, 0 ); + return _errorID; +} + + +void XMLDocument::Print( XMLPrinter* streamer ) +{ + XMLPrinter stdStreamer( stdout ); + if ( !streamer ) { + streamer = &stdStreamer; + } + Accept( streamer ); +} + + +void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 ) +{ + _errorID = error; + _errorStr1 = str1; + _errorStr2 = str2; +} + + +void XMLDocument::PrintError() const +{ + if ( _errorID ) { + static const int LEN = 20; + char buf1[LEN] = { 0 }; + char buf2[LEN] = { 0 }; + + if ( _errorStr1 ) { + TIXML_SNPRINTF( buf1, LEN, "%s", _errorStr1 ); + } + if ( _errorStr2 ) { + TIXML_SNPRINTF( buf2, LEN, "%s", _errorStr2 ); + } + + printf( "XMLDocument error id=%d str1=%s str2=%s\n", + _errorID, buf1, buf2 ); + } +} + + +XMLPrinter::XMLPrinter( FILE* file, bool compact ) : + _elementJustOpened( false ), + _firstElement( true ), + _fp( file ), + _depth( 0 ), + _textDepth( -1 ), + _processEntities( true ), + _compactMode( compact ) +{ + for( int i=0; i'] = true; // not required, but consistency is nice + _buffer.Push( 0 ); +} + + +void XMLPrinter::Print( const char* format, ... ) +{ + va_list va; + va_start( va, format ); + + if ( _fp ) { + vfprintf( _fp, format, va ); + } + else { + // This seems brutally complex. Haven't figured out a better + // way on windows. +#ifdef _MSC_VER + int len = -1; + int expand = 1000; + while ( len < 0 ) { + len = vsnprintf_s( _accumulator.Mem(), _accumulator.Capacity(), _TRUNCATE, format, va ); + if ( len < 0 ) { + expand *= 3/2; + _accumulator.PushArr( expand ); + } + } + char* p = _buffer.PushArr( len ) - 1; + memcpy( p, _accumulator.Mem(), len+1 ); +#else + int len = vsnprintf( 0, 0, format, va ); + // Close out and re-start the va-args + va_end( va ); + va_start( va, format ); + char* p = _buffer.PushArr( len ) - 1; + vsnprintf( p, len+1, format, va ); +#endif + } + va_end( va ); +} + + +void XMLPrinter::PrintSpace( int depth ) +{ + for( int i=0; i 0 && *q < ENTITY_RANGE ) { + // Check for entities. If one is found, flush + // the stream up until the entity, write the + // entity, and keep looking. + if ( flag[(unsigned)(*q)] ) { + while ( p < q ) { + Print( "%c", *p ); + ++p; + } + for( int i=0; i 0) ) { + Print( "%s", p ); + } +} + + +void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) +{ + static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 }; + if ( writeBOM ) { + Print( "%s", bom ); + } + if ( writeDec ) { + PushDeclaration( "xml version=\"1.0\"" ); + } +} + + +void XMLPrinter::OpenElement( const char* name ) +{ + if ( _elementJustOpened ) { + SealElement(); + } + _stack.Push( name ); + + if ( _textDepth < 0 && !_firstElement && !_compactMode ) { + Print( "\n" ); + PrintSpace( _depth ); + } + + Print( "<%s", name ); + _elementJustOpened = true; + _firstElement = false; + ++_depth; +} + + +void XMLPrinter::PushAttribute( const char* name, const char* value ) +{ + TIXMLASSERT( _elementJustOpened ); + Print( " %s=\"", name ); + PrintString( value, false ); + Print( "\"" ); +} + + +void XMLPrinter::PushAttribute( const char* name, int v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute( const char* name, unsigned v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute( const char* name, bool v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute( const char* name, double v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::CloseElement() +{ + --_depth; + const char* name = _stack.Pop(); + + if ( _elementJustOpened ) { + Print( "/>" ); + } + else { + if ( _textDepth < 0 && !_compactMode) { + Print( "\n" ); + PrintSpace( _depth ); + } + Print( "", name ); + } + + if ( _textDepth == _depth ) { + _textDepth = -1; + } + if ( _depth == 0 && !_compactMode) { + Print( "\n" ); + } + _elementJustOpened = false; +} + + +void XMLPrinter::SealElement() +{ + _elementJustOpened = false; + Print( ">" ); +} + + +void XMLPrinter::PushText( const char* text, bool cdata ) +{ + _textDepth = _depth-1; + + if ( _elementJustOpened ) { + SealElement(); + } + if ( cdata ) { + Print( "" ); + } + else { + PrintString( text, true ); + } +} + +void XMLPrinter::PushText( int value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( unsigned value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( bool value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( float value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( double value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushComment( const char* comment ) +{ + if ( _elementJustOpened ) { + SealElement(); + } + if ( _textDepth < 0 && !_firstElement && !_compactMode) { + Print( "\n" ); + PrintSpace( _depth ); + } + _firstElement = false; + Print( "", comment ); +} + + +void XMLPrinter::PushDeclaration( const char* value ) +{ + if ( _elementJustOpened ) { + SealElement(); + } + if ( _textDepth < 0 && !_firstElement && !_compactMode) { + Print( "\n" ); + PrintSpace( _depth ); + } + _firstElement = false; + Print( "", value ); +} + + +void XMLPrinter::PushUnknown( const char* value ) +{ + if ( _elementJustOpened ) { + SealElement(); + } + if ( _textDepth < 0 && !_firstElement && !_compactMode) { + Print( "\n" ); + PrintSpace( _depth ); + } + _firstElement = false; + Print( "", value ); +} + + +bool XMLPrinter::VisitEnter( const XMLDocument& doc ) +{ + _processEntities = doc.ProcessEntities(); + if ( doc.HasBOM() ) { + PushHeader( true, false ); + } + return true; +} + + +bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) +{ + OpenElement( element.Name() ); + while ( attribute ) { + PushAttribute( attribute->Name(), attribute->Value() ); + attribute = attribute->Next(); + } + return true; +} + + +bool XMLPrinter::VisitExit( const XMLElement& ) +{ + CloseElement(); + return true; +} + + +bool XMLPrinter::Visit( const XMLText& text ) +{ + PushText( text.Value(), text.CData() ); + return true; +} + + +bool XMLPrinter::Visit( const XMLComment& comment ) +{ + PushComment( comment.Value() ); + return true; +} + +bool XMLPrinter::Visit( const XMLDeclaration& declaration ) +{ + PushDeclaration( declaration.Value() ); + return true; +} + + +bool XMLPrinter::Visit( const XMLUnknown& unknown ) +{ + PushUnknown( unknown.Value() ); + return true; +} + +} // namespace tinyxml2 + diff --git a/ovr_sdk_win_23.0.0/3rdParty/TinyXml/tinyxml2.h b/ovr_sdk_win_23.0.0/3rdParty/TinyXml/tinyxml2.h new file mode 100644 index 0000000..ba1b249 --- /dev/null +++ b/ovr_sdk_win_23.0.0/3rdParty/TinyXml/tinyxml2.h @@ -0,0 +1,1911 @@ +/* +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef TINYXML2_INCLUDED +#define TINYXML2_INCLUDED + +#if defined(ANDROID_NDK) || defined(__BORLANDC__) +# include +# include +# include +# include +# include +# include +#else +# include +# include +# include +# include +# include +# include +#endif + +/* + TODO: intern strings instead of allocation. +*/ +/* + gcc: + g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe + + Formatting, Artistic Style: + AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h +*/ + +#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__) +# ifndef DEBUG +# define DEBUG +# endif +#endif + + +#if defined(DEBUG) +# if defined(_MSC_VER) +# define TIXMLASSERT( x ) if ( !(x)) { __debugbreak(); } //if ( !(x)) WinDebugBreak() +# elif defined (ANDROID_NDK) +# include +# define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } +# else +# include +# define TIXMLASSERT assert +# endif +# else +# define TIXMLASSERT( x ) {} +#endif + + +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) +// Microsoft visual studio, version 2005 and higher. +/*int _snprintf_s( + char *buffer, + size_t sizeOfBuffer, + size_t count, + const char *format [, + argument] ... +);*/ +inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) +{ + va_list va; + va_start( va, format ); + int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); + va_end( va ); + return result; +} +#define TIXML_SSCANF sscanf_s +#else +// GCC version 3 and higher +//#warning( "Using sn* functions." ) +#define TIXML_SNPRINTF snprintf +#define TIXML_SSCANF sscanf +#endif + +static const int TIXML2_MAJOR_VERSION = 1; +static const int TIXML2_MINOR_VERSION = 0; +static const int TIXML2_PATCH_VERSION = 9; + +namespace tinyxml2 +{ +class XMLDocument; +class XMLElement; +class XMLAttribute; +class XMLComment; +class XMLNode; +class XMLText; +class XMLDeclaration; +class XMLUnknown; + +class XMLPrinter; + +/* + A class that wraps strings. Normally stores the start and end + pointers into the XML file itself, and will apply normalization + and entity translation if actually read. Can also store (and memory + manage) a traditional char[] +*/ +class StrPair +{ +public: + enum { + NEEDS_ENTITY_PROCESSING = 0x01, + NEEDS_NEWLINE_NORMALIZATION = 0x02, + COLLAPSE_WHITESPACE = 0x04, + + TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_NAME = 0, + ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + COMMENT = NEEDS_NEWLINE_NORMALIZATION + }; + + StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {} + ~StrPair(); + + void Set( char* start, char* end, int flags ) { + Reset(); + _start = start; + _end = end; + _flags = flags | NEEDS_FLUSH; + } + + const char* GetStr(); + + bool Empty() const { + return _start == _end; + } + + void SetInternedStr( const char* str ) { + Reset(); + _start = const_cast(str); + } + + void SetStr( const char* str, int flags=0 ); + + char* ParseText( char* in, const char* endTag, int strFlags ); + char* ParseName( char* in ); + +private: + void Reset(); + void CollapseWhitespace(); + + enum { + NEEDS_FLUSH = 0x100, + NEEDS_DELETE = 0x200 + }; + + // After parsing, if *end != 0, it can be set to zero. + int _flags; + char* _start; + char* _end; +}; + + +/* + A dynamic array of Plain Old Data. Doesn't support constructors, etc. + Has a small initial memory pool, so that low or no usage will not + cause a call to new/delete +*/ +template +class DynArray +{ +public: + DynArray< T, INIT >() { + _mem = _pool; + _allocated = INIT; + _size = 0; + } + + ~DynArray() { + if ( _mem != _pool ) { + delete [] _mem; + } + } + + void Push( T t ) { + EnsureCapacity( _size+1 ); + _mem[_size++] = t; + } + + T* PushArr( int count ) { + EnsureCapacity( _size+count ); + T* ret = &_mem[_size]; + _size += count; + return ret; + } + + T Pop() { + return _mem[--_size]; + } + + void PopArr( int count ) { + TIXMLASSERT( _size >= count ); + _size -= count; + } + + bool Empty() const { + return _size == 0; + } + + T& operator[](int i) { + TIXMLASSERT( i>= 0 && i < _size ); + return _mem[i]; + } + + const T& operator[](int i) const { + TIXMLASSERT( i>= 0 && i < _size ); + return _mem[i]; + } + + int Size() const { + return _size; + } + + int Capacity() const { + return _allocated; + } + + const T* Mem() const { + return _mem; + } + + T* Mem() { + return _mem; + } + +private: + void EnsureCapacity( int cap ) { + if ( cap > _allocated ) { + int newAllocated = cap * 2; + T* newMem = new T[newAllocated]; + memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs + if ( _mem != _pool ) { + delete [] _mem; + } + _mem = newMem; + _allocated = newAllocated; + } + } + + T* _mem; + T _pool[INIT]; + int _allocated; // objects allocated + int _size; // number objects in use +}; + + +/* + Parent virtual class of a pool for fast allocation + and deallocation of objects. +*/ +class MemPool +{ +public: + MemPool() {} + virtual ~MemPool() {} + + virtual int ItemSize() const = 0; + virtual void* Alloc() = 0; + virtual void Free( void* ) = 0; + virtual void SetTracked() = 0; +}; + + +/* + Template child class to create pools of the correct type. +*/ +template< int SIZE > +class MemPoolT : public MemPool +{ +public: + MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} + ~MemPoolT() { + // Delete the blocks. + for( int i=0; i<_blockPtrs.Size(); ++i ) { + delete _blockPtrs[i]; + } + } + + virtual int ItemSize() const { + return SIZE; + } + int CurrentAllocs() const { + return _currentAllocs; + } + + virtual void* Alloc() { + if ( !_root ) { + // Need a new block. + Block* block = new Block(); + _blockPtrs.Push( block ); + + for( int i=0; ichunk[i].next = &block->chunk[i+1]; + } + block->chunk[COUNT-1].next = 0; + _root = block->chunk; + } + void* result = _root; + _root = _root->next; + + ++_currentAllocs; + if ( _currentAllocs > _maxAllocs ) { + _maxAllocs = _currentAllocs; + } + _nAllocs++; + _nUntracked++; + return result; + } + virtual void Free( void* mem ) { + if ( !mem ) { + return; + } + --_currentAllocs; + Chunk* chunk = (Chunk*)mem; +#ifdef DEBUG + memset( chunk, 0xfe, sizeof(Chunk) ); +#endif + chunk->next = _root; + _root = chunk; + } + void Trace( const char* name ) { + printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", + name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() ); + } + + void SetTracked() { + _nUntracked--; + } + + int Untracked() const { + return _nUntracked; + } + + enum { COUNT = 1024/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private + +private: + union Chunk { + Chunk* next; + char mem[SIZE]; + }; + struct Block { + Chunk chunk[COUNT]; + }; + DynArray< Block*, 10 > _blockPtrs; + Chunk* _root; + + int _currentAllocs; + int _nAllocs; + int _maxAllocs; + int _nUntracked; +}; + + + +/** + Implements the interface to the "Visitor pattern" (see the Accept() method.) + If you call the Accept() method, it requires being passed a XMLVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs + are simply called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its sibilings will be visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the TiXmlDocument, although all nodes support visiting. + + You should never change the document from a callback. + + @sa XMLNode::Accept() +*/ +class XMLVisitor +{ +public: + virtual ~XMLVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { + return true; + } + /// Visit a document. + virtual bool VisitExit( const XMLDocument& /*doc*/ ) { + return true; + } + + /// Visit an element. + virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { + return true; + } + /// Visit an element. + virtual bool VisitExit( const XMLElement& /*element*/ ) { + return true; + } + + /// Visit a declaration. + virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { + return true; + } + /// Visit a text node. + virtual bool Visit( const XMLText& /*text*/ ) { + return true; + } + /// Visit a comment node. + virtual bool Visit( const XMLComment& /*comment*/ ) { + return true; + } + /// Visit an unknown node. + virtual bool Visit( const XMLUnknown& /*unknown*/ ) { + return true; + } +}; + + +/* + Utility functionality. +*/ +class XMLUtil +{ +public: + // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't + // correct, but simple, and usually works. + static const char* SkipWhiteSpace( const char* p ) { + while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast(p) ) ) { + ++p; + } + return p; + } + static char* SkipWhiteSpace( char* p ) { + while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast(p) ) ) { + ++p; + } + return p; + } + static bool IsWhiteSpace( char p ) { + return !IsUTF8Continuation(p) && isspace( static_cast(p) ); + } + + inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { + int n = 0; + if ( p == q ) { + return true; + } + while( *p && *q && *p == *q && n(const_cast(this)->FirstChildElement( value )); + } + + /// Get the last child node, or null if none exists. + const XMLNode* LastChild() const { + return _lastChild; + } + + XMLNode* LastChild() { + return const_cast(const_cast(this)->LastChild() ); + } + + /** Get the last child element or optionally the last child + element with the specified name. + */ + const XMLElement* LastChildElement( const char* value=0 ) const; + + XMLElement* LastChildElement( const char* value=0 ) { + return const_cast(const_cast(this)->LastChildElement(value) ); + } + + /// Get the previous (left) sibling node of this node. + const XMLNode* PreviousSibling() const { + return _prev; + } + + XMLNode* PreviousSibling() { + return _prev; + } + + /// Get the previous (left) sibling element of this node, with an opitionally supplied name. + const XMLElement* PreviousSiblingElement( const char* value=0 ) const ; + + XMLElement* PreviousSiblingElement( const char* value=0 ) { + return const_cast(const_cast(this)->PreviousSiblingElement( value ) ); + } + + /// Get the next (right) sibling node of this node. + const XMLNode* NextSibling() const { + return _next; + } + + XMLNode* NextSibling() { + return _next; + } + + /// Get the next (right) sibling element of this node, with an opitionally supplied name. + const XMLElement* NextSiblingElement( const char* value=0 ) const; + + XMLElement* NextSiblingElement( const char* value=0 ) { + return const_cast(const_cast(this)->NextSiblingElement( value ) ); + } + + /** + Add a child node as the last (right) child. + */ + XMLNode* InsertEndChild( XMLNode* addThis ); + + XMLNode* LinkEndChild( XMLNode* addThis ) { + return InsertEndChild( addThis ); + } + /** + Add a child node as the first (left) child. + */ + XMLNode* InsertFirstChild( XMLNode* addThis ); + /** + Add a node after the specified child node. + */ + XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ); + + /** + Delete all the children of this node. + */ + void DeleteChildren(); + + /** + Delete a child of this node. + */ + void DeleteChild( XMLNode* node ); + + /** + Make a copy of this node, but not its children. + You may pass in a Document pointer that will be + the owner of the new Node. If the 'document' is + null, then the node returned will be allocated + from the current Document. (this->GetDocument()) + + Note: if called on a XMLDocument, this will return null. + */ + virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; + + /** + Test if 2 nodes are the same, but don't test children. + The 2 nodes do not need to be in the same Document. + + Note: if called on a XMLDocument, this will return false. + */ + virtual bool ShallowEqual( const XMLNode* compare ) const = 0; + + /** Accept a hierarchical visit of the nodes in the TinyXML DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the TiXmlVisitor interface. + + This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + TiXmlPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( XMLVisitor* visitor ) const = 0; + + // internal + virtual char* ParseDeep( char*, StrPair* ); + +protected: + XMLNode( XMLDocument* ); + virtual ~XMLNode(); + XMLNode( const XMLNode& ); // not supported + XMLNode& operator=( const XMLNode& ); // not supported + + XMLDocument* _document; + XMLNode* _parent; + mutable StrPair _value; + + XMLNode* _firstChild; + XMLNode* _lastChild; + + XMLNode* _prev; + XMLNode* _next; + +private: + MemPool* _memPool; + void Unlink( XMLNode* child ); +}; + + +/** XML text. + + Note that a text node can have child element nodes, for example: + @verbatim + This is bold + @endverbatim + + A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCDATA() and query it with CDATA(). +*/ +class XMLText : public XMLNode +{ + friend class XMLBase; + friend class XMLDocument; +public: + virtual bool Accept( XMLVisitor* visitor ) const; + + virtual XMLText* ToText() { + return this; + } + virtual const XMLText* ToText() const { + return this; + } + + /// Declare whether this should be CDATA or standard text. + void SetCData( bool isCData ) { + _isCData = isCData; + } + /// Returns true if this is a CDATA text element. + bool CData() const { + return _isCData; + } + + char* ParseDeep( char*, StrPair* endTag ); + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} + virtual ~XMLText() {} + XMLText( const XMLText& ); // not supported + XMLText& operator=( const XMLText& ); // not supported + +private: + bool _isCData; +}; + + +/** An XML Comment. */ +class XMLComment : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLComment* ToComment() { + return this; + } + virtual const XMLComment* ToComment() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + char* ParseDeep( char*, StrPair* endTag ); + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLComment( XMLDocument* doc ); + virtual ~XMLComment(); + XMLComment( const XMLComment& ); // not supported + XMLComment& operator=( const XMLComment& ); // not supported + +private: +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXML2 will happily read or write files without a declaration, + however. + + The text of the declaration isn't interpreted. It is parsed + and written as a string. +*/ +class XMLDeclaration : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLDeclaration* ToDeclaration() { + return this; + } + virtual const XMLDeclaration* ToDeclaration() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + char* ParseDeep( char*, StrPair* endTag ); + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLDeclaration( XMLDocument* doc ); + virtual ~XMLDeclaration(); + XMLDeclaration( const XMLDeclaration& ); // not supported + XMLDeclaration& operator=( const XMLDeclaration& ); // not supported +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into TiXmlUnknowns. +*/ +class XMLUnknown : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLUnknown* ToUnknown() { + return this; + } + virtual const XMLUnknown* ToUnknown() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + char* ParseDeep( char*, StrPair* endTag ); + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLUnknown( XMLDocument* doc ); + virtual ~XMLUnknown(); + XMLUnknown( const XMLUnknown& ); // not supported + XMLUnknown& operator=( const XMLUnknown& ); // not supported +}; + + +enum XMLError { + XML_NO_ERROR = 0, + XML_SUCCESS = 0, + + XML_NO_ATTRIBUTE, + XML_WRONG_ATTRIBUTE_TYPE, + + XML_ERROR_FILE_NOT_FOUND, + XML_ERROR_FILE_COULD_NOT_BE_OPENED, + XML_ERROR_FILE_READ_ERROR, + XML_ERROR_ELEMENT_MISMATCH, + XML_ERROR_PARSING_ELEMENT, + XML_ERROR_PARSING_ATTRIBUTE, + XML_ERROR_IDENTIFYING_TAG, + XML_ERROR_PARSING_TEXT, + XML_ERROR_PARSING_CDATA, + XML_ERROR_PARSING_COMMENT, + XML_ERROR_PARSING_DECLARATION, + XML_ERROR_PARSING_UNKNOWN, + XML_ERROR_EMPTY_DOCUMENT, + XML_ERROR_MISMATCHED_ELEMENT, + XML_ERROR_PARSING, + + XML_CAN_NOT_CONVERT_TEXT, + XML_NO_TEXT_NODE +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not XMLNodes. You may only query the + Next() attribute in a list. +*/ +class XMLAttribute +{ + friend class XMLElement; +public: + /// The name of the attribute. + const char* Name() const { + return _name.GetStr(); + } + /// The value of the attribute. + const char* Value() const { + return _value.GetStr(); + } + /// The next attribute in the list. + const XMLAttribute* Next() const { + return _next; + } + + /** IntAttribute interprets the attribute as an integer, and returns the value. + If the value isn't an integer, 0 will be returned. There is no error checking; + use QueryIntAttribute() if you need error checking. + */ + int IntValue() const { + int i=0; + QueryIntValue( &i ); + return i; + } + /// Query as an unsigned integer. See IntAttribute() + unsigned UnsignedValue() const { + unsigned i=0; + QueryUnsignedValue( &i ); + return i; + } + /// Query as a boolean. See IntAttribute() + bool BoolValue() const { + bool b=false; + QueryBoolValue( &b ); + return b; + } + /// Query as a double. See IntAttribute() + double DoubleValue() const { + double d=0; + QueryDoubleValue( &d ); + return d; + } + /// Query as a float. See IntAttribute() + float FloatValue() const { + float f=0; + QueryFloatValue( &f ); + return f; + } + + /** QueryIntAttribute interprets the attribute as an integer, and returns the value + in the provided paremeter. The function will return XML_NO_ERROR on success, + and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. + */ + XMLError QueryIntValue( int* value ) const; + /// See QueryIntAttribute + XMLError QueryUnsignedValue( unsigned int* value ) const; + /// See QueryIntAttribute + XMLError QueryBoolValue( bool* value ) const; + /// See QueryIntAttribute + XMLError QueryDoubleValue( double* value ) const; + /// See QueryIntAttribute + XMLError QueryFloatValue( float* value ) const; + + /// Set the attribute to a string value. + void SetAttribute( const char* value ); + /// Set the attribute to value. + void SetAttribute( int value ); + /// Set the attribute to value. + void SetAttribute( unsigned value ); + /// Set the attribute to value. + void SetAttribute( bool value ); + /// Set the attribute to value. + void SetAttribute( double value ); + /// Set the attribute to value. + void SetAttribute( float value ); + +private: + enum { BUF_SIZE = 200 }; + + XMLAttribute() : _next( 0 ) {} + virtual ~XMLAttribute() {} + + XMLAttribute( const XMLAttribute& ); // not supported + void operator=( const XMLAttribute& ); // not supported + void SetName( const char* name ); + + char* ParseDeep( char* p, bool processEntities ); + + mutable StrPair _name; + mutable StrPair _value; + XMLAttribute* _next; + MemPool* _memPool; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class XMLElement : public XMLNode +{ + friend class XMLBase; + friend class XMLDocument; +public: + /// Get the name of an element (which is the Value() of the node.) + const char* Name() const { + return Value(); + } + /// Set the name of the element. + void SetName( const char* str, bool staticMem=false ) { + SetValue( str, staticMem ); + } + + virtual XMLElement* ToElement() { + return this; + } + virtual const XMLElement* ToElement() const { + return this; + } + virtual bool Accept( XMLVisitor* visitor ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none + exists. For example: + + @verbatim + const char* value = ele->Attribute( "foo" ); + @endverbatim + + The 'value' parameter is normally null. However, if specified, + the attribute will only be returned if the 'name' and 'value' + match. This allow you to write code: + + @verbatim + if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar(); + @endverbatim + + rather than: + @verbatim + if ( ele->Attribute( "foo" ) ) { + if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar(); + } + @endverbatim + */ + const char* Attribute( const char* name, const char* value=0 ) const; + + /** Given an attribute name, IntAttribute() returns the value + of the attribute interpreted as an integer. 0 will be + returned if there is an error. For a method with error + checking, see QueryIntAttribute() + */ + int IntAttribute( const char* name ) const { + int i=0; + QueryIntAttribute( name, &i ); + return i; + } + /// See IntAttribute() + unsigned UnsignedAttribute( const char* name ) const { + unsigned i=0; + QueryUnsignedAttribute( name, &i ); + return i; + } + /// See IntAttribute() + bool BoolAttribute( const char* name ) const { + bool b=false; + QueryBoolAttribute( name, &b ); + return b; + } + /// See IntAttribute() + double DoubleAttribute( const char* name ) const { + double d=0; + QueryDoubleAttribute( name, &d ); + return d; + } + /// See IntAttribute() + float FloatAttribute( const char* name ) const { + float f=0; + QueryFloatAttribute( name, &f ); + return f; + } + + /** Given an attribute name, QueryIntAttribute() returns + XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion + can't be performed, or XML_NO_ATTRIBUTE if the attribute + doesn't exist. If successful, the result of the conversion + will be written to 'value'. If not successful, nothing will + be written to 'value'. This allows you to provide default + value: + + @verbatim + int value = 10; + QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 + @endverbatim + */ + XMLError QueryIntAttribute( const char* name, int* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryIntValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryUnsignedValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryBoolAttribute( const char* name, bool* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryBoolValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryDoubleAttribute( const char* name, double* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryDoubleValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryFloatAttribute( const char* name, float* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryFloatValue( value ); + } + + /// Sets the named attribute to value. + void SetAttribute( const char* name, const char* value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, int value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, unsigned value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, bool value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, double value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + + /** + Delete an attribute. + */ + void DeleteAttribute( const char* name ); + + /// Return the first attribute in the list. + const XMLAttribute* FirstAttribute() const { + return _rootAttribute; + } + /// Query a specific attribute in the list. + const XMLAttribute* FindAttribute( const char* name ) const; + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the TiXmlText child + and accessing it directly. + + If the first child of 'this' is a TiXmlText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + */ + const char* GetText() const; + + /** + Convenience method to query the value of a child text node. This is probably best + shown by example. Given you have a document is this form: + @verbatim + + 1 + 1.4 + + @endverbatim + + The QueryIntText() and similar functions provide a safe and easier way to get to the + "value" of x and y. + + @verbatim + int x = 0; + float y = 0; // types of x and y are contrived for example + const XMLElement* xElement = pointElement->FirstChildElement( "x" ); + const XMLElement* yElement = pointElement->FirstChildElement( "y" ); + xElement->QueryIntText( &x ); + yElement->QueryFloatText( &y ); + @endverbatim + + @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted + to the requested type, and XML_NO_TEXT_NODE if there is no child text to query. + + */ + XMLError QueryIntText( int* ival ) const; + /// See QueryIntText() + XMLError QueryUnsignedText( unsigned* uval ) const; + /// See QueryIntText() + XMLError QueryBoolText( bool* bval ) const; + /// See QueryIntText() + XMLError QueryDoubleText( double* dval ) const; + /// See QueryIntText() + XMLError QueryFloatText( float* fval ) const; + + // internal: + enum { + OPEN, // + CLOSED, // + CLOSING // + }; + int ClosingType() const { + return _closingType; + } + char* ParseDeep( char* p, StrPair* endTag ); + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +private: + XMLElement( XMLDocument* doc ); + virtual ~XMLElement(); + XMLElement( const XMLElement& ); // not supported + void operator=( const XMLElement& ); // not supported + + XMLAttribute* FindAttribute( const char* name ); + XMLAttribute* FindOrCreateAttribute( const char* name ); + //void LinkAttribute( XMLAttribute* attrib ); + char* ParseAttributes( char* p ); + + int _closingType; + // The attribute list is ordered; there is no 'lastAttribute' + // because the list needs to be scanned for dupes before adding + // a new attribute. + XMLAttribute* _rootAttribute; +}; + + +enum Whitespace { + PRESERVE_WHITESPACE, + COLLAPSE_WHITESPACE +}; + + +/** A Document binds together all the functionality. + It can be saved, loaded, and printed to the screen. + All Nodes are connected and allocated to a Document. + If the Document is deleted, all its Nodes are also deleted. +*/ +class XMLDocument : public XMLNode +{ + friend class XMLElement; +public: + /// constructor + XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE ); + ~XMLDocument(); + + virtual XMLDocument* ToDocument() { + return this; + } + virtual const XMLDocument* ToDocument() const { + return this; + } + + /** + Parse an XML file from a character string. + Returns XML_NO_ERROR (0) on success, or + an errorID. + + You may optionally pass in the 'nBytes', which is + the number of bytes which will be parsed. If not + specified, TinyXML will assume 'xml' points to a + null terminated string. + */ + XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) ); + + /** + Load an XML file from disk. + Returns XML_NO_ERROR (0) on success, or + an errorID. + */ + XMLError LoadFile( const char* filename ); + + /** + Load an XML file from disk. You are responsible + for providing and closing the FILE*. + + Returns XML_NO_ERROR (0) on success, or + an errorID. + */ + XMLError LoadFile( FILE* ); + + /** + Save the XML file to disk. + Returns XML_NO_ERROR (0) on success, or + an errorID. + */ + XMLError SaveFile( const char* filename, bool compact = false ); + + /** + Save the XML file to disk. You are responsible + for providing and closing the FILE*. + + Returns XML_NO_ERROR (0) on success, or + an errorID. + */ + XMLError SaveFile( FILE* fp, bool compact = false ); + + bool ProcessEntities() const { + return _processEntities; + } + Whitespace WhitespaceMode() const { + return _whitespace; + } + + /** + Returns true if this document has a leading Byte Order Mark of UTF8. + */ + bool HasBOM() const { + return _writeBOM; + } + /** Sets whether to write the BOM when writing the file. + */ + void SetBOM( bool useBOM ) { + _writeBOM = useBOM; + } + + /** Return the root element of DOM. Equivalent to FirstChildElement(). + To get the first node, use FirstChild(). + */ + XMLElement* RootElement() { + return FirstChildElement(); + } + const XMLElement* RootElement() const { + return FirstChildElement(); + } + + /** Print the Document. If the Printer is not provided, it will + print to stdout. If you provide Printer, this can print to a file: + @verbatim + XMLPrinter printer( fp ); + doc.Print( &printer ); + @endverbatim + + Or you can use a printer to print to memory: + @verbatim + XMLPrinter printer; + doc->Print( &printer ); + // printer.CStr() has a const char* to the XML + @endverbatim + */ + void Print( XMLPrinter* streamer=0 ); + virtual bool Accept( XMLVisitor* visitor ) const; + + /** + Create a new Element associated with + this Document. The memory for the Element + is managed by the Document. + */ + XMLElement* NewElement( const char* name ); + /** + Create a new Comment associated with + this Document. The memory for the Comment + is managed by the Document. + */ + XMLComment* NewComment( const char* comment ); + /** + Create a new Text associated with + this Document. The memory for the Text + is managed by the Document. + */ + XMLText* NewText( const char* text ); + /** + Create a new Declaration associated with + this Document. The memory for the object + is managed by the Document. + + If the 'text' param is null, the standard + declaration is used.: + @verbatim + + @endverbatim + */ + XMLDeclaration* NewDeclaration( const char* text=0 ); + /** + Create a new Unknown associated with + this Document. The memory forthe object + is managed by the Document. + */ + XMLUnknown* NewUnknown( const char* text ); + + /** + Delete a node associated with this document. + It will be unlinked from the DOM. + */ + void DeleteNode( XMLNode* node ) { + node->_parent->DeleteChild( node ); + } + + void SetError( XMLError error, const char* str1, const char* str2 ); + + /// Return true if there was an error parsing the document. + bool Error() const { + return _errorID != XML_NO_ERROR; + } + /// Return the errorID. + XMLError ErrorID() const { + return _errorID; + } + /// Return a possibly helpful diagnostic location or string. + const char* GetErrorStr1() const { + return _errorStr1; + } + /// Return a possibly helpful secondary diagnostic location or string. + const char* GetErrorStr2() const { + return _errorStr2; + } + /// If there is an error, print it to stdout. + void PrintError() const; + + // internal + char* Identify( char* p, XMLNode** node ); + + virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { + return 0; + } + virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const { + return false; + } + +private: + XMLDocument( const XMLDocument& ); // not supported + void operator=( const XMLDocument& ); // not supported + void InitDocument(); + + bool _writeBOM; + bool _processEntities; + XMLError _errorID; + Whitespace _whitespace; + const char* _errorStr1; + const char* _errorStr2; + char* _charBuffer; + + MemPoolT< sizeof(XMLElement) > _elementPool; + MemPoolT< sizeof(XMLAttribute) > _attributePool; + MemPoolT< sizeof(XMLText) > _textPool; + MemPoolT< sizeof(XMLComment) > _commentPool; +}; + + +/** + A XMLHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that XMLHandle is not part of the TinyXML + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + XMLElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + XMLElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + XMLElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + XMLElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. XMLHandle addresses the verbosity + of such code. A XMLHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + XMLHandle docHandle( &document ); + XMLElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild().NextSibling().ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + XMLHandle handleCopy = handle; + @endverbatim + + See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects. +*/ +class XMLHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + XMLHandle( XMLNode* node ) { + _node = node; + } + /// Create a handle from a node. + XMLHandle( XMLNode& node ) { + _node = &node; + } + /// Copy constructor + XMLHandle( const XMLHandle& ref ) { + _node = ref._node; + } + /// Assignment + XMLHandle& operator=( const XMLHandle& ref ) { + _node = ref._node; + return *this; + } + + /// Get the first child of this handle. + XMLHandle FirstChild() { + return XMLHandle( _node ? _node->FirstChild() : 0 ); + } + /// Get the first child element of this handle. + XMLHandle FirstChildElement( const char* value=0 ) { + return XMLHandle( _node ? _node->FirstChildElement( value ) : 0 ); + } + /// Get the last child of this handle. + XMLHandle LastChild() { + return XMLHandle( _node ? _node->LastChild() : 0 ); + } + /// Get the last child element of this handle. + XMLHandle LastChildElement( const char* _value=0 ) { + return XMLHandle( _node ? _node->LastChildElement( _value ) : 0 ); + } + /// Get the previous sibling of this handle. + XMLHandle PreviousSibling() { + return XMLHandle( _node ? _node->PreviousSibling() : 0 ); + } + /// Get the previous sibling element of this handle. + XMLHandle PreviousSiblingElement( const char* _value=0 ) { + return XMLHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 ); + } + /// Get the next sibling of this handle. + XMLHandle NextSibling() { + return XMLHandle( _node ? _node->NextSibling() : 0 ); + } + /// Get the next sibling element of this handle. + XMLHandle NextSiblingElement( const char* _value=0 ) { + return XMLHandle( _node ? _node->NextSiblingElement( _value ) : 0 ); + } + + /// Safe cast to XMLNode. This can return null. + XMLNode* ToNode() { + return _node; + } + /// Safe cast to XMLElement. This can return null. + XMLElement* ToElement() { + return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 ); + } + /// Safe cast to XMLText. This can return null. + XMLText* ToText() { + return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 ); + } + /// Safe cast to XMLUnknown. This can return null. + XMLUnknown* ToUnknown() { + return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 ); + } + /// Safe cast to XMLDeclaration. This can return null. + XMLDeclaration* ToDeclaration() { + return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 ); + } + +private: + XMLNode* _node; +}; + + +/** + A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the + same in all regards, except for the 'const' qualifiers. See XMLHandle for API. +*/ +class XMLConstHandle +{ +public: + XMLConstHandle( const XMLNode* node ) { + _node = node; + } + XMLConstHandle( const XMLNode& node ) { + _node = &node; + } + XMLConstHandle( const XMLConstHandle& ref ) { + _node = ref._node; + } + + XMLConstHandle& operator=( const XMLConstHandle& ref ) { + _node = ref._node; + return *this; + } + + const XMLConstHandle FirstChild() const { + return XMLConstHandle( _node ? _node->FirstChild() : 0 ); + } + const XMLConstHandle FirstChildElement( const char* value=0 ) const { + return XMLConstHandle( _node ? _node->FirstChildElement( value ) : 0 ); + } + const XMLConstHandle LastChild() const { + return XMLConstHandle( _node ? _node->LastChild() : 0 ); + } + const XMLConstHandle LastChildElement( const char* _value=0 ) const { + return XMLConstHandle( _node ? _node->LastChildElement( _value ) : 0 ); + } + const XMLConstHandle PreviousSibling() const { + return XMLConstHandle( _node ? _node->PreviousSibling() : 0 ); + } + const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const { + return XMLConstHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 ); + } + const XMLConstHandle NextSibling() const { + return XMLConstHandle( _node ? _node->NextSibling() : 0 ); + } + const XMLConstHandle NextSiblingElement( const char* _value=0 ) const { + return XMLConstHandle( _node ? _node->NextSiblingElement( _value ) : 0 ); + } + + + const XMLNode* ToNode() const { + return _node; + } + const XMLElement* ToElement() const { + return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 ); + } + const XMLText* ToText() const { + return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 ); + } + const XMLUnknown* ToUnknown() const { + return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 ); + } + const XMLDeclaration* ToDeclaration() const { + return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 ); + } + +private: + const XMLNode* _node; +}; + + +/** + Printing functionality. The XMLPrinter gives you more + options than the XMLDocument::Print() method. + + It can: + -# Print to memory. + -# Print to a file you provide. + -# Print XML without a XMLDocument. + + Print to Memory + + @verbatim + XMLPrinter printer; + doc->Print( &printer ); + SomeFunction( printer.CStr() ); + @endverbatim + + Print to a File + + You provide the file pointer. + @verbatim + XMLPrinter printer( fp ); + doc.Print( &printer ); + @endverbatim + + Print without a XMLDocument + + When loading, an XML parser is very useful. However, sometimes + when saving, it just gets in the way. The code is often set up + for streaming, and constructing the DOM is just overhead. + + The Printer supports the streaming case. The following code + prints out a trivially simple XML file without ever creating + an XML document. + + @verbatim + XMLPrinter printer( fp ); + printer.OpenElement( "foo" ); + printer.PushAttribute( "foo", "bar" ); + printer.CloseElement(); + @endverbatim +*/ +class XMLPrinter : public XMLVisitor +{ +public: + /** Construct the printer. If the FILE* is specified, + this will print to the FILE. Else it will print + to memory, and the result is available in CStr(). + If 'compact' is set to true, then output is created + with only required whitespace and newlines. + */ + XMLPrinter( FILE* file=0, bool compact = false ); + ~XMLPrinter() {} + + /** If streaming, write the BOM and declaration. */ + void PushHeader( bool writeBOM, bool writeDeclaration ); + /** If streaming, start writing an element. + The element must be closed with CloseElement() + */ + void OpenElement( const char* name ); + /// If streaming, add an attribute to an open element. + void PushAttribute( const char* name, const char* value ); + void PushAttribute( const char* name, int value ); + void PushAttribute( const char* name, unsigned value ); + void PushAttribute( const char* name, bool value ); + void PushAttribute( const char* name, double value ); + /// If streaming, close the Element. + void CloseElement(); + + /// Add a text node. + void PushText( const char* text, bool cdata=false ); + /// Add a text node from an integer. + void PushText( int value ); + /// Add a text node from an unsigned. + void PushText( unsigned value ); + /// Add a text node from a bool. + void PushText( bool value ); + /// Add a text node from a float. + void PushText( float value ); + /// Add a text node from a double. + void PushText( double value ); + + /// Add a comment + void PushComment( const char* comment ); + + void PushDeclaration( const char* value ); + void PushUnknown( const char* value ); + + virtual bool VisitEnter( const XMLDocument& /*doc*/ ); + virtual bool VisitExit( const XMLDocument& /*doc*/ ) { + return true; + } + + virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ); + virtual bool VisitExit( const XMLElement& element ); + + virtual bool Visit( const XMLText& text ); + virtual bool Visit( const XMLComment& comment ); + virtual bool Visit( const XMLDeclaration& declaration ); + virtual bool Visit( const XMLUnknown& unknown ); + + /** + If in print to memory mode, return a pointer to + the XML file in memory. + */ + const char* CStr() const { + return _buffer.Mem(); + } + /** + If in print to memory mode, return the size + of the XML file in memory. (Note the size returned + includes the terminating null.) + */ + int CStrSize() const { + return _buffer.Size(); + } + +private: + void SealElement(); + void PrintSpace( int depth ); + void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. + void Print( const char* format, ... ); + + bool _elementJustOpened; + bool _firstElement; + FILE* _fp; + int _depth; + int _textDepth; + bool _processEntities; + bool _compactMode; + + enum { + ENTITY_RANGE = 64, + BUF_SIZE = 200 + }; + bool _entityFlag[ENTITY_RANGE]; + bool _restrictedEntityFlag[ENTITY_RANGE]; + + DynArray< const char*, 10 > _stack; + DynArray< char, 20 > _buffer; +#ifdef _MSC_VER + DynArray< char, 20 > _accumulator; +#endif +}; + + +} // tinyxml2 + + +#endif // TINYXML2_INCLUDED diff --git a/ovr_sdk_win_23.0.0/LICENSE.txt b/ovr_sdk_win_23.0.0/LICENSE.txt new file mode 100644 index 0000000..6516fa3 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LICENSE.txt @@ -0,0 +1,3 @@ +Copyright © Facebook Technologies, LLC and its affiliates. All rights reserved. + +Your use of this SDK or tool is subject to the Oculus SDK License Agreement, available at https://developer.oculus.com/licenses/oculussdk/ \ No newline at end of file diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_CAPI_Util.h b/ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_CAPI_Util.h new file mode 100644 index 0000000..09b4a40 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_CAPI_Util.h @@ -0,0 +1,283 @@ +/********************************************************************************/ /** + \file OVR_CAPI_Util.h + \brief This header provides LibOVR utility function declarations + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + *************************************************************************************/ + +#ifndef OVR_CAPI_Util_h +#define OVR_CAPI_Util_h + +#include "OVR_CAPI.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// Enumerates modifications to the projection matrix based on the application's needs. +/// +/// \see ovrMatrix4f_Projection +/// +typedef enum ovrProjectionModifier_ { + /// Use for generating a default projection matrix that is: + /// * Right-handed. + /// * Near depth values stored in the depth buffer are smaller than far depth values. + /// * Both near and far are explicitly defined. + /// * With a clipping range that is (0 to w). + ovrProjection_None = 0x00, + + /// Enable if using left-handed transformations in your application. + ovrProjection_LeftHanded = 0x01, + + /// After the projection transform is applied, far values stored in the depth buffer will be less + /// than closer depth values. + /// NOTE: Enable only if the application is using a floating-point depth buffer for proper + /// precision. + ovrProjection_FarLessThanNear = 0x02, + + /// When this flag is used, the zfar value pushed into ovrMatrix4f_Projection() will be ignored + /// NOTE: Enable only if ovrProjection_FarLessThanNear is also enabled where the far clipping + /// plane will be pushed to infinity. + ovrProjection_FarClipAtInfinity = 0x04, + + /// Enable if the application is rendering with OpenGL and expects a projection matrix with a + /// clipping range of (-w to w). + /// Ignore this flag if your application already handles the conversion from D3D range (0 to w) to + /// OpenGL. + ovrProjection_ClipRangeOpenGL = 0x08, +} ovrProjectionModifier; + +/// Return values for ovr_Detect. +/// +/// \see ovr_Detect +/// +typedef struct OVR_ALIGNAS(8) ovrDetectResult_ { + /// Is ovrFalse when the Oculus Service is not running. + /// This means that the Oculus Service is either uninstalled or stopped. + /// IsOculusHMDConnected will be ovrFalse in this case. + /// Is ovrTrue when the Oculus Service is running. + /// This means that the Oculus Service is installed and running. + /// IsOculusHMDConnected will reflect the state of the HMD. + ovrBool IsOculusServiceRunning; + + /// Is ovrFalse when an Oculus HMD is not detected. + /// If the Oculus Service is not running, this will be ovrFalse. + /// Is ovrTrue when an Oculus HMD is detected. + /// This implies that the Oculus Service is also installed and running. + ovrBool IsOculusHMDConnected; + + OVR_UNUSED_STRUCT_PAD(pad0, 6) ///< \internal struct padding + +} ovrDetectResult; + +OVR_STATIC_ASSERT(sizeof(ovrDetectResult) == 8, "ovrDetectResult size mismatch"); + +/// Modes used to generate Touch Haptics from audio PCM buffer. +/// +typedef enum ovrHapticsGenMode_ { + /// Point sample original signal at Haptics frequency + ovrHapticsGenMode_PointSample, + ovrHapticsGenMode_Count +} ovrHapticsGenMode; + +/// Store audio PCM data (as 32b float samples) for an audio channel. +/// Note: needs to be released with ovr_ReleaseAudioChannelData to avoid memory leak. +/// +typedef struct ovrAudioChannelData_ { + /// Samples stored as floats [-1.0f, 1.0f]. + const float* Samples; + + /// Number of samples + int SamplesCount; + + /// Frequency (e.g. 44100) + int Frequency; +} ovrAudioChannelData; + +/// Store a full Haptics clip, which can be used as data source for multiple ovrHapticsBuffers. +/// +typedef struct ovrHapticsClip_ { + /// Samples stored in opaque format + const void* Samples; + + /// Number of samples + int SamplesCount; +} ovrHapticsClip; + +/// Detects Oculus Runtime and Device Status +/// +/// Checks for Oculus Runtime and Oculus HMD device status without loading the LibOVRRT +/// shared library. This may be called before ovr_Initialize() to help decide whether or +/// not to initialize LibOVR. +/// +/// \param[in] timeoutMilliseconds Specifies a timeout to wait for HMD to be attached or 0 to poll. +/// +/// \return Returns an ovrDetectResult object indicating the result of detection. +/// +/// \see ovrDetectResult +/// +OVR_PUBLIC_FUNCTION(ovrDetectResult) ovr_Detect(int timeoutMilliseconds); + +// On the Windows platform, +#ifdef _WIN32 +/// This is the Windows Named Event name that is used to check for HMD connected state. +#define OVR_HMD_CONNECTED_EVENT_NAME L"OculusHMDConnected" +#endif // _WIN32 + +/// Used to generate projection from ovrEyeDesc::Fov. +/// +/// \param[in] fov Specifies the ovrFovPort to use. +/// \param[in] znear Distance to near Z limit. +/// \param[in] zfar Distance to far Z limit. +/// \param[in] projectionModFlags A combination of the ovrProjectionModifier flags. +/// +/// \return Returns the calculated projection matrix. +/// +/// \see ovrProjectionModifier +/// +OVR_PUBLIC_FUNCTION(ovrMatrix4f) +ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, unsigned int projectionModFlags); + +/// Extracts the required data from the result of ovrMatrix4f_Projection. +/// +/// \param[in] projection Specifies the project matrix from which to +/// extract ovrTimewarpProjectionDesc. +/// \param[in] projectionModFlags A combination of the ovrProjectionModifier flags. +/// \return Returns the extracted ovrTimewarpProjectionDesc. +/// \see ovrTimewarpProjectionDesc +/// +OVR_PUBLIC_FUNCTION(ovrTimewarpProjectionDesc) +ovrTimewarpProjectionDesc_FromProjection(ovrMatrix4f projection, unsigned int projectionModFlags); + +/// Generates an orthographic sub-projection. +/// +/// Used for 2D rendering, Y is down. +/// +/// \param[in] projection The perspective matrix that the orthographic matrix is derived from. +/// \param[in] orthoScale Equal to 1.0f / pixelsPerTanAngleAtCenter. +/// \param[in] orthoDistance Equal to the distance from the camera in meters, such as 0.8m. +/// \param[in] HmdToEyeOffsetX Specifies the offset of the eye from the center. +/// +/// \return Returns the calculated projection matrix. +/// +OVR_PUBLIC_FUNCTION(ovrMatrix4f) +ovrMatrix4f_OrthoSubProjection( + ovrMatrix4f projection, + ovrVector2f orthoScale, + float orthoDistance, + float HmdToEyeOffsetX); + +/// Computes offset eye poses based on headPose returned by ovrTrackingState. +/// +/// \param[in] headPose Indicates the HMD position and orientation to use for the calculation. +/// \param[in] hmdToEyePose Can be ovrEyeRenderDesc.HmdToEyePose returned from +/// ovr_GetRenderDesc. For monoscopic rendering, use a position vector that is average +/// of the two position vectors for each eyes. +/// \param[out] outEyePoses If outEyePoses are used for rendering, they should be passed to +/// ovr_SubmitFrame in ovrLayerEyeFov::RenderPose or ovrLayerEyeFovDepth::RenderPose. +/// +#undef ovr_CalcEyePoses +OVR_PUBLIC_FUNCTION(void) +ovr_CalcEyePoses(ovrPosef headPose, const ovrVector3f hmdToEyeOffset[2], ovrPosef outEyePoses[2]); +OVR_PRIVATE_FUNCTION(void) +ovr_CalcEyePoses2(ovrPosef headPose, const ovrPosef HmdToEyePose[2], ovrPosef outEyePoses[2]); +#define ovr_CalcEyePoses ovr_CalcEyePoses2 + +/// Returns the predicted head pose in outHmdTrackingState and offset eye poses in outEyePoses. +/// +/// This is a thread-safe function where caller should increment frameIndex with every frame +/// and pass that index where applicable to functions called on the rendering thread. +/// Assuming outEyePoses are used for rendering, it should be passed as a part of ovrLayerEyeFov. +/// The caller does not need to worry about applying HmdToEyePose to the returned outEyePoses +/// variables. +/// +/// \param[in] hmd Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] frameIndex Specifies the targeted frame index, or 0 to refer to one frame after +/// the last time ovr_SubmitFrame was called. +/// \param[in] latencyMarker Specifies that this call is the point in time where +/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer +/// provides "SensorSampleTimestamp", that will override the value stored here. +/// \param[in] hmdToEyePose Can be ovrEyeRenderDesc.HmdToEyePose returned from +/// ovr_GetRenderDesc. For monoscopic rendering, use a position vector that is average +/// of the two position vectors for each eyes. +/// \param[out] outEyePoses The predicted eye poses. +/// \param[out] outSensorSampleTime The time when this function was called. May be NULL, in which +/// case it is ignored. +/// +#undef ovr_GetEyePoses +OVR_PUBLIC_FUNCTION(void) +ovr_GetEyePoses( + ovrSession session, + long long frameIndex, + ovrBool latencyMarker, + const ovrVector3f hmdToEyeOffset[2], + ovrPosef outEyePoses[2], + double* outSensorSampleTime); +OVR_PRIVATE_FUNCTION(void) +ovr_GetEyePoses2( + ovrSession session, + long long frameIndex, + ovrBool latencyMarker, + const ovrPosef HmdToEyePose[2], + ovrPosef outEyePoses[2], + double* outSensorSampleTime); +#define ovr_GetEyePoses ovr_GetEyePoses2 + +/// Tracking poses provided by the SDK come in a right-handed coordinate system. If an application +/// is passing in ovrProjection_LeftHanded into ovrMatrix4f_Projection, then it should also use +/// this function to flip the HMD tracking poses to be left-handed. +/// +/// While this utility function is intended to convert a left-handed ovrPosef into a right-handed +/// coordinate system, it will also work for converting right-handed to left-handed since the +/// flip operation is the same for both cases. +/// +/// \param[in] inPose that is right-handed +/// \param[out] outPose that is requested to be left-handed (can be the same pointer to inPose) +/// +OVR_PUBLIC_FUNCTION(void) ovrPosef_FlipHandedness(const ovrPosef* inPose, ovrPosef* outPose); + +/// Reads an audio channel from Wav (Waveform Audio File) data. +/// Input must be a byte buffer representing a valid Wav file. Audio samples from the specified +/// channel are read, +/// converted to float [-1.0f, 1.0f] and returned through ovrAudioChannelData. +/// +/// Supported formats: PCM 8b, 16b, 32b and IEEE float (little-endian only). +/// +/// \param[out] outAudioChannel output audio channel data. +/// \param[in] inputData a binary buffer representing a valid Wav file data. +/// \param[in] dataSizeInBytes size of the buffer in bytes. +/// \param[in] stereoChannelToUse audio channel index to extract (0 for mono). +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_ReadWavFromBuffer( + ovrAudioChannelData* outAudioChannel, + const void* inputData, + int dataSizeInBytes, + int stereoChannelToUse); + +/// Generates playable Touch Haptics data from an audio channel. +/// +/// \param[out] outHapticsClip generated Haptics clip. +/// \param[in] audioChannel input audio channel data. +/// \param[in] genMode mode used to convert and audio channel data to Haptics data. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GenHapticsFromAudioData( + ovrHapticsClip* outHapticsClip, + const ovrAudioChannelData* audioChannel, + ovrHapticsGenMode genMode); + +/// Releases memory allocated for ovrAudioChannelData. Must be called to avoid memory leak. +/// \param[in] audioChannel pointer to an audio channel +/// +OVR_PUBLIC_FUNCTION(void) ovr_ReleaseAudioChannelData(ovrAudioChannelData* audioChannel); + +/// Releases memory allocated for ovrHapticsClip. Must be called to avoid memory leak. +/// \param[in] hapticsClip pointer to a haptics clip +/// +OVR_PUBLIC_FUNCTION(void) ovr_ReleaseHapticsClip(ovrHapticsClip* hapticsClip); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // Header include guard diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_Math.h b/ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_Math.h new file mode 100644 index 0000000..a31911f --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_Math.h @@ -0,0 +1,4526 @@ +/********************************************************************************/ /** + \file OVR_Math.h + \brief Implementation of 3D primitives such as vectors, matrices. + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + *************************************************************************************/ + +#ifndef OVR_Math_h +#define OVR_Math_h + +// This file is intended to be independent of the rest of LibOVR and LibOVRKernel and thus +// has no #include dependencies on either. + +#include +#include +#include +#include +#include +#include + +#ifndef OVR_EXCLUDE_CAPI_FROM_MATH +#include "../OVR_CAPI.h" // Required due to a dependence on the ovrFovPort_ declaration. +#endif + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4127) // conditional expression is constant + +#if _MSC_VER < 1800 // isfinite was introduced in VS2013 +#define isfinite(x) _finite((x)) +#endif +#endif + +#if defined(_MSC_VER) +#define OVRMath_sprintf sprintf_s +#else +#define OVRMath_sprintf snprintf +#endif + +//------------------------------------------------------------------------------------- +// ***** OVR_MATH_ASSERT +// +// Independent debug break implementation for OVR_Math.h. + +#if !defined(OVR_MATH_DEBUG_BREAK) +#if defined(_DEBUG) +#if defined(_MSC_VER) +#define OVR_MATH_DEBUG_BREAK __debugbreak() +#else +#define OVR_MATH_DEBUG_BREAK __builtin_trap() +#endif +#else +#define OVR_MATH_DEBUG_BREAK ((void)0) +#endif +#endif + +//------------------------------------------------------------------------------------- +// ***** OVR_MATH_ASSERT +// +// Independent OVR_MATH_ASSERT implementation for OVR_Math.h. + +#if !defined(OVR_MATH_ASSERT) +#if defined(_DEBUG) +#define OVR_MATH_ASSERT(p) \ + if (!(p)) { \ + OVR_MATH_DEBUG_BREAK; \ + } +#else +#define OVR_MATH_ASSERT(p) ((void)0) +#endif +#endif + +//------------------------------------------------------------------------------------- +// ***** OVR_MATH_STATIC_ASSERT +// +// Independent OVR_MATH_ASSERT implementation for OVR_Math.h. + +#if !defined(OVR_MATH_STATIC_ASSERT) +#if defined(__cplusplus) && \ + ((defined(_MSC_VER) && (defined(_MSC_VER) >= 1600)) || defined(__GXX_EXPERIMENTAL_CXX0X__) || \ + (__cplusplus >= 201103L)) +#define OVR_MATH_STATIC_ASSERT static_assert +#else +#if !defined(OVR_SA_UNUSED) +#if defined(__GNUC__) || defined(__clang__) +#define OVR_SA_UNUSED __attribute__((unused)) +#else +#define OVR_SA_UNUSED +#endif +#define OVR_SA_PASTE(a, b) a##b +#define OVR_SA_HELP(a, b) OVR_SA_PASTE(a, b) +#endif + +#define OVR_MATH_STATIC_ASSERT(expression, msg) \ + typedef char OVR_SA_HELP(compileTimeAssert, __LINE__)[((expression) != 0) ? 1 : -1] OVR_SA_UNUSED +#endif +#endif + +namespace OVR { + +template +const T OVRMath_Min(const T a, const T b) { + return (a < b) ? a : b; +} + +template +const T OVRMath_Max(const T a, const T b) { + return (b < a) ? a : b; +} + +template +void OVRMath_Swap(T& a, T& b) { + T temp(a); + a = b; + b = temp; +} + +//------------------------------------------------------------------------------------- +// ***** Constants for 3D world/axis definitions. + +// Definitions of axes for coordinate and rotation conversions. +enum Axis { Axis_X = 0, Axis_Y = 1, Axis_Z = 2 }; + +// RotateDirection describes the rotation direction around an axis, interpreted as follows: +// CW - Clockwise while looking "down" from positive axis towards the origin. +// CCW - Counter-clockwise while looking from the positive axis towards the origin, +// which is in the negative axis direction. +// CCW is the default for the RHS coordinate system. Oculus standard RHS coordinate +// system defines Y up, X right, and Z back (pointing out from the screen). In this +// system Rotate_CCW around Z will specifies counter-clockwise rotation in XY plane. +enum RotateDirection { Rotate_CCW = 1, Rotate_CW = -1 }; + +// Constants for right handed and left handed coordinate systems +enum HandedSystem { Handed_R = 1, Handed_L = -1 }; + +// AxisDirection describes which way the coordinate axis points. Used by WorldAxes. +enum AxisDirection { + Axis_Up = 2, + Axis_Down = -2, + Axis_Right = 1, + Axis_Left = -1, + Axis_In = 3, + Axis_Out = -3 +}; + +struct WorldAxes { + AxisDirection XAxis, YAxis, ZAxis; + + WorldAxes(AxisDirection x, AxisDirection y, AxisDirection z) : XAxis(x), YAxis(y), ZAxis(z) { + OVR_MATH_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x)); + } +}; + +} // namespace OVR + +//------------------------------------------------------------------------------------// +// ***** C Compatibility Types + +// These declarations are used to support conversion between C types used in +// LibOVR C interfaces and their C++ versions. As an example, they allow passing +// Vector3f into a function that expects ovrVector3f. + +typedef struct ovrQuatf_ ovrQuatf; +typedef struct ovrQuatd_ ovrQuatd; +typedef struct ovrSizei_ ovrSizei; +typedef struct ovrSizef_ ovrSizef; +typedef struct ovrSized_ ovrSized; +typedef struct ovrRecti_ ovrRecti; +typedef struct ovrVector2i_ ovrVector2i; +typedef struct ovrVector2f_ ovrVector2f; +typedef struct ovrVector2d_ ovrVector2d; +typedef struct ovrVector3f_ ovrVector3f; +typedef struct ovrVector3d_ ovrVector3d; +typedef struct ovrVector4f_ ovrVector4f; +typedef struct ovrVector4d_ ovrVector4d; +typedef struct ovrMatrix2f_ ovrMatrix2f; +typedef struct ovrMatrix2d_ ovrMatrix2d; +typedef struct ovrMatrix3f_ ovrMatrix3f; +typedef struct ovrMatrix3d_ ovrMatrix3d; +typedef struct ovrMatrix4f_ ovrMatrix4f; +typedef struct ovrMatrix4d_ ovrMatrix4d; +typedef struct ovrPosef_ ovrPosef; +typedef struct ovrPosed_ ovrPosed; +typedef struct ovrPoseStatef_ ovrPoseStatef; +typedef struct ovrPoseStated_ ovrPoseStated; +typedef struct ovrFovPort_ ovrFovPort; + +namespace OVR { + +// Forward-declare our templates. +template +class Quat; +template +class Size; +template +class Rect; +template +class Vector2; +template +class Vector3; +template +class Vector4; +template +class Matrix2; +template +class Matrix3; +template +class Matrix4; +template +class Pose; +template +class PoseState; +struct FovPort; + +// CompatibleTypes::Type is used to lookup a compatible C-version of a C++ class. +template +struct CompatibleTypes { + // Declaration here seems necessary for MSVC; specializations are + // used instead. + typedef struct { + } Type; +}; + +// Specializations providing CompatibleTypes::Type value. +template <> +struct CompatibleTypes> { + typedef ovrQuatf Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrQuatd Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrMatrix2f Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrMatrix2d Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrMatrix3f Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrMatrix3d Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrMatrix4f Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrMatrix4d Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrSizei Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrSizef Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrSized Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrRecti Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrVector2i Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrVector2f Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrVector2d Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrVector3f Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrVector3d Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrVector4f Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrVector4d Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrPosef Type; +}; +template <> +struct CompatibleTypes> { + typedef ovrPosed Type; +}; +template <> +struct CompatibleTypes { + typedef ovrFovPort Type; +}; + +//------------------------------------------------------------------------------------// +// ***** Math +// +// Math class contains constants and functions. This class is a template specialized +// per type, with Math and Math being distinct. +template +class Math { + public: + // By default, support explicit conversion to float. This allows Vector2 to + // compile, for example. + typedef float OtherFloatType; + + static int Tolerance() { + return 0; + } // Default value so integer types compile +}; + +//------------------------------------------------------------------------------------// +// ***** double constants +#define MATH_DOUBLE_PI 3.14159265358979323846 +#define MATH_DOUBLE_TWOPI (2 * MATH_DOUBLE_PI) +#define MATH_DOUBLE_PIOVER2 (0.5 * MATH_DOUBLE_PI) +#define MATH_DOUBLE_PIOVER4 (0.25 * MATH_DOUBLE_PI) +#define MATH_FLOAT_MAXVALUE (FLT_MAX) + +#define MATH_DOUBLE_RADTODEGREEFACTOR (360.0 / MATH_DOUBLE_TWOPI) +#define MATH_DOUBLE_DEGREETORADFACTOR (MATH_DOUBLE_TWOPI / 360.0) + +#define MATH_DOUBLE_E 2.71828182845904523536 +#define MATH_DOUBLE_LOG2E 1.44269504088896340736 +#define MATH_DOUBLE_LOG10E 0.434294481903251827651 +#define MATH_DOUBLE_LN2 0.693147180559945309417 +#define MATH_DOUBLE_LN10 2.30258509299404568402 + +#define MATH_DOUBLE_SQRT2 1.41421356237309504880 +#define MATH_DOUBLE_SQRT1_2 0.707106781186547524401 + +#define MATH_DOUBLE_TOLERANCE \ + 1e-12 // a default number for value equality tolerance: about 4500*Epsilon; +#define MATH_DOUBLE_SINGULARITYRADIUS \ + 1e-12 // about 1-cos(.0001 degree), for gimbal lock numerical problems + +#define MATH_DOUBLE_HUGENUMBER 1.3407807929942596e+154 +#define MATH_DOUBLE_SMALLESTNONDENORMAL 2.2250738585072014e-308 + +//------------------------------------------------------------------------------------// +// ***** float constants +#define MATH_FLOAT_PI float(MATH_DOUBLE_PI) +#define MATH_FLOAT_TWOPI float(MATH_DOUBLE_TWOPI) +#define MATH_FLOAT_PIOVER2 float(MATH_DOUBLE_PIOVER2) +#define MATH_FLOAT_PIOVER4 float(MATH_DOUBLE_PIOVER4) + +#define MATH_FLOAT_RADTODEGREEFACTOR float(MATH_DOUBLE_RADTODEGREEFACTOR) +#define MATH_FLOAT_DEGREETORADFACTOR float(MATH_DOUBLE_DEGREETORADFACTOR) + +#define MATH_FLOAT_E float(MATH_DOUBLE_E) +#define MATH_FLOAT_LOG2E float(MATH_DOUBLE_LOG2E) +#define MATH_FLOAT_LOG10E float(MATH_DOUBLE_LOG10E) +#define MATH_FLOAT_LN2 float(MATH_DOUBLE_LN2) +#define MATH_FLOAT_LN10 float(MATH_DOUBLE_LN10) + +#define MATH_FLOAT_SQRT2 float(MATH_DOUBLE_SQRT2) +#define MATH_FLOAT_SQRT1_2 float(MATH_DOUBLE_SQRT1_2) + +#define MATH_FLOAT_TOLERANCE \ + 1e-5f // a default number for value equality tolerance: 1e-5, about 84*EPSILON; +#define MATH_FLOAT_SINGULARITYRADIUS \ + 1e-7f // about 1-cos(.025 degree), for gimbal lock numerical problems + +#define MATH_FLOAT_HUGENUMBER 1.8446742974197924e+019f +#define MATH_FLOAT_SMALLESTNONDENORMAL 1.1754943508222875e-038f + +// Single-precision Math constants class. +template <> +class Math { + public: + typedef double OtherFloatType; + + static inline float MaxValue() { + return FLT_MAX; + }; + static inline float Tolerance() { + return MATH_FLOAT_TOLERANCE; + }; // a default number for value equality tolerance + static inline float SingularityRadius() { + return MATH_FLOAT_SINGULARITYRADIUS; + }; // for gimbal lock numerical problems + static inline float HugeNumber() { + return MATH_FLOAT_HUGENUMBER; + } + static inline float SmallestNonDenormal() { + return MATH_FLOAT_SMALLESTNONDENORMAL; + } +}; + +// Double-precision Math constants class +template <> +class Math { + public: + typedef float OtherFloatType; + + static inline double Tolerance() { + return MATH_DOUBLE_TOLERANCE; + }; // a default number for value equality tolerance + static inline double SingularityRadius() { + return MATH_DOUBLE_SINGULARITYRADIUS; + }; // for gimbal lock numerical problems + static inline double HugeNumber() { + return MATH_DOUBLE_HUGENUMBER; + } + static inline double SmallestNonDenormal() { + return MATH_DOUBLE_SMALLESTNONDENORMAL; + } +}; + +typedef Math Mathf; +typedef Math Mathd; + +// Conversion functions between degrees and radians +// (non-templated to ensure passing int arguments causes warning) +inline float RadToDegree(float rad) { + return rad * MATH_FLOAT_RADTODEGREEFACTOR; +} +inline double RadToDegree(double rad) { + return rad * MATH_DOUBLE_RADTODEGREEFACTOR; +} + +inline float DegreeToRad(float deg) { + return deg * MATH_FLOAT_DEGREETORADFACTOR; +} +inline double DegreeToRad(double deg) { + return deg * MATH_DOUBLE_DEGREETORADFACTOR; +} + +// Square function +template +inline T Sqr(T x) { + return x * x; +} + +// MERGE_MOBILE_SDK +// Safe reciprocal square root. +template +T RcpSqrt(const T f) { + return (f >= Math::SmallestNonDenormal()) ? static_cast(1.0 / sqrt(f)) + : Math::HugeNumber(); +} +// MERGE_MOBILE_SDK + +// Sign: returns 0 if x == 0, -1 if x < 0, and 1 if x > 0 +template +inline T Sign(T x) { + return (x != T(0)) ? (x < T(0) ? T(-1) : T(1)) : T(0); +} + +// Numerically stable acos function +inline float Acos(float x) { + return (x > 1.0f) ? 0.0f : (x < -1.0f) ? MATH_FLOAT_PI : acosf(x); +} +inline double Acos(double x) { + return (x > 1.0) ? 0.0 : (x < -1.0) ? MATH_DOUBLE_PI : acos(x); +} + +// Numerically stable asin function +inline float Asin(float x) { + return (x > 1.0f) ? MATH_FLOAT_PIOVER2 : (x < -1.0f) ? -MATH_FLOAT_PIOVER2 : asinf(x); +} +inline double Asin(double x) { + return (x > 1.0) ? MATH_DOUBLE_PIOVER2 : (x < -1.0) ? -MATH_DOUBLE_PIOVER2 : asin(x); +} + +template +class Quat; + +//------------------------------------------------------------------------------------- +// ***** Vector2<> + +// Vector2f (Vector2d) represents a 2-dimensional vector or point in space, +// consisting of coordinates x and y + +template +class Vector2 { + public: + typedef T ElementType; + static const size_t ElementCount = 2; + + T x, y; + + Vector2() : x(0), y(0) {} + Vector2(T x_, T y_) : x(x_), y(y_) {} + explicit Vector2(T s) : x(s), y(s) {} + explicit Vector2(const Vector2::OtherFloatType>& src) + : x((T)src.x), y((T)src.y) {} + + static Vector2 Zero() { + return Vector2(0, 0); + } + + // C-interop support. + typedef typename CompatibleTypes>::Type CompatibleType; + + Vector2(const CompatibleType& s) : x(s.x), y(s.y) {} + + operator const CompatibleType&() const { + OVR_MATH_STATIC_ASSERT( + sizeof(Vector2) == sizeof(CompatibleType), "sizeof(Vector2) failure"); + return reinterpret_cast(*this); + } + + bool operator==(const Vector2& b) const { + return x == b.x && y == b.y; + } + bool operator!=(const Vector2& b) const { + return x != b.x || y != b.y; + } + + Vector2 operator+(const Vector2& b) const { + return Vector2(x + b.x, y + b.y); + } + Vector2& operator+=(const Vector2& b) { + x += b.x; + y += b.y; + return *this; + } + Vector2 operator-(const Vector2& b) const { + return Vector2(x - b.x, y - b.y); + } + Vector2& operator-=(const Vector2& b) { + x -= b.x; + y -= b.y; + return *this; + } + Vector2 operator-() const { + return Vector2(-x, -y); + } + + // Scalar multiplication/division scales vector. + Vector2 operator*(T s) const { + return Vector2(x * s, y * s); + } + Vector2& operator*=(T s) { + x *= s; + y *= s; + return *this; + } + + Vector2 operator/(T s) const { + T rcp = T(1) / s; + return Vector2(x * rcp, y * rcp); + } + Vector2& operator/=(T s) { + T rcp = T(1) / s; + x *= rcp; + y *= rcp; + return *this; + } + + static Vector2 Min(const Vector2& a, const Vector2& b) { + return Vector2((a.x < b.x) ? a.x : b.x, (a.y < b.y) ? a.y : b.y); + } + static Vector2 Max(const Vector2& a, const Vector2& b) { + return Vector2((a.x > b.x) ? a.x : b.x, (a.y > b.y) ? a.y : b.y); + } + + Vector2 Clamped(T maxMag) const { + T magSquared = LengthSq(); + if (magSquared <= Sqr(maxMag)) + return *this; + else + return *this * (maxMag / sqrt(magSquared)); + } + + // Compare two vectors for equality with tolerance. Returns true if vectors match within + // tolerance. + bool IsEqual(const Vector2& b, T tolerance = Math::Tolerance()) const { + return (fabs(b.x - x) <= tolerance) && (fabs(b.y - y) <= tolerance); + } + bool Compare(const Vector2& b, T tolerance = Math::Tolerance()) const { + return IsEqual(b, tolerance); + } + + // Access element by index + T& operator[](int idx) { + OVR_MATH_ASSERT(0 <= idx && idx < 2); + return *(&x + idx); + } + const T& operator[](int idx) const { + OVR_MATH_ASSERT(0 <= idx && idx < 2); + return *(&x + idx); + } + + // Entry-wise product of two vectors + Vector2 EntrywiseMultiply(const Vector2& b) const { + return Vector2(x * b.x, y * b.y); + } + + // Multiply and divide operators do entry-wise math. Used Dot() for dot product. + Vector2 operator*(const Vector2& b) const { + return Vector2(x * b.x, y * b.y); + } + Vector2 operator/(const Vector2& b) const { + return Vector2(x / b.x, y / b.y); + } + + // Dot product + // Used to calculate angle q between two vectors among other things, + // as (A dot B) = |a||b|cos(q). + T Dot(const Vector2& b) const { + return x * b.x + y * b.y; + } + + // Returns the angle from this vector to b, in radians. + T Angle(const Vector2& b) const { + T div = LengthSq() * b.LengthSq(); + OVR_MATH_ASSERT(div != T(0)); + T result = Acos((this->Dot(b)) / sqrt(div)); + return result; + } + + // Return Length of the vector squared. + T LengthSq() const { + return (x * x + y * y); + } + + // Return vector length. + T Length() const { + return sqrt(LengthSq()); + } + + // Returns squared distance between two points represented by vectors. + T DistanceSq(const Vector2& b) const { + return (*this - b).LengthSq(); + } + + // Returns distance between two points represented by vectors. + T Distance(const Vector2& b) const { + return (*this - b).Length(); + } + + // Determine if this a unit vector. + bool IsNormalized() const { + return fabs(LengthSq() - T(1)) < Math::Tolerance(); + } + + // Normalize, convention vector length to 1. + void Normalize() { + T s = Length(); + if (s != T(0)) + s = T(1) / s; + *this *= s; + } + + // Returns normalized (unit) version of the vector without modifying itself. + Vector2 Normalized() const { + T s = Length(); + if (s != T(0)) + s = T(1) / s; + return *this * s; + } + + // Linearly interpolates from this vector to another. + // Factor should be between 0.0 and 1.0, with 0 giving full value to this. + Vector2 Lerp(const Vector2& b, T f) const { + return *this * (T(1) - f) + b * f; + } + + // Projects this vector onto the argument; in other words, + // A.Project(B) returns projection of vector A onto B. + Vector2 ProjectTo(const Vector2& b) const { + T l2 = b.LengthSq(); + OVR_MATH_ASSERT(l2 != T(0)); + return b * (Dot(b) / l2); + } + + // returns true if vector b is clockwise from this vector + bool IsClockwise(const Vector2& b) const { + return (x * b.y - y * b.x) < 0; + } +}; + +typedef Vector2 Vector2f; +typedef Vector2 Vector2d; +typedef Vector2 Vector2i; + +typedef Vector2 Point2f; +typedef Vector2 Point2d; +typedef Vector2 Point2i; + +//------------------------------------------------------------------------------------- +// ***** Vector3<> - 3D vector of {x, y, z} + +// +// Vector3f (Vector3d) represents a 3-dimensional vector or point in space, +// consisting of coordinates x, y and z. + +template +class Vector3 { + public: + typedef T ElementType; + static const size_t ElementCount = 3; + + T x, y, z; + + // FIXME: default initialization of a vector class can be very expensive in a full-blown + // application. A few hundred thousand vector constructions is not unlikely and can add + // up to milliseconds of time on processors like the PS3 PPU. + Vector3() : x(0), y(0), z(0) {} + Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) {} + explicit Vector3(T s) : x(s), y(s), z(s) {} + explicit Vector3(const Vector3::OtherFloatType>& src) + : x((T)src.x), y((T)src.y), z((T)src.z) {} + + static Vector3 Zero() { + return Vector3(0, 0, 0); + } + + // C-interop support. + typedef typename CompatibleTypes>::Type CompatibleType; + + Vector3(const CompatibleType& s) : x(s.x), y(s.y), z(s.z) {} + + operator const CompatibleType&() const { + OVR_MATH_STATIC_ASSERT( + sizeof(Vector3) == sizeof(CompatibleType), "sizeof(Vector3) failure"); + return reinterpret_cast(*this); + } + + bool operator==(const Vector3& b) const { + return x == b.x && y == b.y && z == b.z; + } + bool operator!=(const Vector3& b) const { + return x != b.x || y != b.y || z != b.z; + } + + Vector3 operator+(const Vector3& b) const { + return Vector3(x + b.x, y + b.y, z + b.z); + } + Vector3& operator+=(const Vector3& b) { + x += b.x; + y += b.y; + z += b.z; + return *this; + } + Vector3 operator-(const Vector3& b) const { + return Vector3(x - b.x, y - b.y, z - b.z); + } + Vector3& operator-=(const Vector3& b) { + x -= b.x; + y -= b.y; + z -= b.z; + return *this; + } + Vector3 operator-() const { + return Vector3(-x, -y, -z); + } + + // Scalar multiplication/division scales vector. + Vector3 operator*(T s) const { + return Vector3(x * s, y * s, z * s); + } + Vector3& operator*=(T s) { + x *= s; + y *= s; + z *= s; + return *this; + } + + Vector3 operator/(T s) const { + T rcp = T(1) / s; + return Vector3(x * rcp, y * rcp, z * rcp); + } + Vector3& operator/=(T s) { + T rcp = T(1) / s; + x *= rcp; + y *= rcp; + z *= rcp; + return *this; + } + + static Vector3 Min(const Vector3& a, const Vector3& b) { + return Vector3((a.x < b.x) ? a.x : b.x, (a.y < b.y) ? a.y : b.y, (a.z < b.z) ? a.z : b.z); + } + static Vector3 Max(const Vector3& a, const Vector3& b) { + return Vector3((a.x > b.x) ? a.x : b.x, (a.y > b.y) ? a.y : b.y, (a.z > b.z) ? a.z : b.z); + } + + Vector3 Clamped(T maxMag) const { + T magSquared = LengthSq(); + if (magSquared <= Sqr(maxMag)) + return *this; + else + return *this * (maxMag / sqrt(magSquared)); + } + + // Compare two vectors for equality with tolerance. Returns true if vectors match within + // tolerance. + bool IsEqual(const Vector3& b, T tolerance = Math::Tolerance()) const { + return (fabs(b.x - x) <= tolerance) && (fabs(b.y - y) <= tolerance) && + (fabs(b.z - z) <= tolerance); + } + bool Compare(const Vector3& b, T tolerance = Math::Tolerance()) const { + return IsEqual(b, tolerance); + } + + T& operator[](int idx) { + OVR_MATH_ASSERT(0 <= idx && idx < 3); + return *(&x + idx); + } + + const T& operator[](int idx) const { + OVR_MATH_ASSERT(0 <= idx && idx < 3); + return *(&x + idx); + } + + // Entrywise product of two vectors + Vector3 EntrywiseMultiply(const Vector3& b) const { + return Vector3(x * b.x, y * b.y, z * b.z); + } + + // Multiply and divide operators do entry-wise math + Vector3 operator*(const Vector3& b) const { + return Vector3(x * b.x, y * b.y, z * b.z); + } + + Vector3 operator/(const Vector3& b) const { + return Vector3(x / b.x, y / b.y, z / b.z); + } + + // Dot product + // Used to calculate angle q between two vectors among other things, + // as (A dot B) = |a||b|cos(q). + T Dot(const Vector3& b) const { + return x * b.x + y * b.y + z * b.z; + } + + // Compute cross product, which generates a normal vector. + // Direction vector can be determined by right-hand rule: Pointing index finder in + // direction a and middle finger in direction b, thumb will point in a.Cross(b). + Vector3 Cross(const Vector3& b) const { + return Vector3(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); + } + + // Returns the angle from this vector to b, in radians. + T Angle(const Vector3& b) const { + T div = LengthSq() * b.LengthSq(); + OVR_MATH_ASSERT(div != T(0)); + T result = Acos((this->Dot(b)) / sqrt(div)); + return result; + } + + // Return Length of the vector squared. + T LengthSq() const { + return (x * x + y * y + z * z); + } + + // Return vector length. + T Length() const { + return (T)sqrt(LengthSq()); + } + + // Returns squared distance between two points represented by vectors. + T DistanceSq(Vector3 const& b) const { + return (*this - b).LengthSq(); + } + + // Returns distance between two points represented by vectors. + T Distance(Vector3 const& b) const { + return (*this - b).Length(); + } + + bool IsNormalized() const { + return fabs(LengthSq() - T(1)) < Math::Tolerance(); + } + + // Normalize, convention vector length to 1. + void Normalize() { + T s = Length(); + if (s != T(0)) + s = T(1) / s; + *this *= s; + } + + // Returns normalized (unit) version of the vector without modifying itself. + Vector3 Normalized() const { + T s = Length(); + if (s != T(0)) + s = T(1) / s; + return *this * s; + } + + // Linearly interpolates from this vector to another. + // Factor should be between 0.0 and 1.0, with 0 giving full value to this. + Vector3 Lerp(const Vector3& b, T f) const { + return *this * (T(1) - f) + b * f; + } + + // Projects this vector onto the argument; in other words, + // A.Project(B) returns projection of vector A onto B. + Vector3 ProjectTo(const Vector3& b) const { + T l2 = b.LengthSq(); + OVR_MATH_ASSERT(l2 != T(0)); + return b * (Dot(b) / l2); + } + + // Projects this vector onto a plane defined by a normal vector + Vector3 ProjectToPlane(const Vector3& normal) const { + return *this - this->ProjectTo(normal); + } + + bool IsNan() const { + return !isfinite(x + y + z); + } + bool IsFinite() const { + return isfinite(x + y + z); + } +}; + +typedef Vector3 Vector3f; +typedef Vector3 Vector3d; +typedef Vector3 Vector3i; + +OVR_MATH_STATIC_ASSERT((sizeof(Vector3f) == 3 * sizeof(float)), "sizeof(Vector3f) failure"); +OVR_MATH_STATIC_ASSERT((sizeof(Vector3d) == 3 * sizeof(double)), "sizeof(Vector3d) failure"); +OVR_MATH_STATIC_ASSERT((sizeof(Vector3i) == 3 * sizeof(int32_t)), "sizeof(Vector3i) failure"); + +typedef Vector3 Point3f; +typedef Vector3 Point3d; +typedef Vector3 Point3i; + +//------------------------------------------------------------------------------------- +// ***** Vector4<> - 4D vector of {x, y, z, w} + +// +// Vector4f (Vector4d) represents a 3-dimensional vector or point in space, +// consisting of coordinates x, y, z and w. + +template +class Vector4 { + public: + typedef T ElementType; + static const size_t ElementCount = 4; + + T x, y, z, w; + + // FIXME: default initialization of a vector class can be very expensive in a full-blown + // application. A few hundred thousand vector constructions is not unlikely and can add + // up to milliseconds of time on processors like the PS3 PPU. + Vector4() : x(0), y(0), z(0), w(0) {} + Vector4(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) {} + explicit Vector4(T s) : x(s), y(s), z(s), w(s) {} + explicit Vector4(const Vector3& v, const T w_ = T(1)) : x(v.x), y(v.y), z(v.z), w(w_) {} + explicit Vector4(const Vector4::OtherFloatType>& src) + : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) {} + + static Vector4 Zero() { + return Vector4(0, 0, 0, 0); + } + + // C-interop support. + typedef typename CompatibleTypes>::Type CompatibleType; + + Vector4(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) {} + + operator const CompatibleType&() const { + OVR_MATH_STATIC_ASSERT( + sizeof(Vector4) == sizeof(CompatibleType), "sizeof(Vector4) failure"); + return reinterpret_cast(*this); + } + + Vector4& operator=(const Vector3& other) { + x = other.x; + y = other.y; + z = other.z; + w = 1; + return *this; + } + bool operator==(const Vector4& b) const { + return x == b.x && y == b.y && z == b.z && w == b.w; + } + bool operator!=(const Vector4& b) const { + return x != b.x || y != b.y || z != b.z || w != b.w; + } + + Vector4 operator+(const Vector4& b) const { + return Vector4(x + b.x, y + b.y, z + b.z, w + b.w); + } + Vector4& operator+=(const Vector4& b) { + x += b.x; + y += b.y; + z += b.z; + w += b.w; + return *this; + } + Vector4 operator-(const Vector4& b) const { + return Vector4(x - b.x, y - b.y, z - b.z, w - b.w); + } + Vector4& operator-=(const Vector4& b) { + x -= b.x; + y -= b.y; + z -= b.z; + w -= b.w; + return *this; + } + Vector4 operator-() const { + return Vector4(-x, -y, -z, -w); + } + + // Scalar multiplication/division scales vector. + Vector4 operator*(T s) const { + return Vector4(x * s, y * s, z * s, w * s); + } + Vector4& operator*=(T s) { + x *= s; + y *= s; + z *= s; + w *= s; + return *this; + } + + Vector4 operator/(T s) const { + T rcp = T(1) / s; + return Vector4(x * rcp, y * rcp, z * rcp, w * rcp); + } + Vector4& operator/=(T s) { + T rcp = T(1) / s; + x *= rcp; + y *= rcp; + z *= rcp; + w *= rcp; + return *this; + } + + static Vector4 Min(const Vector4& a, const Vector4& b) { + return Vector4( + (a.x < b.x) ? a.x : b.x, + (a.y < b.y) ? a.y : b.y, + (a.z < b.z) ? a.z : b.z, + (a.w < b.w) ? a.w : b.w); + } + static Vector4 Max(const Vector4& a, const Vector4& b) { + return Vector4( + (a.x > b.x) ? a.x : b.x, + (a.y > b.y) ? a.y : b.y, + (a.z > b.z) ? a.z : b.z, + (a.w > b.w) ? a.w : b.w); + } + + Vector4 Clamped(T maxMag) const { + T magSquared = LengthSq(); + if (magSquared <= Sqr(maxMag)) + return *this; + else + return *this * (maxMag / sqrt(magSquared)); + } + + // Compare two vectors for equality with tolerance. Returns true if vectors match within + // tolerance. + bool IsEqual(const Vector4& b, T tolerance = Math::Tolerance()) const { + return (fabs(b.x - x) <= tolerance) && (fabs(b.y - y) <= tolerance) && + (fabs(b.z - z) <= tolerance) && (fabs(b.w - w) <= tolerance); + } + bool Compare(const Vector4& b, T tolerance = Math::Tolerance()) const { + return IsEqual(b, tolerance); + } + + T& operator[](int idx) { + OVR_MATH_ASSERT(0 <= idx && idx < 4); + return *(&x + idx); + } + + const T& operator[](int idx) const { + OVR_MATH_ASSERT(0 <= idx && idx < 4); + return *(&x + idx); + } + + // Entry wise product of two vectors + Vector4 EntrywiseMultiply(const Vector4& b) const { + return Vector4(x * b.x, y * b.y, z * b.z, w * b.w); + } + + // Multiply and divide operators do entry-wise math + Vector4 operator*(const Vector4& b) const { + return Vector4(x * b.x, y * b.y, z * b.z, w * b.w); + } + + Vector4 operator/(const Vector4& b) const { + return Vector4(x / b.x, y / b.y, z / b.z, w / b.w); + } + + // Dot product + T Dot(const Vector4& b) const { + return x * b.x + y * b.y + z * b.z + w * b.w; + } + + // Return Length of the vector squared. + T LengthSq() const { + return (x * x + y * y + z * z + w * w); + } + + // Return vector length. + T Length() const { + return sqrt(LengthSq()); + } + + bool IsNormalized() const { + return fabs(LengthSq() - T(1)) < Math::Tolerance(); + } + + // Normalize, convention vector length to 1. + void Normalize() { + T s = Length(); + if (s != T(0)) + s = T(1) / s; + *this *= s; + } + + // Returns normalized (unit) version of the vector without modifying itself. + Vector4 Normalized() const { + T s = Length(); + if (s != T(0)) + s = T(1) / s; + return *this * s; + } + + // Linearly interpolates from this vector to another. + // Factor should be between 0.0 and 1.0, with 0 giving full value to this. + Vector4 Lerp(const Vector4& b, T f) const { + return *this * (T(1) - f) + b * f; + } +}; + +typedef Vector4 Vector4f; +typedef Vector4 Vector4d; +typedef Vector4 Vector4i; + +//------------------------------------------------------------------------------------- +// ***** Bounds3 + +// Bounds class used to describe a 3D axis aligned bounding box. + +template +class Bounds3 { + public: + Vector3 b[2]; + + Bounds3() { + Clear(); + } + + Bounds3(const Vector3& mins, const Vector3& maxs) { + b[0] = mins; + b[1] = maxs; + } + + void Clear() { + b[0].x = b[0].y = b[0].z = Math::MaxValue(); + b[1].x = b[1].y = b[1].z = -Math::MaxValue(); + } + + void AddPoint(const Vector3& v) { + b[0].x = (b[0].x < v.x ? b[0].x : v.x); + b[0].y = (b[0].y < v.y ? b[0].y : v.y); + b[0].z = (b[0].z < v.z ? b[0].z : v.z); + b[1].x = (v.x < b[1].x ? b[1].x : v.x); + b[1].y = (v.y < b[1].y ? b[1].y : v.y); + b[1].z = (v.z < b[1].z ? b[1].z : v.z); + } + + bool Excludes(const Vector3& v) const { + bool testing = false; + for (int32_t t = 0; t < 3; ++t) { + testing |= v[t] > b[1][t]; + testing |= v[t] < b[0][t]; + } + return testing; + } + + // exludes, ignoring vertical + bool ExcludesXZ(const Vector3& v) const { + bool testing = false; + testing |= v[0] > b[1][0]; + testing |= v[0] < b[0][0]; + testing |= v[2] > b[1][2]; + testing |= v[2] < b[0][2]; + return testing; + } + + bool Excludes(const Bounds3& bounds) const { + bool testing = false; + for (int32_t t = 0; t < 3; ++t) { + testing |= bounds.b[0][t] > b[1][t]; + testing |= bounds.b[1][t] < b[0][t]; + } + return testing; + } + + const Vector3& GetMins() const { + return b[0]; + } + const Vector3& GetMaxs() const { + return b[1]; + } + + Vector3& GetMins() { + return b[0]; + } + Vector3& GetMaxs() { + return b[1]; + } +}; + +typedef Bounds3 Bounds3f; +typedef Bounds3 Bounds3d; + +//------------------------------------------------------------------------------------- +// ***** Size + +// Size class represents 2D size with Width, Height components. +// Used to describe distentions of render targets, etc. + +template +class Size { + public: + T w, h; + + Size() : w(0), h(0) {} + Size(T w_, T h_) : w(w_), h(h_) {} + explicit Size(T s) : w(s), h(s) {} + explicit Size(const Size::OtherFloatType>& src) : w((T)src.w), h((T)src.h) {} + + // C-interop support. + typedef typename CompatibleTypes>::Type CompatibleType; + + Size(const CompatibleType& s) : w(s.w), h(s.h) {} + + operator const CompatibleType&() const { + OVR_MATH_STATIC_ASSERT(sizeof(Size) == sizeof(CompatibleType), "sizeof(Size) failure"); + return reinterpret_cast(*this); + } + + bool operator==(const Size& b) const { + return w == b.w && h == b.h; + } + bool operator!=(const Size& b) const { + return w != b.w || h != b.h; + } + + Size operator+(const Size& b) const { + return Size(w + b.w, h + b.h); + } + Size& operator+=(const Size& b) { + w += b.w; + h += b.h; + return *this; + } + Size operator-(const Size& b) const { + return Size(w - b.w, h - b.h); + } + Size& operator-=(const Size& b) { + w -= b.w; + h -= b.h; + return *this; + } + Size operator-() const { + return Size(-w, -h); + } + Size operator*(const Size& b) const { + return Size(w * b.w, h * b.h); + } + Size& operator*=(const Size& b) { + w *= b.w; + h *= b.h; + return *this; + } + Size operator/(const Size& b) const { + return Size(w / b.w, h / b.h); + } + Size& operator/=(const Size& b) { + w /= b.w; + h /= b.h; + return *this; + } + + // Scalar multiplication/division scales both components. + Size operator*(T s) const { + return Size(w * s, h * s); + } + Size& operator*=(T s) { + w *= s; + h *= s; + return *this; + } + Size operator/(T s) const { + return Size(w / s, h / s); + } + Size& operator/=(T s) { + w /= s; + h /= s; + return *this; + } + + static Size Min(const Size& a, const Size& b) { + return Size((a.w < b.w) ? a.w : b.w, (a.h < b.h) ? a.h : b.h); + } + static Size Max(const Size& a, const Size& b) { + return Size((a.w > b.w) ? a.w : b.w, (a.h > b.h) ? a.h : b.h); + } + + T Area() const { + return w * h; + } + + inline Vector2 ToVector() const { + return Vector2(w, h); + } +}; + +typedef Size Sizei; +typedef Size Sizeu; +typedef Size Sizef; +typedef Size Sized; + +//------------------------------------------------------------------------------------- +// ***** Size3 + +// Size3 class represents 3D size with Width, Height, Depth components. +// Used to describe distentions of render targets, etc. + +template +class Size3 { + public: + T w, h, d; + + Size3() : w(0), h(0), d(0) {} + Size3(T w_, T h_, T d_) : w(w_), h(h_), d(d_) {} + explicit Size3(T s) : w(s), h(s), d(s) {} + explicit Size3(const Size::OtherFloatType>& src) + : w((T)src.w), h((T)src.h), d((T)1) {} + explicit Size3(const Size3::OtherFloatType>& src) + : w((T)src.w), h((T)src.h), d((T)src.d) {} + + // C-interop support. + typedef typename CompatibleTypes>::Type CompatibleType; + + Size3(const CompatibleType& s) : w(s.w), h(s.h), d(s.d) {} + + operator const CompatibleType&() const { + OVR_MATH_STATIC_ASSERT(sizeof(Size3) == sizeof(CompatibleType), "sizeof(Size3) failure"); + return reinterpret_cast(*this); + } + + bool operator==(const Size3& b) const { + return w == b.w && h == b.h && d == b.d; + } + bool operator!=(const Size3& b) const { + return w != b.w || h != b.h || d != b.d; + } + + Size3 operator+(const Size3& b) const { + return Size3(w + b.w, h + b.h, d + b.d); + } + Size3& operator+=(const Size3& b) { + w += b.w; + h += b.h; + d += b.d; + return *this; + } + Size3 operator-(const Size3& b) const { + return Size3(w - b.w, h - b.h, d - b.d); + } + Size3& operator-=(const Size3& b) { + w -= b.w; + h -= b.h; + d -= b.d; + return *this; + } + Size3 operator-() const { + return Size3(-w, -h, -d); + } + Size3 operator*(const Size3& b) const { + return Size3(w * b.w, h * b.h, d * b.d); + } + Size3& operator*=(const Size3& b) { + w *= b.w; + h *= b.h; + d *= b.d; + return *this; + } + Size3 operator/(const Size3& b) const { + return Size3(w / b.w, h / b.h, d / b.d); + } + Size3& operator/=(const Size3& b) { + w /= b.w; + h /= b.h; + d /= b.d; + return *this; + } + + // Scalar multiplication/division scales both components. + Size3 operator*(T s) const { + return Size3(w * s, h * s, d * s); + } + Size3& operator*=(T s) { + w *= s; + h *= s; + d *= s; + return *this; + } + Size3 operator/(T s) const { + return Size3(w / s, h / s, d / s); + } + Size3& operator/=(T s) { + w /= s; + h /= s; + d /= s; + return *this; + } + + static Size3 Min(const Size3& a, const Size3& b) { + return Size3((a.w < b.w) ? a.w : b.w, (a.h < b.h) ? a.h : b.h, (a.d < b.d) ? a.d : b.d); + } + static Size3 Max(const Size3& a, const Size3& b) { + return Size3((a.w > b.w) ? a.w : b.w, (a.h > b.h) ? a.h : b.h, (a.d > b.d) ? a.d : b.d); + } + + T Volume() const { + return w * h * d; + } + + inline Vector3 ToVector() const { + return Vector3(w, h, d); + } +}; + +typedef Size3 Size3u; + +//----------------------------------------------------------------------------------- +// ***** Rect + +// Rect describes a rectangular area for rendering, that includes position and size. +template +class Rect { + public: + T x, y; + T w, h; + + Rect() {} + Rect(T x1, T y1, T w1, T h1) : x(x1), y(y1), w(w1), h(h1) {} + Rect(const Vector2& pos, const Size& sz) : x(pos.x), y(pos.y), w(sz.w), h(sz.h) {} + Rect(const Size& sz) : x(0), y(0), w(sz.w), h(sz.h) {} + + // C-interop support. + typedef typename CompatibleTypes>::Type CompatibleType; + + Rect(const CompatibleType& s) : x(s.Pos.x), y(s.Pos.y), w(s.Size.w), h(s.Size.h) {} + + operator const CompatibleType&() const { + OVR_MATH_STATIC_ASSERT(sizeof(Rect) == sizeof(CompatibleType), "sizeof(Rect) failure"); + return reinterpret_cast(*this); + } + + Vector2 GetPos() const { + return Vector2(x, y); + } + Size GetSize() const { + return Size(w, h); + } + void SetPos(const Vector2& pos) { + x = pos.x; + y = pos.y; + } + void SetSize(const Size& sz) { + w = sz.w; + h = sz.h; + } + + bool operator==(const Rect& vp) const { + return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); + } + bool operator!=(const Rect& vp) const { + return !operator==(vp); + } +}; + +typedef Rect Recti; + +//-------------------------------------------------------------------------------------// +// ***** Quat +// +// Quatf represents a quaternion class used for rotations. +// +// Quaternion multiplications are done in right-to-left order, to match the +// behavior of matrices. + +template +class Quat { + public: + typedef T ElementType; + static const size_t ElementCount = 4; + + // x,y,z = axis*sin(angle), w = cos(angle) + T x, y, z, w; + + Quat() : x(0), y(0), z(0), w(1) {} + Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) {} + explicit Quat(const Quat::OtherFloatType>& src) + : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { + // NOTE: Converting a normalized Quat to Quat + // will generally result in an un-normalized quaternion. + // But we don't normalize here in case the quaternion + // being converted is not a normalized rotation quaternion. + } + + typedef typename CompatibleTypes>::Type CompatibleType; + + // C-interop support. + Quat(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) {} + + operator CompatibleType() const { + CompatibleType result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + } + + // Constructs quaternion for rotation around the axis by an angle. + Quat(const Vector3& axis, T angle) { + // Make sure we don't divide by zero. + if (axis.LengthSq() == T(0)) { + // Assert if the axis is zero, but the angle isn't + OVR_MATH_ASSERT(angle == T(0)); + x = y = z = T(0); + w = T(1); + return; + } + + Vector3 unitAxis = axis.Normalized(); + T sinHalfAngle = sin(angle * T(0.5)); + + w = cos(angle * T(0.5)); + x = unitAxis.x * sinHalfAngle; + y = unitAxis.y * sinHalfAngle; + z = unitAxis.z * sinHalfAngle; + } + + // Constructs quaternion for rotation around one of the coordinate axis by an angle. + Quat(Axis A, T angle, RotateDirection d = Rotate_CCW, HandedSystem s = Handed_R) { + T sinHalfAngle = s * d * sin(angle * T(0.5)); + T v[3]; + v[0] = v[1] = v[2] = T(0); + v[A] = sinHalfAngle; + + w = cos(angle * T(0.5)); + x = v[0]; + y = v[1]; + z = v[2]; + } + + Quat operator-() { + return Quat(-x, -y, -z, -w); + } // unary minus + + static Quat Identity() { + return Quat(0, 0, 0, 1); + } + + // Compute axis and angle from quaternion + void GetAxisAngle(Vector3* axis, T* angle) const { + if (x * x + y * y + z * z > Math::Tolerance() * Math::Tolerance()) { + *axis = Vector3(x, y, z).Normalized(); + *angle = 2 * Acos(w); + if (*angle > ((T)MATH_DOUBLE_PI)) // Reduce the magnitude of the angle, if necessary + { + *angle = ((T)MATH_DOUBLE_TWOPI) - *angle; + *axis = *axis * (-1); + } + } else { + *axis = Vector3(1, 0, 0); + *angle = T(0); + } + } + + // Convert a quaternion to a rotation vector, also known as + // Rodrigues vector, AxisAngle vector, SORA vector, exponential map. + // A rotation vector describes a rotation about an axis: + // the axis of rotation is the vector normalized, + // the angle of rotation is the magnitude of the vector. + Vector3 ToRotationVector() const { + // OVR_MATH_ASSERT(IsNormalized()); // If this fires, caller has a quat math bug + T s = T(0); + T sinHalfAngle = sqrt(x * x + y * y + z * z); + if (sinHalfAngle > T(0)) { + T cosHalfAngle = w; + T halfAngle = atan2(sinHalfAngle, cosHalfAngle); + + // Ensure minimum rotation magnitude + if (cosHalfAngle < 0) + halfAngle -= T(MATH_DOUBLE_PI); + + s = T(2) * halfAngle / sinHalfAngle; + } + return Vector3(x * s, y * s, z * s); + } + + // Faster version of the above, optimized for use with small rotations, where rotation angle ~= + // sin(angle) + inline OVR::Vector3 FastToRotationVector() const { + OVR_MATH_ASSERT(IsNormalized()); // If this fires, caller has a quat math bug + T s; + T sinHalfSquared = x * x + y * y + z * z; + if (sinHalfSquared < T(.0037)) // =~ sin(7/2 degrees)^2 + { + // Max rotation magnitude error is about .062% at 7 degrees rotation, or about .0043 degrees + s = T(2) * Sign(w); + } else { + T sinHalfAngle = sqrt(sinHalfSquared); + T cosHalfAngle = w; + T halfAngle = atan2(sinHalfAngle, cosHalfAngle); + + // Ensure minimum rotation magnitude + if (cosHalfAngle < 0) + halfAngle -= T(MATH_DOUBLE_PI); + + s = T(2) * halfAngle / sinHalfAngle; + } + return Vector3(x * s, y * s, z * s); + } + + // Given a rotation vector of form unitRotationAxis * angle, + // returns the equivalent quaternion (unitRotationAxis * sin(angle), cos(Angle)). + static Quat FromRotationVector(const Vector3& v) { + T angleSquared = v.LengthSq(); + T s = T(0); + T c = T(1); + if (angleSquared > T(0)) { + T angle = sqrt(angleSquared); + s = sin(angle * T(0.5)) / angle; // normalize + c = cos(angle * T(0.5)); + } + return Quat(s * v.x, s * v.y, s * v.z, c); + } + + // Faster version of above, optimized for use with small rotation magnitudes, where rotation angle + // =~ sin(angle). + // If normalize is false, small-angle quaternions are returned un-normalized. + inline static Quat FastFromRotationVector(const OVR::Vector3& v, bool normalize = true) { + T s, c; + T angleSquared = v.LengthSq(); + if (angleSquared < T(0.0076)) // =~ (5 degrees*pi/180)^2 + { + s = T(0.5); + c = T(1.0); + // Max rotation magnitude error (after normalization) is about .064% at 5 degrees rotation, or + // .0032 degrees + if (normalize && angleSquared > 0) { + // sin(angle/2)^2 ~= (angle/2)^2 and cos(angle/2)^2 ~= 1 + T invLen = T(1) / sqrt(angleSquared * T(0.25) + T(1)); // normalize + s = s * invLen; + c = c * invLen; + } + } else { + T angle = sqrt(angleSquared); + s = sin(angle * T(0.5)) / angle; + c = cos(angle * T(0.5)); + } + return Quat(s * v.x, s * v.y, s * v.z, c); + } + + // Constructs the quaternion from a rotation matrix + explicit Quat(const Matrix4& m) { + T trace = m.M[0][0] + m.M[1][1] + m.M[2][2]; + + // In almost all cases, the first part is executed. + // However, if the trace is not positive, the other + // cases arise. + if (trace > T(0)) { + T s = sqrt(trace + T(1)) * T(2); // s=4*qw + w = T(0.25) * s; + x = (m.M[2][1] - m.M[1][2]) / s; + y = (m.M[0][2] - m.M[2][0]) / s; + z = (m.M[1][0] - m.M[0][1]) / s; + } else if ((m.M[0][0] > m.M[1][1]) && (m.M[0][0] > m.M[2][2])) { + T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2); + w = (m.M[2][1] - m.M[1][2]) / s; + x = T(0.25) * s; + y = (m.M[0][1] + m.M[1][0]) / s; + z = (m.M[2][0] + m.M[0][2]) / s; + } else if (m.M[1][1] > m.M[2][2]) { + T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy + w = (m.M[0][2] - m.M[2][0]) / s; + x = (m.M[0][1] + m.M[1][0]) / s; + y = T(0.25) * s; + z = (m.M[1][2] + m.M[2][1]) / s; + } else { + T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz + w = (m.M[1][0] - m.M[0][1]) / s; + x = (m.M[0][2] + m.M[2][0]) / s; + y = (m.M[1][2] + m.M[2][1]) / s; + z = T(0.25) * s; + } + OVR_MATH_ASSERT(IsNormalized()); // Ensure input matrix is orthogonal + } + + // Constructs the quaternion from a rotation matrix + explicit Quat(const Matrix3& m) { + T trace = m.M[0][0] + m.M[1][1] + m.M[2][2]; + + // In almost all cases, the first part is executed. + // However, if the trace is not positive, the other + // cases arise. + if (trace > T(0)) { + T s = sqrt(trace + T(1)) * T(2); // s=4*qw + w = T(0.25) * s; + x = (m.M[2][1] - m.M[1][2]) / s; + y = (m.M[0][2] - m.M[2][0]) / s; + z = (m.M[1][0] - m.M[0][1]) / s; + } else if ((m.M[0][0] > m.M[1][1]) && (m.M[0][0] > m.M[2][2])) { + T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2); + w = (m.M[2][1] - m.M[1][2]) / s; + x = T(0.25) * s; + y = (m.M[0][1] + m.M[1][0]) / s; + z = (m.M[2][0] + m.M[0][2]) / s; + } else if (m.M[1][1] > m.M[2][2]) { + T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy + w = (m.M[0][2] - m.M[2][0]) / s; + x = (m.M[0][1] + m.M[1][0]) / s; + y = T(0.25) * s; + z = (m.M[1][2] + m.M[2][1]) / s; + } else { + T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz + w = (m.M[1][0] - m.M[0][1]) / s; + x = (m.M[0][2] + m.M[2][0]) / s; + y = (m.M[1][2] + m.M[2][1]) / s; + z = T(0.25) * s; + } + OVR_MATH_ASSERT(IsNormalized()); // Ensure input matrix is orthogonal + } + + // MERGE_MOBILE_SDK + // Constructs a quaternion that rotates 'from' to line up with 'to'. + explicit Quat(const Vector3& from, const Vector3& to) { + const T cx = from.y * to.z - from.z * to.y; + const T cy = from.z * to.x - from.x * to.z; + const T cz = from.x * to.y - from.y * to.x; + const T dot = from.x * to.x + from.y * to.y + from.z * to.z; + const T crossLengthSq = cx * cx + cy * cy + cz * cz; + const T magnitude = static_cast(sqrt(crossLengthSq + dot * dot)); + const T cw = dot + magnitude; + if (cw < Math::SmallestNonDenormal()) { + const T sx = to.y * to.y + to.z * to.z; + const T sz = to.x * to.x + to.y * to.y; + if (sx > sz) { + const T rcpLength = RcpSqrt(sx); + x = T(0); + y = to.z * rcpLength; + z = -to.y * rcpLength; + w = T(0); + } else { + const T rcpLength = RcpSqrt(sz); + x = to.y * rcpLength; + y = -to.x * rcpLength; + z = T(0); + w = T(0); + } + return; + } + const T rcpLength = RcpSqrt(crossLengthSq + cw * cw); + x = cx * rcpLength; + y = cy * rcpLength; + z = cz * rcpLength; + w = cw * rcpLength; + } + // MERGE_MOBILE_SDK + + bool operator==(const Quat& b) const { + return x == b.x && y == b.y && z == b.z && w == b.w; + } + bool operator!=(const Quat& b) const { + return x != b.x || y != b.y || z != b.z || w != b.w; + } + + Quat operator+(const Quat& b) const { + return Quat(x + b.x, y + b.y, z + b.z, w + b.w); + } + Quat& operator+=(const Quat& b) { + w += b.w; + x += b.x; + y += b.y; + z += b.z; + return *this; + } + Quat operator-(const Quat& b) const { + return Quat(x - b.x, y - b.y, z - b.z, w - b.w); + } + Quat& operator-=(const Quat& b) { + w -= b.w; + x -= b.x; + y -= b.y; + z -= b.z; + return *this; + } + + Quat operator*(T s) const { + return Quat(x * s, y * s, z * s, w * s); + } + Quat& operator*=(T s) { + w *= s; + x *= s; + y *= s; + z *= s; + return *this; + } + Quat operator/(T s) const { + T rcp = T(1) / s; + return Quat(x * rcp, y * rcp, z * rcp, w * rcp); + } + Quat& operator/=(T s) { + T rcp = T(1) / s; + w *= rcp; + x *= rcp; + y *= rcp; + z *= rcp; + return *this; + } + + // MERGE_MOBILE_SDK + Vector3 operator*(const Vector3& v) const { + return Rotate(v); + } + // MERGE_MOBILE_SDK + + // Compare two quats for equality within tolerance. Returns true if quats match within tolerance. + bool IsEqual(const Quat& b, T tolerance = Math::Tolerance()) const { + return Abs(Dot(b)) >= T(1) - tolerance; + } + + // Compare two quats for equality within tolerance while checking matching hemispheres. Returns + // true if quats match within tolerance. + bool IsEqualMatchHemisphere(Quat b, T tolerance = Math::Tolerance()) const { + b.EnsureSameHemisphere(*this); + return Abs(Dot(b)) >= T(1) - tolerance; + } + + static T Abs(const T v) { + return (v >= 0) ? v : -v; + } + + // Get Imaginary part vector + Vector3 Imag() const { + return Vector3(x, y, z); + } + + // Get quaternion length. + T Length() const { + return sqrt(LengthSq()); + } + + // Get quaternion length squared. + T LengthSq() const { + return (x * x + y * y + z * z + w * w); + } + + // Simple Euclidean distance in R^4 (not SLERP distance, but at least respects Haar measure) + T Distance(const Quat& q) const { + T d1 = (*this - q).Length(); + T d2 = (*this + q).Length(); // Antipodal point check + return (d1 < d2) ? d1 : d2; + } + + T DistanceSq(const Quat& q) const { + T d1 = (*this - q).LengthSq(); + T d2 = (*this + q).LengthSq(); // Antipodal point check + return (d1 < d2) ? d1 : d2; + } + + T Dot(const Quat& q) const { + return x * q.x + y * q.y + z * q.z + w * q.w; + } + + // Angle between two quaternions in radians + T Angle(const Quat& q) const { + return T(2) * Acos(Abs(Dot(q))); + } + + // Angle of quaternion + T Angle() const { + return T(2) * Acos(Abs(w)); + } + + // Normalize + bool IsNormalized() const { + return fabs(LengthSq() - T(1)) < Math::Tolerance(); + } + + void Normalize() { + T s = Length(); + if (s != T(0)) + s = T(1) / s; + *this *= s; + } + + Quat Normalized() const { + T s = Length(); + if (s != T(0)) + s = T(1) / s; + return *this * s; + } + + inline void EnsureSameHemisphere(const Quat& o) { + if (Dot(o) < T(0)) { + x = -x; + y = -y; + z = -z; + w = -w; + } + } + + // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized. + Quat Conj() const { + return Quat(-x, -y, -z, w); + } + + // Quaternion multiplication. Combines quaternion rotations, performing the one on the + // right hand side first. + Quat operator*(const Quat& b) const { + return Quat( + w * b.x + x * b.w + y * b.z - z * b.y, + w * b.y - x * b.z + y * b.w + z * b.x, + w * b.z + x * b.y - y * b.x + z * b.w, + w * b.w - x * b.x - y * b.y - z * b.z); + } + const Quat& operator*=(const Quat& b) { + *this = *this * b; + return *this; + } + + // + // this^p normalized; same as rotating by this p times. + Quat PowNormalized(T p) const { + Vector3 v; + T a; + GetAxisAngle(&v, &a); + return Quat(v, a * p); + } + + // Compute quaternion that rotates v into alignTo: alignTo = Quat::Align(alignTo, v).Rotate(v). + // NOTE: alignTo and v must be normalized. + static Quat Align(const Vector3& alignTo, const Vector3& v) { + OVR_MATH_ASSERT(alignTo.IsNormalized() && v.IsNormalized()); + Vector3 bisector = (v + alignTo); + bisector.Normalize(); + T cosHalfAngle = v.Dot(bisector); // 0..1 + if (cosHalfAngle > T(0)) { + Vector3 imag = v.Cross(bisector); + return Quat(imag.x, imag.y, imag.z, cosHalfAngle); + } else { + // cosHalfAngle == 0: a 180 degree rotation. + // sinHalfAngle == 1, rotation axis is any axis perpendicular + // to alignTo. Choose axis to include largest magnitude components + if (fabs(v.x) > fabs(v.y)) { + // x or z is max magnitude component + // = Cross(v, (0,1,0)).Normalized(); + T invLen = sqrt(v.x * v.x + v.z * v.z); + if (invLen > T(0)) + invLen = T(1) / invLen; + return Quat(-v.z * invLen, 0, v.x * invLen, 0); + } else { + // y or z is max magnitude component + // = Cross(v, (1,0,0)).Normalized(); + T invLen = sqrt(v.y * v.y + v.z * v.z); + if (invLen > T(0)) + invLen = T(1) / invLen; + return Quat(0, v.z * invLen, -v.y * invLen, 0); + } + } + } + + // Decompose a quat into quat = swing * twist, where twist is a rotation about axis, + // and swing is a rotation perpendicular to axis. + Quat GetSwingTwist(const Vector3& axis, Quat* twist) const { + OVR_MATH_ASSERT(twist); + OVR_MATH_ASSERT(axis.IsNormalized()); + + // Create a normalized quaternion from projection of (x,y,z) onto axis + T d = axis.Dot(Vector3(x, y, z)); + *twist = Quat(axis.x * d, axis.y * d, axis.z * d, w); + T len = twist->Length(); + if (len == 0) + twist->w = T(1); // identity + else + *twist /= len; // normalize + + return *this * twist->Inverted(); + } + + // Normalized linear interpolation of quaternions + // NOTE: This function is a bad approximation of Slerp() + // when the angle between the *this and b is large. + // Use FastSlerp() or Slerp() instead. + Quat Lerp(const Quat& b, T s) const { + return (*this * (T(1) - s) + b * (Dot(b) < 0 ? -s : s)).Normalized(); + } + + // Spherical linear interpolation between rotations + Quat Slerp(const Quat& b, T s) const { + Vector3 delta = (b * this->Inverted()).ToRotationVector(); + return (FromRotationVector(delta * s) * *this) + .Normalized(); // normalize so errors don't accumulate + } + + // Spherical linear interpolation: much faster for small rotations, accurate for large rotations. + // See FastTo/FromRotationVector + Quat FastSlerp(const Quat& b, T s) const { + Vector3 delta = (b * this->Inverted()).FastToRotationVector(); + return (FastFromRotationVector(delta * s, false) * *this).Normalized(); + } + + // MERGE_MOBILE_SDK + // FIXME: This is opposite of Lerp for some reason. It goes from 1 to 0 instead of 0 to 1. + // Leaving it as a gift for future generations to deal with. + Quat Nlerp(const Quat& other, T a) const { + T sign = (Dot(other) >= 0.0f) ? 1.0f : -1.0f; + return (*this * sign * a + other * (1 - a)).Normalized(); + } + // MERGE_MOBILE_SDK + + // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise, + // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1. + Vector3 Rotate(const Vector3& v) const { + OVR_MATH_ASSERT(IsNormalized()); // If this fires, caller has a quat math bug + + // rv = q * (v,0) * q' + // Same as rv = v + real * cross(imag,v)*2 + cross(imag, cross(imag,v)*2); + + // uv = 2 * Imag().Cross(v); + T uvx = T(2) * (y * v.z - z * v.y); + T uvy = T(2) * (z * v.x - x * v.z); + T uvz = T(2) * (x * v.y - y * v.x); + + // return v + Real()*uv + Imag().Cross(uv); + return Vector3( + v.x + w * uvx + y * uvz - z * uvy, + v.y + w * uvy + z * uvx - x * uvz, + v.z + w * uvz + x * uvy - y * uvx); + } + + // Rotation by inverse of *this + Vector3 InverseRotate(const Vector3& v) const { + OVR_MATH_ASSERT(IsNormalized()); // If this fires, caller has a quat math bug + + // rv = q' * (v,0) * q + // Same as rv = v + real * cross(-imag,v)*2 + cross(-imag, cross(-imag,v)*2); + // or rv = v - real * cross(imag,v)*2 + cross(imag, cross(imag,v)*2); + + // uv = 2 * Imag().Cross(v); + T uvx = T(2) * (y * v.z - z * v.y); + T uvy = T(2) * (z * v.x - x * v.z); + T uvz = T(2) * (x * v.y - y * v.x); + + // return v - Real()*uv + Imag().Cross(uv); + return Vector3( + v.x - w * uvx + y * uvz - z * uvy, + v.y - w * uvy + z * uvx - x * uvz, + v.z - w * uvz + x * uvy - y * uvx); + } + + // Inversed quaternion rotates in the opposite direction. + Quat Inverted() const { + return Quat(-x, -y, -z, w); + } + + Quat Inverse() const { + return Quat(-x, -y, -z, w); + } + + // Sets this quaternion to the one rotates in the opposite direction. + void Invert() { + *this = Quat(-x, -y, -z, w); + } + + // Time integration of constant angular velocity over dt + Quat TimeIntegrate(const Vector3& angularVelocity, T dt) const { + // solution is: this * exp( omega*dt/2 ); FromRotationVector(v) gives exp(v*.5). + return (*this * FastFromRotationVector(angularVelocity * dt, false)).Normalized(); + } + + // Time integration of constant angular acceleration and velocity over dt + // These are the first two terms of the "Magnus expansion" of the solution + // + // o = o * exp( W=(W1 + W2 + W3+...) * 0.5 ); + // + // omega1 = (omega + omegaDot*dt) + // W1 = (omega + omega1)*dt/2 + // W2 = cross(omega, omega1)/12*dt^2 % (= -cross(omega_dot, omega)/12*dt^3) + // Terms 3 and beyond are vanishingly small: + // W3 = cross(omega_dot, cross(omega_dot, omega))/240*dt^5 + // + Quat TimeIntegrate(const Vector3& angularVelocity, const Vector3& angularAcceleration, T dt) + const { + const Vector3& omega = angularVelocity; + const Vector3& omegaDot = angularAcceleration; + + Vector3 omega1 = (omega + omegaDot * dt); + Vector3 W = ((omega + omega1) + omega.Cross(omega1) * (dt / T(6))) * (dt / T(2)); + + // FromRotationVector(v) is exp(v*.5) + return (*this * FastFromRotationVector(W, false)).Normalized(); + } + + // Decompose rotation into three rotations: + // roll radians about Z axis, then pitch radians about X axis, then yaw radians about Y axis. + // Call with nullptr if a return value is not needed. + void GetYawPitchRoll(T* yaw, T* pitch, T* roll) const { + return GetEulerAngles(yaw, pitch, roll); + } + + // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of + // axis rotations and the specified coordinate system. Right-handed coordinate system + // is the default, with CCW rotations while looking in the negative axis direction. + // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned. + // Rotation order is c, b, a: + // rotation c around axis A3 + // is followed by rotation b around axis A2 + // is followed by rotation a around axis A1 + // rotations are CCW or CW (D) in LH or RH coordinate system (S) + // + template + void GetEulerAngles(T* a, T* b, T* c) const { + OVR_MATH_ASSERT(IsNormalized()); // If this fires, caller has a quat math bug + OVR_MATH_STATIC_ASSERT( + (A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)"); + + T Q[3] = {x, y, z}; // Quaternion components x,y,z + + T ww = w * w; + T Q11 = Q[A1] * Q[A1]; + T Q22 = Q[A2] * Q[A2]; + T Q33 = Q[A3] * Q[A3]; + + T psign = T(-1); + // Determine whether even permutation + if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) + psign = T(1); + + T s2 = psign * T(2) * (psign * w * Q[A2] + Q[A1] * Q[A3]); + + T singularityRadius = Math::SingularityRadius(); + if (s2 < T(-1) + singularityRadius) { // South pole singularity + if (a) + *a = T(0); + if (b) + *b = -S * D * ((T)MATH_DOUBLE_PIOVER2); + if (c) + *c = S * D * atan2(T(2) * (psign * Q[A1] * Q[A2] + w * Q[A3]), ww + Q22 - Q11 - Q33); + } else if (s2 > T(1) - singularityRadius) { // North pole singularity + if (a) + *a = T(0); + if (b) + *b = S * D * ((T)MATH_DOUBLE_PIOVER2); + if (c) + *c = S * D * atan2(T(2) * (psign * Q[A1] * Q[A2] + w * Q[A3]), ww + Q22 - Q11 - Q33); + } else { + if (a) + *a = -S * D * atan2(T(-2) * (w * Q[A1] - psign * Q[A2] * Q[A3]), ww + Q33 - Q11 - Q22); + if (b) + *b = S * D * asin(s2); + if (c) + *c = S * D * atan2(T(2) * (w * Q[A3] - psign * Q[A1] * Q[A2]), ww + Q11 - Q22 - Q33); + } + } + + template + void GetEulerAngles(T* a, T* b, T* c) const { + GetEulerAngles(a, b, c); + } + + template + void GetEulerAngles(T* a, T* b, T* c) const { + GetEulerAngles(a, b, c); + } + + // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of + // axis rotations and the specified coordinate system. Right-handed coordinate system + // is the default, with CCW rotations while looking in the negative axis direction. + // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned. + // rotation a around axis A1 + // is followed by rotation b around axis A2 + // is followed by rotation c around axis A1 + // Rotations are CCW or CW (D) in LH or RH coordinate system (S) + template + void GetEulerAnglesABA(T* a, T* b, T* c) const { + OVR_MATH_ASSERT(IsNormalized()); // If this fires, caller has a quat math bug + OVR_MATH_STATIC_ASSERT(A1 != A2, "A1 != A2"); + + T Q[3] = {x, y, z}; // Quaternion components + + // Determine the missing axis that was not supplied + int m = 3 - A1 - A2; + + T ww = w * w; + T Q11 = Q[A1] * Q[A1]; + T Q22 = Q[A2] * Q[A2]; + T Qmm = Q[m] * Q[m]; + + T psign = T(-1); + if ((A1 + 1) % 3 == A2) // Determine whether even permutation + { + psign = T(1); + } + + T c2 = ww + Q11 - Q22 - Qmm; + T singularityRadius = Math::SingularityRadius(); + if (c2 < T(-1) + singularityRadius) { // South pole singularity + if (a) + *a = T(0); + if (b) + *b = S * D * ((T)MATH_DOUBLE_PI); + if (c) + *c = S * D * atan2(T(2) * (w * Q[A1] - psign * Q[A2] * Q[m]), ww + Q22 - Q11 - Qmm); + } else if (c2 > T(1) - singularityRadius) { // North pole singularity + if (a) + *a = T(0); + if (b) + *b = T(0); + if (c) + *c = S * D * atan2(T(2) * (w * Q[A1] - psign * Q[A2] * Q[m]), ww + Q22 - Q11 - Qmm); + } else { + if (a) + *a = S * D * atan2(psign * w * Q[m] + Q[A1] * Q[A2], w * Q[A2] - psign * Q[A1] * Q[m]); + if (b) + *b = S * D * acos(c2); + if (c) + *c = S * D * atan2(-psign * w * Q[m] + Q[A1] * Q[A2], w * Q[A2] + psign * Q[A1] * Q[m]); + } + } + + bool IsNan() const { + return !isfinite(x + y + z + w); + } + bool IsFinite() const { + return isfinite(x + y + z + w); + } +}; + +typedef Quat Quatf; +typedef Quat Quatd; + +OVR_MATH_STATIC_ASSERT((sizeof(Quatf) == 4 * sizeof(float)), "sizeof(Quatf) failure"); +OVR_MATH_STATIC_ASSERT((sizeof(Quatd) == 4 * sizeof(double)), "sizeof(Quatd) failure"); + +//------------------------------------------------------------------------------------- +// ***** Pose +// +// Position and orientation combined. +// +// This structure needs to be the same size and layout on 32-bit and 64-bit arch. +// Update OVR_PadCheck.cpp when updating this object. +template +class Pose { + public: + typedef typename CompatibleTypes>::Type CompatibleType; + + Pose() {} + Pose(const Quat& orientation, const Vector3& pos) + : Rotation(orientation), Translation(pos) {} + Pose(const Pose& s) : Rotation(s.Rotation), Translation(s.Translation) {} + Pose(const Matrix3& R, const Vector3& t) : Rotation((Quat)R), Translation(t) {} + Pose(const CompatibleType& s) : Rotation(s.Orientation), Translation(s.Position) {} + + explicit Pose(const Pose::OtherFloatType>& s) + : Rotation(s.Rotation), Translation(s.Translation) { + // Ensure normalized rotation if converting from float to double + if (sizeof(T) > sizeof(typename Math::OtherFloatType)) + Rotation.Normalize(); + } + + static Pose Identity() { + return Pose(Quat(0, 0, 0, 1), Vector3(0, 0, 0)); + } + + void SetIdentity() { + Rotation = Quat(0, 0, 0, 1); + Translation = Vector3(0, 0, 0); + } + + // used to make things obviously broken if someone tries to use the value + void SetInvalid() { + Rotation = Quat(NAN, NAN, NAN, NAN); + Translation = Vector3(NAN, NAN, NAN); + } + + bool IsEqual(const Pose& b, T tolerance = Math::Tolerance()) const { + return Translation.IsEqual(b.Translation, tolerance) && Rotation.IsEqual(b.Rotation, tolerance); + } + + bool IsEqualMatchHemisphere(const Pose& b, T tolerance = Math::Tolerance()) const { + return Translation.IsEqual(b.Translation, tolerance) && + Rotation.IsEqualMatchHemisphere(b.Rotation, tolerance); + } + + operator typename CompatibleTypes>::Type() const { + typename CompatibleTypes>::Type result; + result.Orientation = Rotation; + result.Position = Translation; + return result; + } + + Quat Rotation; + Vector3 Translation; + + OVR_MATH_STATIC_ASSERT( + (sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float)), + "(sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float))"); + + void ToArray(T* arr) const { + T temp[7] = {Rotation.x, + Rotation.y, + Rotation.z, + Rotation.w, + Translation.x, + Translation.y, + Translation.z}; + for (int i = 0; i < 7; i++) + arr[i] = temp[i]; + } + + static Pose FromArray(const T* v) { + Quat rotation(v[0], v[1], v[2], v[3]); + Vector3 translation(v[4], v[5], v[6]); + // Ensure rotation is normalized, in case it was originally a float, stored in a .json file, + // etc. + return Pose(rotation.Normalized(), translation); + } + + Vector3 Rotate(const Vector3& v) const { + return Rotation.Rotate(v); + } + + Vector3 InverseRotate(const Vector3& v) const { + return Rotation.InverseRotate(v); + } + + Vector3 Translate(const Vector3& v) const { + return v + Translation; + } + + Vector3 Transform(const Vector3& v) const { + return Rotate(v) + Translation; + } + + Vector3 InverseTransform(const Vector3& v) const { + return InverseRotate(v - Translation); + } + + Vector3 TransformNormal(const Vector3& v) const { + return Rotate(v); + } + + Vector3 InverseTransformNormal(const Vector3& v) const { + return InverseRotate(v); + } + + Vector3 Apply(const Vector3& v) const { + return Transform(v); + } + + Pose operator*(const Pose& other) const { + return Pose(Rotation * other.Rotation, Apply(other.Translation)); + } + + Pose Inverted() const { + Quat inv = Rotation.Inverted(); + return Pose(inv, inv.Rotate(-Translation)); + } + + // Interpolation between two poses: translation is interpolated with Lerp(), + // and rotations are interpolated with Slerp(). + Pose Lerp(const Pose& b, T s) const { + return Pose(Rotation.Slerp(b.Rotation, s), Translation.Lerp(b.Translation, s)); + } + + // Similar to Lerp above, except faster in case of small rotation differences. See + // Quat::FastSlerp. + Pose FastLerp(const Pose& b, T s) const { + return Pose(Rotation.FastSlerp(b.Rotation, s), Translation.Lerp(b.Translation, s)); + } + + Pose TimeIntegrate(const Vector3& linearVelocity, const Vector3& angularVelocity, T dt) + const { + return Pose( + (Rotation * Quat::FastFromRotationVector(angularVelocity * dt, false)).Normalized(), + Translation + linearVelocity * dt); + } + + Pose TimeIntegrate( + const Vector3& linearVelocity, + const Vector3& linearAcceleration, + const Vector3& angularVelocity, + const Vector3& angularAcceleration, + T dt) const { + return Pose( + Rotation.TimeIntegrate(angularVelocity, angularAcceleration, dt), + Translation + linearVelocity * dt + linearAcceleration * dt * dt * T(0.5)); + } + + Pose Normalized() const { + return Pose(Rotation.Normalized(), Translation); + } + void Normalize() { + Rotation.Normalize(); + } + + bool IsNan() const { + return Translation.IsNan() || Rotation.IsNan(); + } + bool IsFinite() const { + return Translation.IsFinite() && Rotation.IsFinite(); + } +}; + +typedef Pose Posef; +typedef Pose Posed; + +OVR_MATH_STATIC_ASSERT( + (sizeof(Posed) == sizeof(Quatd) + sizeof(Vector3d)), + "sizeof(Posed) failure"); +OVR_MATH_STATIC_ASSERT( + (sizeof(Posef) == sizeof(Quatf) + sizeof(Vector3f)), + "sizeof(Posef) failure"); + +//------------------------------------------------------------------------------------- +// ***** Matrix4 +// +// Matrix4 is a 4x4 matrix used for 3d transformations and projections. +// Translation stored in the last column. +// The matrix is stored in row-major order in memory, meaning that values +// of the first row are stored before the next one. +// +// The arrangement of the matrix is chosen to be in Right-Handed +// coordinate system and counterclockwise rotations when looking down +// the axis +// +// Transformation Order: +// - Transformations are applied from right to left, so the expression +// M1 * M2 * M3 * V means that the vector V is transformed by M3 first, +// followed by M2 and M1. +// +// Coordinate system: Right Handed +// +// Rotations: Counterclockwise when looking down the axis. All angles are in radians. +// +// | sx 01 02 tx | // First column (sx, 10, 20): Axis X basis vector. +// | 10 sy 12 ty | // Second column (01, sy, 21): Axis Y basis vector. +// | 20 21 sz tz | // Third columnt (02, 12, sz): Axis Z basis vector. +// | 30 31 32 33 | +// +// The basis vectors are first three columns. + +template +class Matrix4 { + public: + typedef T ElementType; + static const size_t Dimension = 4; + + T M[4][4]; + + enum NoInitType { NoInit }; + + // Construct with no memory initialization. + Matrix4(NoInitType) {} + + // By default, we construct identity matrix. + Matrix4() { + M[0][0] = M[1][1] = M[2][2] = M[3][3] = T(1); + M[0][1] = M[1][0] = M[2][3] = M[3][1] = T(0); + M[0][2] = M[1][2] = M[2][0] = M[3][2] = T(0); + M[0][3] = M[1][3] = M[2][1] = M[3][0] = T(0); + } + + Matrix4( + T m11, + T m12, + T m13, + T m14, + T m21, + T m22, + T m23, + T m24, + T m31, + T m32, + T m33, + T m34, + T m41, + T m42, + T m43, + T m44) { + M[0][0] = m11; + M[0][1] = m12; + M[0][2] = m13; + M[0][3] = m14; + M[1][0] = m21; + M[1][1] = m22; + M[1][2] = m23; + M[1][3] = m24; + M[2][0] = m31; + M[2][1] = m32; + M[2][2] = m33; + M[2][3] = m34; + M[3][0] = m41; + M[3][1] = m42; + M[3][2] = m43; + M[3][3] = m44; + } + + Matrix4(T m11, T m12, T m13, T m21, T m22, T m23, T m31, T m32, T m33) { + M[0][0] = m11; + M[0][1] = m12; + M[0][2] = m13; + M[0][3] = T(0); + M[1][0] = m21; + M[1][1] = m22; + M[1][2] = m23; + M[1][3] = T(0); + M[2][0] = m31; + M[2][1] = m32; + M[2][2] = m33; + M[2][3] = T(0); + M[3][0] = T(0); + M[3][1] = T(0); + M[3][2] = T(0); + M[3][3] = T(1); + } + + explicit Matrix4(const Matrix3& m) { + M[0][0] = m.M[0][0]; + M[0][1] = m.M[0][1]; + M[0][2] = m.M[0][2]; + M[0][3] = T(0); + M[1][0] = m.M[1][0]; + M[1][1] = m.M[1][1]; + M[1][2] = m.M[1][2]; + M[1][3] = T(0); + M[2][0] = m.M[2][0]; + M[2][1] = m.M[2][1]; + M[2][2] = m.M[2][2]; + M[2][3] = T(0); + M[3][0] = T(0); + M[3][1] = T(0); + M[3][2] = T(0); + M[3][3] = T(1); + } + + explicit Matrix4(const Quat& q) { + OVR_MATH_ASSERT(q.IsNormalized()); // If this fires, caller has a quat math bug + T ww = q.w * q.w; + T xx = q.x * q.x; + T yy = q.y * q.y; + T zz = q.z * q.z; + + M[0][0] = ww + xx - yy - zz; + M[0][1] = 2 * (q.x * q.y - q.w * q.z); + M[0][2] = 2 * (q.x * q.z + q.w * q.y); + M[0][3] = T(0); + M[1][0] = 2 * (q.x * q.y + q.w * q.z); + M[1][1] = ww - xx + yy - zz; + M[1][2] = 2 * (q.y * q.z - q.w * q.x); + M[1][3] = T(0); + M[2][0] = 2 * (q.x * q.z - q.w * q.y); + M[2][1] = 2 * (q.y * q.z + q.w * q.x); + M[2][2] = ww - xx - yy + zz; + M[2][3] = T(0); + M[3][0] = T(0); + M[3][1] = T(0); + M[3][2] = T(0); + M[3][3] = T(1); + } + + explicit Matrix4(const Pose& p) { + Matrix4 result(p.Rotation); + result.SetTranslation(p.Translation); + *this = result; + } + + // C-interop support + explicit Matrix4(const Matrix4::OtherFloatType>& src) { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + M[i][j] = (T)src.M[i][j]; + } + + // C-interop support. + Matrix4(const typename CompatibleTypes>::Type& s) { + OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix4), "sizeof(s) == sizeof(Matrix4)"); + memcpy(M, s.M, sizeof(M)); + } + + operator typename CompatibleTypes>::Type() const { + typename CompatibleTypes>::Type result; + OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix4), "sizeof(result) == sizeof(Matrix4)"); + memcpy(result.M, M, sizeof(M)); + return result; + } + + void ToString(char* dest, size_t destsize) const { + size_t pos = 0; + for (int r = 0; r < 4; r++) { + for (int c = 0; c < 4; c++) { + pos += OVRMath_sprintf(dest + pos, destsize - pos, "%g ", M[r][c]); + } + } + } + + static Matrix4 FromString(const char* src) { + Matrix4 result; + if (src) { + for (int r = 0; r < 4; r++) { + for (int c = 0; c < 4; c++) { + result.M[r][c] = (T)atof(src); + while (*src && *src != ' ') { + src++; + } + while (*src && *src == ' ') { + src++; + } + } + } + } + return result; + } + + static Matrix4 Identity() { + return Matrix4(); + } + + void SetIdentity() { + M[0][0] = M[1][1] = M[2][2] = M[3][3] = T(1); + M[0][1] = M[1][0] = M[2][3] = M[3][1] = T(0); + M[0][2] = M[1][2] = M[2][0] = M[3][2] = T(0); + M[0][3] = M[1][3] = M[2][1] = M[3][0] = T(0); + } + + void SetXBasis(const Vector3& v) { + M[0][0] = v.x; + M[1][0] = v.y; + M[2][0] = v.z; + } + Vector3 GetXBasis() const { + return Vector3(M[0][0], M[1][0], M[2][0]); + } + + void SetYBasis(const Vector3& v) { + M[0][1] = v.x; + M[1][1] = v.y; + M[2][1] = v.z; + } + Vector3 GetYBasis() const { + return Vector3(M[0][1], M[1][1], M[2][1]); + } + + void SetZBasis(const Vector3& v) { + M[0][2] = v.x; + M[1][2] = v.y; + M[2][2] = v.z; + } + Vector3 GetZBasis() const { + return Vector3(M[0][2], M[1][2], M[2][2]); + } + + bool operator==(const Matrix4& b) const { + bool isEqual = true; + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + isEqual &= (M[i][j] == b.M[i][j]); + + return isEqual; + } + + Matrix4 operator+(const Matrix4& b) const { + Matrix4 result(*this); + result += b; + return result; + } + + Matrix4& operator+=(const Matrix4& b) { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + M[i][j] += b.M[i][j]; + return *this; + } + + Matrix4 operator-(const Matrix4& b) const { + Matrix4 result(*this); + result -= b; + return result; + } + + Matrix4& operator-=(const Matrix4& b) { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + M[i][j] -= b.M[i][j]; + return *this; + } + + // Multiplies two matrices into destination with minimum copying. + static Matrix4& Multiply(Matrix4* d, const Matrix4& a, const Matrix4& b) { + OVR_MATH_ASSERT((d != &a) && (d != &b)); + int i = 0; + do { + d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0] + + a.M[i][3] * b.M[3][0]; + d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1] + + a.M[i][3] * b.M[3][1]; + d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2] + + a.M[i][3] * b.M[3][2]; + d->M[i][3] = a.M[i][0] * b.M[0][3] + a.M[i][1] * b.M[1][3] + a.M[i][2] * b.M[2][3] + + a.M[i][3] * b.M[3][3]; + } while ((++i) < 4); + + return *d; + } + + Matrix4 operator*(const Matrix4& b) const { + Matrix4 result(Matrix4::NoInit); + Multiply(&result, *this, b); + return result; + } + + Matrix4& operator*=(const Matrix4& b) { + return Multiply(this, Matrix4(*this), b); + } + + Matrix4 operator*(T s) const { + Matrix4 result(*this); + result *= s; + return result; + } + + Matrix4& operator*=(T s) { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + M[i][j] *= s; + return *this; + } + + Matrix4 operator/(T s) const { + Matrix4 result(*this); + result /= s; + return result; + } + + Matrix4& operator/=(T s) { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + M[i][j] /= s; + return *this; + } + + T operator()(int i, int j) const { + return M[i][j]; + } + T& operator()(int i, int j) { + return M[i][j]; + } + + Vector4 operator*(const Vector4& b) const { + return Transform(b); + } + + Vector3 Transform(const Vector3& v) const { + const T rcpW = T(1) / (M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3]); + return Vector3( + (M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3]) * rcpW, + (M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3]) * rcpW, + (M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]) * rcpW); + } + + Vector4 Transform(const Vector4& v) const { + return Vector4( + M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3] * v.w, + M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3] * v.w, + M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3] * v.w, + M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3] * v.w); + } + + Matrix4 Transposed() const { + return Matrix4( + M[0][0], + M[1][0], + M[2][0], + M[3][0], + M[0][1], + M[1][1], + M[2][1], + M[3][1], + M[0][2], + M[1][2], + M[2][2], + M[3][2], + M[0][3], + M[1][3], + M[2][3], + M[3][3]); + } + + void Transpose() { + *this = Transposed(); + } + + T SubDet(const size_t* rows, const size_t* cols) const { + return M[rows[0]][cols[0]] * + (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]]) - + M[rows[0]][cols[1]] * + (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]]) + + M[rows[0]][cols[2]] * + (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]); + } + + T Cofactor(size_t I, size_t J) const { + const size_t indices[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}}; + return ((I + J) & 1) ? -SubDet(indices[I], indices[J]) : SubDet(indices[I], indices[J]); + } + + T Determinant() const { + return M[0][0] * Cofactor(0, 0) + M[0][1] * Cofactor(0, 1) + M[0][2] * Cofactor(0, 2) + + M[0][3] * Cofactor(0, 3); + } + + Matrix4 Adjugated() const { + return Matrix4( + Cofactor(0, 0), + Cofactor(1, 0), + Cofactor(2, 0), + Cofactor(3, 0), + Cofactor(0, 1), + Cofactor(1, 1), + Cofactor(2, 1), + Cofactor(3, 1), + Cofactor(0, 2), + Cofactor(1, 2), + Cofactor(2, 2), + Cofactor(3, 2), + Cofactor(0, 3), + Cofactor(1, 3), + Cofactor(2, 3), + Cofactor(3, 3)); + } + + Matrix4 Inverted() const { + T det = Determinant(); + OVR_MATH_ASSERT(det != 0); + return Adjugated() * (T(1) / det); + } + + void Invert() { + *this = Inverted(); + } + + // This is more efficient than general inverse, but ONLY works + // correctly if it is a homogeneous transform matrix (rot + trans) + Matrix4 InvertedHomogeneousTransform() const { + // Make the inverse rotation matrix + Matrix4 rinv = this->Transposed(); + rinv.M[3][0] = rinv.M[3][1] = rinv.M[3][2] = T(0); + // Make the inverse translation matrix + Vector3 tvinv(-M[0][3], -M[1][3], -M[2][3]); + Matrix4 tinv = Matrix4::Translation(tvinv); + return rinv * tinv; // "untranslate", then "unrotate" + } + + // This is more efficient than general inverse, but ONLY works + // correctly if it is a homogeneous transform matrix (rot + trans) + void InvertHomogeneousTransform() { + *this = InvertedHomogeneousTransform(); + } + + // Matrix to Euler Angles conversion + // a,b,c, are the YawPitchRoll angles to be returned + // rotation a around axis A1 + // is followed by rotation b around axis A2 + // is followed by rotation c around axis A3 + // rotations are CCW or CW (D) in LH or RH coordinate system (S) + template + void ToEulerAngles(T* a, T* b, T* c) const { + OVR_MATH_STATIC_ASSERT( + (A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)"); + + T psign = T(-1); + if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation + psign = T(1); + + T pm = psign * M[A1][A3]; + T singularityRadius = Math::SingularityRadius(); + if (pm < T(-1) + singularityRadius) { // South pole singularity + *a = T(0); + *b = -S * D * ((T)MATH_DOUBLE_PIOVER2); + *c = S * D * atan2(psign * M[A2][A1], M[A2][A2]); + } else if (pm > T(1) - singularityRadius) { // North pole singularity + *a = T(0); + *b = S * D * ((T)MATH_DOUBLE_PIOVER2); + *c = S * D * atan2(psign * M[A2][A1], M[A2][A2]); + } else { // Normal case (nonsingular) + *a = S * D * atan2(-psign * M[A2][A3], M[A3][A3]); + *b = S * D * asin(pm); + *c = S * D * atan2(-psign * M[A1][A2], M[A1][A1]); + } + } + + // Matrix to Euler Angles conversion + // a,b,c, are the YawPitchRoll angles to be returned + // rotation a around axis A1 + // is followed by rotation b around axis A2 + // is followed by rotation c around axis A1 + // rotations are CCW or CW (D) in LH or RH coordinate system (S) + template + void ToEulerAnglesABA(T* a, T* b, T* c) const { + OVR_MATH_STATIC_ASSERT(A1 != A2, "A1 != A2"); + + // Determine the axis that was not supplied + int m = 3 - A1 - A2; + + T psign = T(-1); + if ((A1 + 1) % 3 == A2) // Determine whether even permutation + psign = T(1); + + T c2 = M[A1][A1]; + T singularityRadius = Math::SingularityRadius(); + if (c2 < T(-1) + singularityRadius) { // South pole singularity + *a = T(0); + *b = S * D * ((T)MATH_DOUBLE_PI); + *c = S * D * atan2(-psign * M[A2][m], M[A2][A2]); + } else if (c2 > T(1) - singularityRadius) { // North pole singularity + *a = T(0); + *b = T(0); + *c = S * D * atan2(-psign * M[A2][m], M[A2][A2]); + } else { // Normal case (nonsingular) + *a = S * D * atan2(M[A2][A1], -psign * M[m][A1]); + *b = S * D * acos(c2); + *c = S * D * atan2(M[A1][A2], psign * M[A1][m]); + } + } + + // Creates a matrix that converts the vertices from one coordinate system + // to another. + static Matrix4 AxisConversion(const WorldAxes& to, const WorldAxes& from) { + // Holds axis values from the 'to' structure + int toArray[3] = {to.XAxis, to.YAxis, to.ZAxis}; + + // The inverse of the toArray + int inv[4]; + inv[0] = inv[abs(to.XAxis)] = 0; + inv[abs(to.YAxis)] = 1; + inv[abs(to.ZAxis)] = 2; + + Matrix4 m(0, 0, 0, 0, 0, 0, 0, 0, 0); + + // Only three values in the matrix need to be changed to 1 or -1. + m.M[inv[abs(from.XAxis)]][0] = T(from.XAxis / toArray[inv[abs(from.XAxis)]]); + m.M[inv[abs(from.YAxis)]][1] = T(from.YAxis / toArray[inv[abs(from.YAxis)]]); + m.M[inv[abs(from.ZAxis)]][2] = T(from.ZAxis / toArray[inv[abs(from.ZAxis)]]); + return m; + } + + // Creates a matrix for translation by vector + static Matrix4 Translation(const Vector3& v) { + Matrix4 t; + t.M[0][3] = v.x; + t.M[1][3] = v.y; + t.M[2][3] = v.z; + return t; + } + + // Creates a matrix for translation by vector + static Matrix4 Translation(T x, T y, T z = T(0)) { + Matrix4 t; + t.M[0][3] = x; + t.M[1][3] = y; + t.M[2][3] = z; + return t; + } + + // Sets the translation part + void SetTranslation(const Vector3& v) { + M[0][3] = v.x; + M[1][3] = v.y; + M[2][3] = v.z; + } + + Vector3 GetTranslation() const { + return Vector3(M[0][3], M[1][3], M[2][3]); + } + + // Creates a matrix for scaling by vector + static Matrix4 Scaling(const Vector3& v) { + Matrix4 t; + t.M[0][0] = v.x; + t.M[1][1] = v.y; + t.M[2][2] = v.z; + return t; + } + + // Creates a matrix for scaling by vector + static Matrix4 Scaling(T x, T y, T z) { + Matrix4 t; + t.M[0][0] = x; + t.M[1][1] = y; + t.M[2][2] = z; + return t; + } + + // Creates a matrix for scaling by constant + static Matrix4 Scaling(T s) { + Matrix4 t; + t.M[0][0] = s; + t.M[1][1] = s; + t.M[2][2] = s; + return t; + } + + // Simple L1 distance in R^12 + T Distance(const Matrix4& m2) const { + T d = fabs(M[0][0] - m2.M[0][0]) + fabs(M[0][1] - m2.M[0][1]); + d += fabs(M[0][2] - m2.M[0][2]) + fabs(M[0][3] - m2.M[0][3]); + d += fabs(M[1][0] - m2.M[1][0]) + fabs(M[1][1] - m2.M[1][1]); + d += fabs(M[1][2] - m2.M[1][2]) + fabs(M[1][3] - m2.M[1][3]); + d += fabs(M[2][0] - m2.M[2][0]) + fabs(M[2][1] - m2.M[2][1]); + d += fabs(M[2][2] - m2.M[2][2]) + fabs(M[2][3] - m2.M[2][3]); + d += fabs(M[3][0] - m2.M[3][0]) + fabs(M[3][1] - m2.M[3][1]); + d += fabs(M[3][2] - m2.M[3][2]) + fabs(M[3][3] - m2.M[3][3]); + return d; + } + + // Creates a rotation matrix rotating around the X axis by 'angle' radians. + // Just for quick testing. Not for final API. Need to remove case. + static Matrix4 RotationAxis(Axis A, T angle, RotateDirection d, HandedSystem s) { + T sina = s * d * sin(angle); + T cosa = cos(angle); + + switch (A) { + case Axis_X: + return Matrix4(1, 0, 0, 0, cosa, -sina, 0, sina, cosa); + case Axis_Y: + return Matrix4(cosa, 0, sina, 0, 1, 0, -sina, 0, cosa); + case Axis_Z: + return Matrix4(cosa, -sina, 0, sina, cosa, 0, 0, 0, 1); + default: + return Matrix4(); + } + } + + // Creates a rotation matrix rotating around the X axis by 'angle' radians. + // Rotation direction is depends on the coordinate system: + // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), + // while looking in the negative axis direction. This is the + // same as looking down from positive axis values towards origin. + // LHS: Positive angle values rotate clock-wise (CW), while looking in the + // negative axis direction. + static Matrix4 RotationX(T angle) { + T sina = sin(angle); + T cosa = cos(angle); + return Matrix4(1, 0, 0, 0, cosa, -sina, 0, sina, cosa); + } + + // Creates a rotation matrix rotating around the Y axis by 'angle' radians. + // Rotation direction is depends on the coordinate system: + // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), + // while looking in the negative axis direction. This is the + // same as looking down from positive axis values towards origin. + // LHS: Positive angle values rotate clock-wise (CW), while looking in the + // negative axis direction. + static Matrix4 RotationY(T angle) { + T sina = (T)sin(angle); + T cosa = (T)cos(angle); + return Matrix4(cosa, 0, sina, 0, 1, 0, -sina, 0, cosa); + } + + // Creates a rotation matrix rotating around the Z axis by 'angle' radians. + // Rotation direction is depends on the coordinate system: + // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), + // while looking in the negative axis direction. This is the + // same as looking down from positive axis values towards origin. + // LHS: Positive angle values rotate clock-wise (CW), while looking in the + // negative axis direction. + static Matrix4 RotationZ(T angle) { + T sina = sin(angle); + T cosa = cos(angle); + return Matrix4(cosa, -sina, 0, sina, cosa, 0, 0, 0, 1); + } + + // LookAtRH creates a View transformation matrix for right-handed coordinate system. + // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up' + // specifying the up vector. The resulting matrix should be used with PerspectiveRH + // projection. + static Matrix4 LookAtRH(const Vector3& eye, const Vector3& at, const Vector3& up) { + Vector3 z = (eye - at).Normalized(); // Forward + Vector3 x = up.Cross(z).Normalized(); // Right + Vector3 y = z.Cross(x); + + Matrix4 m( + x.x, + x.y, + x.z, + -(x.Dot(eye)), + y.x, + y.y, + y.z, + -(y.Dot(eye)), + z.x, + z.y, + z.z, + -(z.Dot(eye)), + 0, + 0, + 0, + 1); + return m; + } + + // LookAtLH creates a View transformation matrix for left-handed coordinate system. + // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up' + // specifying the up vector. + static Matrix4 LookAtLH(const Vector3& eye, const Vector3& at, const Vector3& up) { + Vector3 z = (at - eye).Normalized(); // Forward + Vector3 x = up.Cross(z).Normalized(); // Right + Vector3 y = z.Cross(x); + + Matrix4 m( + x.x, + x.y, + x.z, + -(x.Dot(eye)), + y.x, + y.y, + y.z, + -(y.Dot(eye)), + z.x, + z.y, + z.z, + -(z.Dot(eye)), + 0, + 0, + 0, + 1); + return m; + } + + // PerspectiveRH creates a right-handed perspective projection matrix that can be + // used with the Oculus sample renderer. + // yfov - Specifies vertical field of view in radians. + // aspect - Screen aspect ration, which is usually width/height for square pixels. + // Note that xfov = yfov * aspect. + // znear - Absolute value of near Z clipping clipping range. + // zfar - Absolute value of far Z clipping clipping range (larger then near). + // Even though RHS usually looks in the direction of negative Z, positive values + // are expected for znear and zfar. + static Matrix4 PerspectiveRH(T yfov, T aspect, T znear, T zfar) { + Matrix4 m; + T tanHalfFov = (T)tan(yfov * T(0.5)); + + m.M[0][0] = T(1) / (aspect * tanHalfFov); + m.M[1][1] = T(1) / tanHalfFov; + m.M[2][2] = zfar / (znear - zfar); + m.M[3][2] = T(-1); + m.M[2][3] = (zfar * znear) / (znear - zfar); + m.M[3][3] = T(0); + + // Note: Post-projection matrix result assumes Left-Handed coordinate system, + // with Y up, X right and Z forward. This supports positive z-buffer values. + // This is the case even for RHS coordinate input. + return m; + } + + // PerspectiveLH creates a left-handed perspective projection matrix that can be + // used with the Oculus sample renderer. + // yfov - Specifies vertical field of view in radians. + // aspect - Screen aspect ration, which is usually width/height for square pixels. + // Note that xfov = yfov * aspect. + // znear - Absolute value of near Z clipping clipping range. + // zfar - Absolute value of far Z clipping clipping range (larger then near). + static Matrix4 PerspectiveLH(T yfov, T aspect, T znear, T zfar) { + Matrix4 m; + T tanHalfFov = (T)tan(yfov * T(0.5)); + + m.M[0][0] = T(1) / (aspect * tanHalfFov); + m.M[1][1] = T(1) / tanHalfFov; + // m.M[2][2] = zfar / (znear - zfar); + m.M[2][2] = zfar / (zfar - znear); + m.M[3][2] = T(-1); + m.M[2][3] = (zfar * znear) / (znear - zfar); + m.M[3][3] = T(0); + + // Note: Post-projection matrix result assumes Left-Handed coordinate system, + // with Y up, X right and Z forward. This supports positive z-buffer values. + // This is the case even for RHS coordinate input. + return m; + } + + static Matrix4 Ortho2D(T w, T h) { + Matrix4 m; + m.M[0][0] = T(2.0) / w; + m.M[1][1] = T(-2.0) / h; + m.M[0][3] = T(-1.0); + m.M[1][3] = T(1.0); + m.M[2][2] = T(0); + return m; + } +}; + +typedef Matrix4 Matrix4f; +typedef Matrix4 Matrix4d; + +//------------------------------------------------------------------------------------- +// ***** Matrix3 +// +// Matrix3 is a 3x3 matrix used for representing a rotation matrix. +// The matrix is stored in row-major order in memory, meaning that values +// of the first row are stored before the next one. +// +// The arrangement of the matrix is chosen to be in Right-Handed +// coordinate system and counterclockwise rotations when looking down +// the axis +// +// Transformation Order: +// - Transformations are applied from right to left, so the expression +// M1 * M2 * M3 * V means that the vector V is transformed by M3 first, +// followed by M2 and M1. +// +// Coordinate system: Right Handed +// +// Rotations: Counterclockwise when looking down the axis. All angles are in radians. + +template +class Matrix3 { + public: + typedef T ElementType; + static const size_t Dimension = 3; + + T M[3][3]; + + enum NoInitType { NoInit }; + + // Construct with no memory initialization. + Matrix3(NoInitType) {} + + // By default, we construct identity matrix. + Matrix3() { + M[0][0] = M[1][1] = M[2][2] = T(1); + M[0][1] = M[1][0] = M[2][0] = T(0); + M[0][2] = M[1][2] = M[2][1] = T(0); + } + + Matrix3(T m11, T m12, T m13, T m21, T m22, T m23, T m31, T m32, T m33) { + M[0][0] = m11; + M[0][1] = m12; + M[0][2] = m13; + M[1][0] = m21; + M[1][1] = m22; + M[1][2] = m23; + M[2][0] = m31; + M[2][1] = m32; + M[2][2] = m33; + } + + // Construction from X, Y, Z basis vectors + Matrix3(const Vector3& xBasis, const Vector3& yBasis, const Vector3& zBasis) { + M[0][0] = xBasis.x; + M[0][1] = yBasis.x; + M[0][2] = zBasis.x; + M[1][0] = xBasis.y; + M[1][1] = yBasis.y; + M[1][2] = zBasis.y; + M[2][0] = xBasis.z; + M[2][1] = yBasis.z; + M[2][2] = zBasis.z; + } + + explicit Matrix3(const Quat& q) { + OVR_MATH_ASSERT(q.IsNormalized()); // If this fires, caller has a quat math bug + const T tx = q.x + q.x, ty = q.y + q.y, tz = q.z + q.z; + const T twx = q.w * tx, twy = q.w * ty, twz = q.w * tz; + const T txx = q.x * tx, txy = q.x * ty, txz = q.x * tz; + const T tyy = q.y * ty, tyz = q.y * tz, tzz = q.z * tz; + M[0][0] = T(1) - (tyy + tzz); + M[0][1] = txy - twz; + M[0][2] = txz + twy; + M[1][0] = txy + twz; + M[1][1] = T(1) - (txx + tzz); + M[1][2] = tyz - twx; + M[2][0] = txz - twy; + M[2][1] = tyz + twx; + M[2][2] = T(1) - (txx + tyy); + } + + inline explicit Matrix3(T s) { + M[0][0] = M[1][1] = M[2][2] = s; + M[0][1] = M[0][2] = M[1][0] = M[1][2] = M[2][0] = M[2][1] = T(0); + } + + Matrix3(T m11, T m22, T m33) { + M[0][0] = m11; + M[0][1] = T(0); + M[0][2] = T(0); + M[1][0] = T(0); + M[1][1] = m22; + M[1][2] = T(0); + M[2][0] = T(0); + M[2][1] = T(0); + M[2][2] = m33; + } + + explicit Matrix3(const Matrix3::OtherFloatType>& src) { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + M[i][j] = (T)src.M[i][j]; + } + + // C-interop support. + Matrix3(const typename CompatibleTypes>::Type& s) { + OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix3), "sizeof(s) == sizeof(Matrix3)"); + memcpy(M, s.M, sizeof(M)); + } + + operator const typename CompatibleTypes>::Type() const { + typename CompatibleTypes>::Type result; + OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix3), "sizeof(result) == sizeof(Matrix3)"); + memcpy(result.M, M, sizeof(M)); + return result; + } + + T operator()(int i, int j) const { + return M[i][j]; + } + T& operator()(int i, int j) { + return M[i][j]; + } + + void ToString(char* dest, size_t destsize) const { + size_t pos = 0; + for (int r = 0; r < 3; r++) { + for (int c = 0; c < 3; c++) + pos += OVRMath_sprintf(dest + pos, destsize - pos, "%g ", M[r][c]); + } + } + + static Matrix3 FromString(const char* src) { + Matrix3 result; + if (src) { + for (int r = 0; r < 3; r++) { + for (int c = 0; c < 3; c++) { + result.M[r][c] = (T)atof(src); + while (*src && *src != ' ') + src++; + while (*src && *src == ' ') + src++; + } + } + } + return result; + } + + static Matrix3 Identity() { + return Matrix3(); + } + + void SetIdentity() { + M[0][0] = M[1][1] = M[2][2] = T(1); + M[0][1] = M[1][0] = M[2][0] = T(0); + M[0][2] = M[1][2] = M[2][1] = T(0); + } + + static Matrix3 Diagonal(T m00, T m11, T m22) { + return Matrix3(m00, 0, 0, 0, m11, 0, 0, 0, m22); + } + static Matrix3 Diagonal(const Vector3& v) { + return Diagonal(v.x, v.y, v.z); + } + + T Trace() const { + return M[0][0] + M[1][1] + M[2][2]; + } + + bool operator==(const Matrix3& b) const { + bool isEqual = true; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) + isEqual &= (M[i][j] == b.M[i][j]); + } + + return isEqual; + } + + Matrix3 operator+(const Matrix3& b) const { + Matrix3 result(*this); + result += b; + return result; + } + + Matrix3& operator+=(const Matrix3& b) { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + M[i][j] += b.M[i][j]; + return *this; + } + + void operator=(const Matrix3& b) { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + M[i][j] = b.M[i][j]; + } + + Matrix3 operator-(const Matrix3& b) const { + Matrix3 result(*this); + result -= b; + return result; + } + + Matrix3& operator-=(const Matrix3& b) { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) + M[i][j] -= b.M[i][j]; + } + + return *this; + } + + // Multiplies two matrices into destination with minimum copying. + static Matrix3& Multiply(Matrix3* d, const Matrix3& a, const Matrix3& b) { + OVR_MATH_ASSERT((d != &a) && (d != &b)); + int i = 0; + do { + d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0]; + d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1]; + d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2]; + } while ((++i) < 3); + + return *d; + } + + Matrix3 operator*(const Matrix3& b) const { + Matrix3 result(Matrix3::NoInit); + Multiply(&result, *this, b); + return result; + } + + Matrix3& operator*=(const Matrix3& b) { + return Multiply(this, Matrix3(*this), b); + } + + Matrix3 operator*(T s) const { + Matrix3 result(*this); + result *= s; + return result; + } + + Matrix3& operator*=(T s) { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) + M[i][j] *= s; + } + + return *this; + } + + Vector3 operator*(const Vector3& b) const { + Vector3 result; + result.x = M[0][0] * b.x + M[0][1] * b.y + M[0][2] * b.z; + result.y = M[1][0] * b.x + M[1][1] * b.y + M[1][2] * b.z; + result.z = M[2][0] * b.x + M[2][1] * b.y + M[2][2] * b.z; + + return result; + } + + Matrix3 operator/(T s) const { + Matrix3 result(*this); + result /= s; + return result; + } + + Matrix3& operator/=(T s) { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) + M[i][j] /= s; + } + + return *this; + } + + Vector2 Transform(const Vector2& v) const { + const T rcpZ = T(1) / (M[2][0] * v.x + M[2][1] * v.y + M[2][2]); + return Vector2( + (M[0][0] * v.x + M[0][1] * v.y + M[0][2]) * rcpZ, + (M[1][0] * v.x + M[1][1] * v.y + M[1][2]) * rcpZ); + } + + Vector3 Transform(const Vector3& v) const { + return Vector3( + M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z, + M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z, + M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z); + } + + Matrix3 Transposed() const { + return Matrix3(M[0][0], M[1][0], M[2][0], M[0][1], M[1][1], M[2][1], M[0][2], M[1][2], M[2][2]); + } + + void Transpose() { + *this = Transposed(); + } + + T SubDet(const size_t* rows, const size_t* cols) const { + return M[rows[0]][cols[0]] * + (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]]) - + M[rows[0]][cols[1]] * + (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]]) + + M[rows[0]][cols[2]] * + (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]); + } + + // M += a*b.t() + inline void Rank1Add(const Vector3& a, const Vector3& b) { + M[0][0] += a.x * b.x; + M[0][1] += a.x * b.y; + M[0][2] += a.x * b.z; + M[1][0] += a.y * b.x; + M[1][1] += a.y * b.y; + M[1][2] += a.y * b.z; + M[2][0] += a.z * b.x; + M[2][1] += a.z * b.y; + M[2][2] += a.z * b.z; + } + + // M -= a*b.t() + inline void Rank1Sub(const Vector3& a, const Vector3& b) { + M[0][0] -= a.x * b.x; + M[0][1] -= a.x * b.y; + M[0][2] -= a.x * b.z; + M[1][0] -= a.y * b.x; + M[1][1] -= a.y * b.y; + M[1][2] -= a.y * b.z; + M[2][0] -= a.z * b.x; + M[2][1] -= a.z * b.y; + M[2][2] -= a.z * b.z; + } + + inline Vector3 Col(int c) const { + return Vector3(M[0][c], M[1][c], M[2][c]); + } + + inline Vector3 Row(int r) const { + return Vector3(M[r][0], M[r][1], M[r][2]); + } + + inline Vector3 GetColumn(int c) const { + return Vector3(M[0][c], M[1][c], M[2][c]); + } + + inline Vector3 GetRow(int r) const { + return Vector3(M[r][0], M[r][1], M[r][2]); + } + + inline void SetColumn(int c, const Vector3& v) { + M[0][c] = v.x; + M[1][c] = v.y; + M[2][c] = v.z; + } + + inline void SetRow(int r, const Vector3& v) { + M[r][0] = v.x; + M[r][1] = v.y; + M[r][2] = v.z; + } + + inline T Determinant() const { + const Matrix3& m = *this; + T d; + + d = m.M[0][0] * (m.M[1][1] * m.M[2][2] - m.M[1][2] * m.M[2][1]); + d -= m.M[0][1] * (m.M[1][0] * m.M[2][2] - m.M[1][2] * m.M[2][0]); + d += m.M[0][2] * (m.M[1][0] * m.M[2][1] - m.M[1][1] * m.M[2][0]); + + return d; + } + + inline Matrix3 Inverse() const { + Matrix3 a; + const Matrix3& m = *this; + T d = Determinant(); + + OVR_MATH_ASSERT(d != 0); + T s = T(1) / d; + + a.M[0][0] = s * (m.M[1][1] * m.M[2][2] - m.M[1][2] * m.M[2][1]); + a.M[1][0] = s * (m.M[1][2] * m.M[2][0] - m.M[1][0] * m.M[2][2]); + a.M[2][0] = s * (m.M[1][0] * m.M[2][1] - m.M[1][1] * m.M[2][0]); + + a.M[0][1] = s * (m.M[0][2] * m.M[2][1] - m.M[0][1] * m.M[2][2]); + a.M[1][1] = s * (m.M[0][0] * m.M[2][2] - m.M[0][2] * m.M[2][0]); + a.M[2][1] = s * (m.M[0][1] * m.M[2][0] - m.M[0][0] * m.M[2][1]); + + a.M[0][2] = s * (m.M[0][1] * m.M[1][2] - m.M[0][2] * m.M[1][1]); + a.M[1][2] = s * (m.M[0][2] * m.M[1][0] - m.M[0][0] * m.M[1][2]); + a.M[2][2] = s * (m.M[0][0] * m.M[1][1] - m.M[0][1] * m.M[1][0]); + + return a; + } + + // Outer Product of two column vectors: a * b.Transpose() + static Matrix3 OuterProduct(const Vector3& a, const Vector3& b) { + return Matrix3( + a.x * b.x, + a.x * b.y, + a.x * b.z, + a.y * b.x, + a.y * b.y, + a.y * b.z, + a.z * b.x, + a.z * b.y, + a.z * b.z); + } + + // Vector cross product as a premultiply matrix: + // L.Cross(R) = LeftCrossAsMatrix(L) * R + static Matrix3 LeftCrossAsMatrix(const Vector3& L) { + return Matrix3(T(0), -L.z, +L.y, +L.z, T(0), -L.x, -L.y, +L.x, T(0)); + } + + // Vector cross product as a premultiply matrix: + // L.Cross(R) = RightCrossAsMatrix(R) * L + static Matrix3 RightCrossAsMatrix(const Vector3& R) { + return Matrix3(T(0), +R.z, -R.y, -R.z, T(0), +R.x, +R.y, -R.x, T(0)); + } + + // Angle in radians of a rotation matrix + // Uses identity trace(a) = 2*cos(theta) + 1 + T Angle() const { + return Acos((Trace() - T(1)) * T(0.5)); + } + + // Angle in radians between two rotation matrices + T Angle(const Matrix3& b) const { + // Compute trace of (this->Transposed() * b) + // This works out to sum of products of elements. + T trace = T(0); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + trace += M[i][j] * b.M[i][j]; + } + } + return Acos((trace - T(1)) * T(0.5)); + } +}; + +typedef Matrix3 Matrix3f; +typedef Matrix3 Matrix3d; + +//------------------------------------------------------------------------------------- +// ***** Matrix2 + +template +class Matrix2 { + public: + typedef T ElementType; + static const size_t Dimension = 2; + + T M[2][2]; + + enum NoInitType { NoInit }; + + // Construct with no memory initialization. + Matrix2(NoInitType) {} + + // By default, we construct identity matrix. + Matrix2() { + M[0][0] = M[1][1] = T(1); + M[0][1] = M[1][0] = T(0); + } + + Matrix2(T m11, T m12, T m21, T m22) { + M[0][0] = m11; + M[0][1] = m12; + M[1][0] = m21; + M[1][1] = m22; + } + + // Construction from X, Y basis vectors + Matrix2(const Vector2& xBasis, const Vector2& yBasis) { + M[0][0] = xBasis.x; + M[0][1] = yBasis.x; + M[1][0] = xBasis.y; + M[1][1] = yBasis.y; + } + + explicit Matrix2(T s) { + M[0][0] = M[1][1] = s; + M[0][1] = M[1][0] = T(0); + } + + Matrix2(T m11, T m22) { + M[0][0] = m11; + M[0][1] = T(0); + M[1][0] = T(0); + M[1][1] = m22; + } + + explicit Matrix2(const Matrix2::OtherFloatType>& src) { + M[0][0] = T(src.M[0][0]); + M[0][1] = T(src.M[0][1]); + M[1][0] = T(src.M[1][0]); + M[1][1] = T(src.M[1][1]); + } + + // C-interop support + Matrix2(const typename CompatibleTypes>::Type& s) { + OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix2), "sizeof(s) == sizeof(Matrix2)"); + memcpy(M, s.M, sizeof(M)); + } + + operator const typename CompatibleTypes>::Type() const { + typename CompatibleTypes>::Type result; + OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix2), "sizeof(result) == sizeof(Matrix2)"); + memcpy(result.M, M, sizeof(M)); + return result; + } + + T operator()(int i, int j) const { + return M[i][j]; + } + T& operator()(int i, int j) { + return M[i][j]; + } + const T* operator[](int i) const { + return M[i]; + } + T* operator[](int i) { + return M[i]; + } + + static Matrix2 Identity() { + return Matrix2(); + } + + void SetIdentity() { + M[0][0] = M[1][1] = T(1); + M[0][1] = M[1][0] = T(0); + } + + static Matrix2 Diagonal(T m00, T m11) { + return Matrix2(m00, m11); + } + static Matrix2 Diagonal(const Vector2& v) { + return Matrix2(v.x, v.y); + } + + T Trace() const { + return M[0][0] + M[1][1]; + } + + bool operator==(const Matrix2& b) const { + return M[0][0] == b.M[0][0] && M[0][1] == b.M[0][1] && M[1][0] == b.M[1][0] && + M[1][1] == b.M[1][1]; + } + + Matrix2 operator+(const Matrix2& b) const { + return Matrix2( + M[0][0] + b.M[0][0], M[0][1] + b.M[0][1], M[1][0] + b.M[1][0], M[1][1] + b.M[1][1]); + } + + Matrix2& operator+=(const Matrix2& b) { + M[0][0] += b.M[0][0]; + M[0][1] += b.M[0][1]; + M[1][0] += b.M[1][0]; + M[1][1] += b.M[1][1]; + return *this; + } + + void operator=(const Matrix2& b) { + M[0][0] = b.M[0][0]; + M[0][1] = b.M[0][1]; + M[1][0] = b.M[1][0]; + M[1][1] = b.M[1][1]; + } + + Matrix2 operator-(const Matrix2& b) const { + return Matrix2( + M[0][0] - b.M[0][0], M[0][1] - b.M[0][1], M[1][0] - b.M[1][0], M[1][1] - b.M[1][1]); + } + + Matrix2& operator-=(const Matrix2& b) { + M[0][0] -= b.M[0][0]; + M[0][1] -= b.M[0][1]; + M[1][0] -= b.M[1][0]; + M[1][1] -= b.M[1][1]; + return *this; + } + + Matrix2 operator*(const Matrix2& b) const { + return Matrix2( + M[0][0] * b.M[0][0] + M[0][1] * b.M[1][0], + M[0][0] * b.M[0][1] + M[0][1] * b.M[1][1], + M[1][0] * b.M[0][0] + M[1][1] * b.M[1][0], + M[1][0] * b.M[0][1] + M[1][1] * b.M[1][1]); + } + + Matrix2& operator*=(const Matrix2& b) { + *this = *this * b; + return *this; + } + + Matrix2 operator*(T s) const { + return Matrix2(M[0][0] * s, M[0][1] * s, M[1][0] * s, M[1][1] * s); + } + + Matrix2& operator*=(T s) { + M[0][0] *= s; + M[0][1] *= s; + M[1][0] *= s; + M[1][1] *= s; + return *this; + } + + Matrix2 operator/(T s) const { + return *this * (T(1) / s); + } + + Matrix2& operator/=(T s) { + return *this *= (T(1) / s); + } + + Vector2 operator*(const Vector2& b) const { + return Vector2(M[0][0] * b.x + M[0][1] * b.y, M[1][0] * b.x + M[1][1] * b.y); + } + + Vector2 Transform(const Vector2& v) const { + return Vector2(M[0][0] * v.x + M[0][1] * v.y, M[1][0] * v.x + M[1][1] * v.y); + } + + Matrix2 Transposed() const { + return Matrix2(M[0][0], M[1][0], M[0][1], M[1][1]); + } + + void Transpose() { + OVRMath_Swap(M[1][0], M[0][1]); + } + + Vector2 GetColumn(int c) const { + return Vector2(M[0][c], M[1][c]); + } + + Vector2 GetRow(int r) const { + return Vector2(M[r][0], M[r][1]); + } + + void SetColumn(int c, const Vector2& v) { + M[0][c] = v.x; + M[1][c] = v.y; + } + + void SetRow(int r, const Vector2& v) { + M[r][0] = v.x; + M[r][1] = v.y; + } + + T Determinant() const { + return M[0][0] * M[1][1] - M[0][1] * M[1][0]; + } + + Matrix2 Inverse() const { + T rcpDet = T(1) / Determinant(); + return Matrix2(M[1][1] * rcpDet, -M[0][1] * rcpDet, -M[1][0] * rcpDet, M[0][0] * rcpDet); + } + + // Outer Product of two column vectors: a * b.Transpose() + static Matrix2 OuterProduct(const Vector2& a, const Vector2& b) { + return Matrix2(a.x * b.x, a.x * b.y, a.y * b.x, a.y * b.y); + } + + // Angle in radians between two rotation matrices + T Angle(const Matrix2& b) const { + const Matrix2& a = *this; + return Acos(a(0, 0) * b(0, 0) + a(1, 0) * b(1, 0)); + } +}; + +typedef Matrix2 Matrix2f; +typedef Matrix2 Matrix2d; + +//------------------------------------------------------------------------------------- + +template +class SymMat3 { + private: + typedef SymMat3 this_type; + + public: + typedef T Value_t; + // Upper symmetric + T v[6]; // _00 _01 _02 _11 _12 _22 + + inline SymMat3() {} + + inline explicit SymMat3(T s) { + v[0] = v[3] = v[5] = s; + v[1] = v[2] = v[4] = T(0); + } + + inline explicit SymMat3(T a00, T a01, T a02, T a11, T a12, T a22) { + v[0] = a00; + v[1] = a01; + v[2] = a02; + v[3] = a11; + v[4] = a12; + v[5] = a22; + } + + // Cast to symmetric Matrix3 + operator Matrix3() const { + return Matrix3(v[0], v[1], v[2], v[1], v[3], v[4], v[2], v[4], v[5]); + } + + static inline int Index(unsigned int i, unsigned int j) { + return (i <= j) ? (3 * i - i * (i + 1) / 2 + j) : (3 * j - j * (j + 1) / 2 + i); + } + + inline T operator()(int i, int j) const { + return v[Index(i, j)]; + } + + inline T& operator()(int i, int j) { + return v[Index(i, j)]; + } + + inline this_type& operator+=(const this_type& b) { + v[0] += b.v[0]; + v[1] += b.v[1]; + v[2] += b.v[2]; + v[3] += b.v[3]; + v[4] += b.v[4]; + v[5] += b.v[5]; + return *this; + } + + inline this_type& operator-=(const this_type& b) { + v[0] -= b.v[0]; + v[1] -= b.v[1]; + v[2] -= b.v[2]; + v[3] -= b.v[3]; + v[4] -= b.v[4]; + v[5] -= b.v[5]; + + return *this; + } + + inline this_type& operator*=(T s) { + v[0] *= s; + v[1] *= s; + v[2] *= s; + v[3] *= s; + v[4] *= s; + v[5] *= s; + + return *this; + } + + inline SymMat3 operator*(T s) const { + SymMat3 d; + d.v[0] = v[0] * s; + d.v[1] = v[1] * s; + d.v[2] = v[2] * s; + d.v[3] = v[3] * s; + d.v[4] = v[4] * s; + d.v[5] = v[5] * s; + + return d; + } + + // Multiplies two matrices into destination with minimum copying. + static SymMat3& Multiply(SymMat3* d, const SymMat3& a, const SymMat3& b) { + // _00 _01 _02 _11 _12 _22 + + d->v[0] = a.v[0] * b.v[0]; + d->v[1] = a.v[0] * b.v[1] + a.v[1] * b.v[3]; + d->v[2] = a.v[0] * b.v[2] + a.v[1] * b.v[4]; + + d->v[3] = a.v[3] * b.v[3]; + d->v[4] = a.v[3] * b.v[4] + a.v[4] * b.v[5]; + + d->v[5] = a.v[5] * b.v[5]; + + return *d; + } + + inline T Determinant() const { + const this_type& m = *this; + T d; + + d = m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)); + d -= m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)); + d += m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0)); + + return d; + } + + inline this_type Inverse() const { + this_type a; + const this_type& m = *this; + T d = Determinant(); + + OVR_MATH_ASSERT(d != 0); + T s = T(1) / d; + + a(0, 0) = s * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)); + + a(0, 1) = s * (m(0, 2) * m(2, 1) - m(0, 1) * m(2, 2)); + a(1, 1) = s * (m(0, 0) * m(2, 2) - m(0, 2) * m(2, 0)); + + a(0, 2) = s * (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)); + a(1, 2) = s * (m(0, 2) * m(1, 0) - m(0, 0) * m(1, 2)); + a(2, 2) = s * (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)); + + return a; + } + + inline T Trace() const { + return v[0] + v[3] + v[5]; + } + + // M = a*a.t() + inline void Rank1(const Vector3& a) { + v[0] = a.x * a.x; + v[1] = a.x * a.y; + v[2] = a.x * a.z; + v[3] = a.y * a.y; + v[4] = a.y * a.z; + v[5] = a.z * a.z; + } + + // M += a*a.t() + inline void Rank1Add(const Vector3& a) { + v[0] += a.x * a.x; + v[1] += a.x * a.y; + v[2] += a.x * a.z; + v[3] += a.y * a.y; + v[4] += a.y * a.z; + v[5] += a.z * a.z; + } + + // M -= a*a.t() + inline void Rank1Sub(const Vector3& a) { + v[0] -= a.x * a.x; + v[1] -= a.x * a.y; + v[2] -= a.x * a.z; + v[3] -= a.y * a.y; + v[4] -= a.y * a.z; + v[5] -= a.z * a.z; + } +}; + +typedef SymMat3 SymMat3f; +typedef SymMat3 SymMat3d; + +template +inline Matrix3 operator*(const SymMat3& a, const SymMat3& b) { +#define AJB_ARBC(r, c) (a(r, 0) * b(0, c) + a(r, 1) * b(1, c) + a(r, 2) * b(2, c)) + return Matrix3( + AJB_ARBC(0, 0), + AJB_ARBC(0, 1), + AJB_ARBC(0, 2), + AJB_ARBC(1, 0), + AJB_ARBC(1, 1), + AJB_ARBC(1, 2), + AJB_ARBC(2, 0), + AJB_ARBC(2, 1), + AJB_ARBC(2, 2)); +#undef AJB_ARBC +} + +template +inline Matrix3 operator*(const Matrix3& a, const SymMat3& b) { +#define AJB_ARBC(r, c) (a(r, 0) * b(0, c) + a(r, 1) * b(1, c) + a(r, 2) * b(2, c)) + return Matrix3( + AJB_ARBC(0, 0), + AJB_ARBC(0, 1), + AJB_ARBC(0, 2), + AJB_ARBC(1, 0), + AJB_ARBC(1, 1), + AJB_ARBC(1, 2), + AJB_ARBC(2, 0), + AJB_ARBC(2, 1), + AJB_ARBC(2, 2)); +#undef AJB_ARBC +} + +//------------------------------------------------------------------------------------- +// ***** Angle + +// Cleanly representing the algebra of 2D rotations. +// The operations maintain the angle between -Pi and Pi, the same range as atan2. + +template +class Angle { + public: + enum AngularUnits { Radians = 0, Degrees = 1 }; + + Angle() : a(0) {} + + // Fix the range to be between -Pi and Pi + Angle(T a_, AngularUnits u = Radians) + : a((u == Radians) ? a_ : a_ * ((T)MATH_DOUBLE_DEGREETORADFACTOR)) { + FixRange(); + } + + T Get(AngularUnits u = Radians) const { + return (u == Radians) ? a : a * ((T)MATH_DOUBLE_RADTODEGREEFACTOR); + } + void Set(const T& x, AngularUnits u = Radians) { + a = (u == Radians) ? x : x * ((T)MATH_DOUBLE_DEGREETORADFACTOR); + FixRange(); + } + int Sign() const { + if (a == 0) + return 0; + else + return (a > 0) ? 1 : -1; + } + T Abs() const { + return (a >= 0) ? a : -a; + } + + bool operator==(const Angle& b) const { + return a == b.a; + } + bool operator!=(const Angle& b) const { + return a != b.a; + } + // bool operator< (const Angle& b) const { return a < a.b; } + // bool operator> (const Angle& b) const { return a > a.b; } + // bool operator<= (const Angle& b) const { return a <= a.b; } + // bool operator>= (const Angle& b) const { return a >= a.b; } + // bool operator= (const T& x) { a = x; FixRange(); } + + // These operations assume a is already between -Pi and Pi. + Angle& operator+=(const Angle& b) { + a = a + b.a; + FastFixRange(); + return *this; + } + Angle& operator+=(const T& x) { + a = a + x; + FixRange(); + return *this; + } + Angle operator+(const Angle& b) const { + Angle res = *this; + res += b; + return res; + } + Angle operator+(const T& x) const { + Angle res = *this; + res += x; + return res; + } + Angle& operator-=(const Angle& b) { + a = a - b.a; + FastFixRange(); + return *this; + } + Angle& operator-=(const T& x) { + a = a - x; + FixRange(); + return *this; + } + Angle operator-(const Angle& b) const { + Angle res = *this; + res -= b; + return res; + } + Angle operator-(const T& x) const { + Angle res = *this; + res -= x; + return res; + } + Angle& operator*=(const T& x) { + a = a * x; + FixRange(); + return *this; + } + Angle operator*(const T& x) const { + Angle res = *this; + res *= x; + return res; + } + + T Distance(const Angle& b) { + T c = fabs(a - b.a); + return (c <= ((T)MATH_DOUBLE_PI)) ? c : ((T)MATH_DOUBLE_TWOPI) - c; + } + + Angle Lerp(const Angle& b, T f) const { + return *this + (b - *this) * f; + } + + private: + // The stored angle, which should be maintained between -Pi and Pi + T a; + + // Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side + inline void FastFixRange() { + if (a < -((T)MATH_DOUBLE_PI)) + a += ((T)MATH_DOUBLE_TWOPI); + else if (a > ((T)MATH_DOUBLE_PI)) + a -= ((T)MATH_DOUBLE_TWOPI); + } + + // Fixes the angle range to [-Pi,Pi] for any given range, but slower then the fast method + inline void FixRange() { + // do nothing if the value is already in the correct range, since fmod call is expensive + if (a >= -((T)MATH_DOUBLE_PI) && a <= ((T)MATH_DOUBLE_PI)) + return; + a = fmod(a, ((T)MATH_DOUBLE_TWOPI)); + if (a < -((T)MATH_DOUBLE_PI)) + a += ((T)MATH_DOUBLE_TWOPI); + else if (a > ((T)MATH_DOUBLE_PI)) + a -= ((T)MATH_DOUBLE_TWOPI); + } +}; + +typedef Angle Anglef; +typedef Angle Angled; + +//------------------------------------------------------------------------------------- +// ***** Plane + +// Consists of a normal vector and distance from the origin where the plane is located. + +template +class Plane { + public: + Vector3 N; + T D; + + Plane() : D(0) {} + + // Normals must already be normalized + Plane(const Vector3& n, T d) : N(n), D(d) {} + Plane(T x, T y, T z, T d) : N(x, y, z), D(d) {} + + // construct from a point on the plane and the normal + Plane(const Vector3& p, const Vector3& n) : N(n), D(-(p.Dot(n))) {} + + // Find the point to plane distance. The sign indicates what side of the plane the point is on (0 + // = point on plane). + T TestSide(const Vector3& p) const { + return (N.Dot(p)) + D; + } + + Plane Flipped() const { + return Plane(-N, -D); + } + + void Flip() { + N = -N; + D = -D; + } + + bool operator==(const Plane& rhs) const { + return (this->D == rhs.D && this->N == rhs.N); + } +}; + +typedef Plane Planef; +typedef Plane Planed; + +//----------------------------------------------------------------------------------- +// ***** ScaleAndOffset + +template +struct ScaleAndOffset { + T Scale; + T Offset; + + ScaleAndOffset(float sx = 0.0f, float sy = 0.0f, float ox = 0.0f, float oy = 0.0f) + : Scale(sx, sy), Offset(ox, oy) {} + + T ApplyTo(const T& input) const { + return input * Scale + Offset; + } + + ScaleAndOffset Invert() const { + ScaleAndOffset inverted; + inverted.Scale = T(1.0f) / this->Scale; + inverted.Offset = -(this->Offset) * inverted.Scale; + return inverted; + } + + // nextSO is the other scale-offset operation that would have normally followed this scale-offset. + // Result is a single scale-offset operation that can be applied to an input instead of + // two or more separate scale-offset applications on a given Vector2f input. + // + // So this: + // ScaleAndOffset2D so1, so2, so3; // initialized to some values + // Vector2f input = Vector2f(2.0f, -1.0f); + // input = so1.ApplyTo(input); + // input = so2.ApplyTo(input); + // input = so3.ApplyTo(input); + // + // equals this: + // ScaleAndOffset2D so1, so2, so3; // initialized to some values + // so1 = so1.Combine(so2); + // so1 = so1.Combine(so3); + // Vector2f input = Vector2f(2.0f, -1.0f); + // input = so1.ApplyTo(input); + // + ScaleAndOffset Combine(const ScaleAndOffset& nextSO) const { + ScaleAndOffset retValSO; + retValSO.Offset = this->Offset * nextSO.Scale + nextSO.Offset; + retValSO.Scale = nextSO.Scale * this->Scale; + return retValSO; + } +}; + +typedef ScaleAndOffset ScaleAndOffset2D; +typedef ScaleAndOffset ScaleAndOffset3D; + +//----------------------------------------------------------------------------------- +// ***** FovPort + +// FovPort describes Field Of View (FOV) of a viewport. +// This class has values for up, down, left and right, stored in +// tangent of the angle units to simplify calculations. +// +// As an example, for a standard 90 degree vertical FOV, we would +// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }. +// +// CreateFromRadians/Degrees helper functions can be used to +// access FOV in different units. + +// ***** FovPort + +struct FovPort { + float UpTan; + float DownTan; + float LeftTan; + float RightTan; + + FovPort(float sideTan = 0.0f) + : UpTan(sideTan), DownTan(sideTan), LeftTan(sideTan), RightTan(sideTan) {} + FovPort(float u, float d, float l, float r) : UpTan(u), DownTan(d), LeftTan(l), RightTan(r) {} + +#ifndef OVR_EXCLUDE_CAPI_FROM_MATH + // C-interop support. + typedef CompatibleTypes::Type CompatibleType; + + FovPort(const CompatibleType& s) + : UpTan(s.UpTan), DownTan(s.DownTan), LeftTan(s.LeftTan), RightTan(s.RightTan) {} + + operator const CompatibleType&() const { + OVR_MATH_STATIC_ASSERT(sizeof(FovPort) == sizeof(CompatibleType), "sizeof(FovPort) failure"); + return reinterpret_cast(*this); + } +#endif + + static FovPort CreateFromRadians(float horizontalFov, float verticalFov) { + FovPort result; + result.UpTan = tanf(verticalFov * 0.5f); + result.DownTan = tanf(verticalFov * 0.5f); + result.LeftTan = tanf(horizontalFov * 0.5f); + result.RightTan = tanf(horizontalFov * 0.5f); + return result; + } + + static FovPort CreateFromDegrees(float horizontalFovDegrees, float verticalFovDegrees) { + return CreateFromRadians(DegreeToRad(horizontalFovDegrees), DegreeToRad(verticalFovDegrees)); + } + + // Get Horizontal/Vertical components of Fov in radians. + float GetVerticalFovRadians() const { + return atanf(UpTan) + atanf(DownTan); + } + float GetHorizontalFovRadians() const { + return atanf(LeftTan) + atanf(RightTan); + } + // Get Horizontal/Vertical components of Fov in degrees. + float GetVerticalFovDegrees() const { + return RadToDegree(GetVerticalFovRadians()); + } + float GetHorizontalFovDegrees() const { + return RadToDegree(GetHorizontalFovRadians()); + } + + // Compute maximum tangent value among all four sides. + float GetMaxSideTan() const { + return OVRMath_Max(OVRMath_Max(UpTan, DownTan), OVRMath_Max(LeftTan, RightTan)); + } + + static ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov(FovPort tanHalfFov) { + float projXScale = 2.0f / (tanHalfFov.LeftTan + tanHalfFov.RightTan); + float projXOffset = (tanHalfFov.LeftTan - tanHalfFov.RightTan) * projXScale * 0.5f; + float projYScale = 2.0f / (tanHalfFov.UpTan + tanHalfFov.DownTan); + float projYOffset = (tanHalfFov.UpTan - tanHalfFov.DownTan) * projYScale * 0.5f; + + ScaleAndOffset2D result; + result.Scale = Vector2f(projXScale, projYScale); + result.Offset = Vector2f(projXOffset, projYOffset); + // Hey - why is that Y.Offset negated? + // It's because a projection matrix transforms from world coords with Y=up, + // whereas this is from NDC which is Y=down. + + return result; + } + + // Converts Fov Tan angle units to [-1,1] render target NDC space + Vector2f TanAngleToRendertargetNDC(Vector2f const& tanEyeAngle) { + ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(*this); + return tanEyeAngle * eyeToSourceNDC.Scale + eyeToSourceNDC.Offset; + } + + // Compute per-channel minimum and maximum of Fov. + static FovPort Min(const FovPort& a, const FovPort& b) { + FovPort fov( + OVRMath_Min(a.UpTan, b.UpTan), + OVRMath_Min(a.DownTan, b.DownTan), + OVRMath_Min(a.LeftTan, b.LeftTan), + OVRMath_Min(a.RightTan, b.RightTan)); + return fov; + } + + static FovPort Max(const FovPort& a, const FovPort& b) { + FovPort fov( + OVRMath_Max(a.UpTan, b.UpTan), + OVRMath_Max(a.DownTan, b.DownTan), + OVRMath_Max(a.LeftTan, b.LeftTan), + OVRMath_Max(a.RightTan, b.RightTan)); + return fov; + } + + static FovPort Uncant(const FovPort& cantedFov, Quatf canting) { + FovPort uncantedFov = cantedFov; + + // make 3D vectors from the FovPorts projected to z=1 plane + Vector3f leftUp = Vector3f(cantedFov.LeftTan, -cantedFov.UpTan, 1.0f); + Vector3f rightUp = Vector3f(-cantedFov.RightTan, -cantedFov.UpTan, 1.0f); + Vector3f leftDown = Vector3f(cantedFov.LeftTan, cantedFov.DownTan, 1.0f); + Vector3f rightDown = Vector3f(-cantedFov.RightTan, cantedFov.DownTan, 1.0f); + + // rotate these vectors using the canting specified + leftUp = canting.Rotate(leftUp); + rightUp = canting.Rotate(rightUp); + leftDown = canting.Rotate(leftDown); + rightDown = canting.Rotate(rightDown); + + // If the z coordinates of any of the corners end up being really small or negative, then + // projection will generate extremely large or inverted frustums and we don't really want that + const float kMinValidZ = 0.01f; + + // re-project back to z=1 plane while making sure we don't generate gigantic values (hence max) + leftUp /= OVRMath_Max(leftUp.z, kMinValidZ); + rightUp /= OVRMath_Max(rightUp.z, kMinValidZ); + leftDown /= OVRMath_Max(leftDown.z, kMinValidZ); + rightDown /= OVRMath_Max(rightDown.z, kMinValidZ); + + // generate new FovTans as "bounding box" values + uncantedFov.UpTan = OVRMath_Max(-leftUp.y, -rightUp.y); + uncantedFov.DownTan = OVRMath_Max(leftDown.y, rightDown.y); + uncantedFov.LeftTan = OVRMath_Max(leftUp.x, leftDown.x); + uncantedFov.RightTan = OVRMath_Max(-rightDown.x, -rightUp.x); + + return uncantedFov; + } + + // Widens a given FovPort by specified angle in each direction + static FovPort Expand(const FovPort& inFov, float expandAngle) { + auto ClampedExpand = [expandAngle](float t) -> float { + // We don't want gigantic values coming out of this function, so we limit resulting FOV. + // Limit before calling tanf() to avoid wrap around to negative values. + const float limitFov = atanf(10.0f); + return tanf(OVRMath_Min(OVRMath_Max(atanf(t) + expandAngle, -limitFov), limitFov)); + }; + + FovPort modFov = FovPort( + ClampedExpand(inFov.UpTan), + ClampedExpand(inFov.DownTan), + ClampedExpand(inFov.LeftTan), + ClampedExpand(inFov.RightTan)); + + return modFov; + } + + template + static FovPort ScaleFovPort(const FovPort& fov, OVR::Vector2 scaleFactors) { + FovPort retFov = FovPort(fov); + retFov.LeftTan *= ((scaleFactors.x != 0.0) ? scaleFactors.x : 1.0f); + retFov.RightTan *= ((scaleFactors.x != 0.0) ? scaleFactors.x : 1.0f); + retFov.UpTan *= ((scaleFactors.y != 0.0) ? scaleFactors.y : 1.0f); + retFov.DownTan *= ((scaleFactors.y != 0.0) ? scaleFactors.y : 1.0f); + return retFov; + } +}; + +inline bool isNan(const Vector3d& v) { + return v.IsNan(); +} + +inline bool isNan(const Vector3f& v) { + return v.IsNan(); +} + +} // Namespace OVR + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_StereoProjection.h b/ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_StereoProjection.h new file mode 100644 index 0000000..c3e4593 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/Extras/OVR_StereoProjection.h @@ -0,0 +1,71 @@ +/************************************************************************************ + +Filename : OVR_StereoProjection.h +Content : Stereo projection functions +Created : November 30, 2013 +Authors : Tom Fosyth + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_StereoProjection_h +#define OVR_StereoProjection_h + +#include "Extras/OVR_Math.h" + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** Stereo Enumerations + +// StereoEye specifies which eye we are rendering for; it is used to +// retrieve StereoEyeParams. +enum StereoEye { StereoEye_Left, StereoEye_Right, StereoEye_Center }; + +//----------------------------------------------------------------------------------- +// ***** Propjection functions + +Matrix4f CreateProjection( + bool rightHanded, + bool isOpenGL, + FovPort fov, + StereoEye eye, + float zNear = 0.01f, + float zFar = 10000.0f, + bool flipZ = false, + bool farAtInfinity = false); + +Matrix4f CreateOrthoSubProjection( + bool rightHanded, + StereoEye eyeType, + float tanHalfFovX, + float tanHalfFovY, + float unitsX, + float unitsY, + float distanceFromCamera, + float interpupillaryDistance, + Matrix4f const& projection, + float zNear = 0.0f, + float zFar = 0.0f, + bool flipZ = false, + bool farAtInfinity = false); + +} // namespace OVR + +#endif // OVR_StereoProjection_h diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI.h b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI.h new file mode 100644 index 0000000..4e0b251 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI.h @@ -0,0 +1,3715 @@ +/************************************************************************************ + \file OVR_CAPI.h + \brief C Interface to the Oculus PC SDK tracking and rendering library. + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + ************************************************************************************/ + +// We don't use version numbers within OVR_CAPI_h, as all versioned variations +// of this file are currently mutually exclusive. +#ifndef OVR_CAPI_h +#define OVR_CAPI_h + +#include "OVR_CAPI_Keys.h" +#include "OVR_ErrorCode.h" +#include "OVR_Version.h" + +#if !defined(_WIN32) +#include +#endif + + +#include + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4324) // structure was padded due to __declspec(align()) +#pragma warning(disable : 4359) // The alignment specified for a type is less than the +// alignment of the type of one of its data members +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_OS +// +#if !defined(OVR_OS_WIN32) && defined(_WIN32) +#define OVR_OS_WIN32 +#endif + +#if !defined(OVR_OS_MAC) && defined(__APPLE__) +#define OVR_OS_MAC +#endif + +#if !defined(OVR_OS_LINUX) && defined(__linux__) +#define OVR_OS_LINUX +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP +// +#if !defined(OVR_CPP) +#if defined(__cplusplus) +#define OVR_CPP(x) x +#else +#define OVR_CPP(x) /* Not C++ */ +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CDECL +// +/// LibOVR calling convention for 32-bit Windows builds. +// +#if !defined(OVR_CDECL) +#if defined(_WIN32) +#define OVR_CDECL __cdecl +#else +#define OVR_CDECL +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_EXTERN_C +// +/// Defined as extern "C" when built from C++ code. +// +#if !defined(OVR_EXTERN_C) +#ifdef __cplusplus +#define OVR_EXTERN_C extern "C" +#else +#define OVR_EXTERN_C +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_PUBLIC_FUNCTION / OVR_PRIVATE_FUNCTION +// +// OVR_PUBLIC_FUNCTION - Functions that externally visible from a shared library. +// Corresponds to Microsoft __dllexport. +// OVR_PUBLIC_CLASS - C++ structs and classes that are externally visible from a +// shared library. Corresponds to Microsoft __dllexport. +// OVR_PRIVATE_FUNCTION - Functions that are not visible outside of a shared library. +// They are private to the shared library. +// OVR_PRIVATE_CLASS - C++ structs and classes that are not visible outside of a +// shared library. They are private to the shared library. +// +// OVR_DLL_BUILD - Used to indicate that the current compilation unit is of a shared library. +// OVR_DLL_IMPORT - Used to indicate that the current compilation unit is a +// user of the corresponding shared library. +// OVR_STATIC_BUILD - used to indicate that the current compilation unit is not a +// shared library but rather statically linked code. +// +#if !defined(OVR_PUBLIC_FUNCTION) +#if defined(OVR_DLL_BUILD) +#if defined(_WIN32) +#define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __declspec(dllexport) rval OVR_CDECL +#define OVR_PUBLIC_CLASS __declspec(dllexport) +#define OVR_PRIVATE_FUNCTION(rval) rval OVR_CDECL +#define OVR_PRIVATE_CLASS +#else +#define OVR_PUBLIC_FUNCTION(rval) \ + OVR_EXTERN_C __attribute__((visibility("default"))) rval OVR_CDECL /* Requires GCC 4.0+ */ +#define OVR_PUBLIC_CLASS __attribute__((visibility("default"))) /* Requires GCC 4.0+ */ +#define OVR_PRIVATE_FUNCTION(rval) __attribute__((visibility("hidden"))) rval OVR_CDECL +#define OVR_PRIVATE_CLASS __attribute__((visibility("hidden"))) +#endif +#elif defined(OVR_DLL_IMPORT) +#if defined(_WIN32) +#define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __declspec(dllimport) rval OVR_CDECL +#define OVR_PUBLIC_CLASS __declspec(dllimport) +#else +#define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C rval OVR_CDECL +#define OVR_PUBLIC_CLASS +#endif +#define OVR_PRIVATE_FUNCTION(rval) rval OVR_CDECL +#define OVR_PRIVATE_CLASS +#else // OVR_STATIC_BUILD +#define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C rval OVR_CDECL +#define OVR_PUBLIC_CLASS +#define OVR_PRIVATE_FUNCTION(rval) rval OVR_CDECL +#define OVR_PRIVATE_CLASS +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_EXPORT +// +/// Provided for backward compatibility with older versions of this library. +// +#if !defined(OVR_EXPORT) +#ifdef OVR_OS_WIN32 +#define OVR_EXPORT __declspec(dllexport) +#else +#define OVR_EXPORT +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_ALIGNAS +// +#if !defined(OVR_ALIGNAS) +#if defined(__GNUC__) || defined(__clang__) +#define OVR_ALIGNAS(n) __attribute__((aligned(n))) +#elif defined(_MSC_VER) || defined(__INTEL_COMPILER) +#define OVR_ALIGNAS(n) __declspec(align(n)) +#elif defined(__CC_ARM) +#define OVR_ALIGNAS(n) __align(n) +#else +#error Need to define OVR_ALIGNAS +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CC_HAS_FEATURE +// +// This is a portable way to use compile-time feature identification available +// with some compilers in a clean way. Direct usage of __has_feature in preprocessing +// statements of non-supporting compilers results in a preprocessing error. +// +// Example usage: +// #if OVR_CC_HAS_FEATURE(is_pod) +// if(__is_pod(T)) // If the type is plain data then we can safely memcpy it. +// memcpy(&destObject, &srcObject, sizeof(object)); +// #endif +// +#if !defined(OVR_CC_HAS_FEATURE) +#if defined(__clang__) // http://clang.llvm.org/docs/LanguageExtensions.html#id2 +#define OVR_CC_HAS_FEATURE(x) __has_feature(x) +#else +#define OVR_CC_HAS_FEATURE(x) 0 +#endif +#endif + +// ------------------------------------------------------------------------ +// ***** OVR_STATIC_ASSERT +// +// Portable support for C++11 static_assert(). +// Acts as if the following were declared: +// void OVR_STATIC_ASSERT(bool const_expression, const char* msg); +// +// Example usage: +// OVR_STATIC_ASSERT(sizeof(int32_t) == 4, "int32_t expected to be 4 bytes."); + +#if !defined(OVR_STATIC_ASSERT) +#if !(defined(__cplusplus) && (__cplusplus >= 201103L)) /* Other */ && \ + !(defined(__GXX_EXPERIMENTAL_CXX0X__)) /* GCC */ && \ + !(defined(__clang__) && defined(__cplusplus) && \ + OVR_CC_HAS_FEATURE(cxx_static_assert)) /* clang */ \ + && !(defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(__cplusplus)) /* VS2010+ */ + +#if !defined(OVR_SA_UNUSED) +#if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) +#define OVR_SA_UNUSED __attribute__((unused)) +#else +#define OVR_SA_UNUSED +#endif +#define OVR_SA_PASTE(a, b) a##b +#define OVR_SA_HELP(a, b) OVR_SA_PASTE(a, b) +#endif + +#if defined(__COUNTER__) +#define OVR_STATIC_ASSERT(expression, msg) \ + typedef char OVR_SA_HELP(staticAssert, __COUNTER__)[((expression) != 0) ? 1 : -1] OVR_SA_UNUSED +#else +#define OVR_STATIC_ASSERT(expression, msg) \ + typedef char OVR_SA_HELP(staticAssert, __LINE__)[((expression) != 0) ? 1 : -1] OVR_SA_UNUSED +#endif + +#else +#define OVR_STATIC_ASSERT(expression, msg) static_assert(expression, msg) +#endif +#endif + +// OVR_STATIC_ASSERT_OFFSETOF statically asserts offsetof(Type.member) == expected_offset +#define OVR_STATIC_ASSERT_OFFSETOF(Type, member, expected_offset) \ + OVR_STATIC_ASSERT( \ + offsetof(Type, member) == (expected_offset), \ + "Expected " #Type "." #member " offset == " #expected_offset) + +// OVR_STATIC_ASSERT_SIZEOF statically asserts sizeof(Type) == expected_size +#define OVR_STATIC_ASSERT_SIZEOF(Type, expected_size) \ + OVR_STATIC_ASSERT( \ + sizeof(Type) == (expected_size), "Expected sizeof(" #Type ") == " #expected_size) + +//----------------------------------------------------------------------------------- +// ***** Padding +// +/// Defines explicitly unused space for a struct. +/// When used correcly, usage of this macro should not change the size of the struct. +/// Compile-time and runtime behavior with and without this defined should be identical. +/// +#if !defined(OVR_UNUSED_STRUCT_PAD) +#define OVR_UNUSED_STRUCT_PAD(padName, size) char padName[size]; +#endif + +//----------------------------------------------------------------------------------- +// ***** Word Size +// +/// Specifies the size of a pointer on the given platform. +/// +#if !defined(OVR_PTR_SIZE) +#if defined(__WORDSIZE) +#define OVR_PTR_SIZE ((__WORDSIZE) / 8) +#elif defined(_WIN64) || defined(__LP64__) || defined(_LP64) || defined(_M_IA64) || \ + defined(__ia64__) || defined(__arch64__) || defined(__64BIT__) || defined(__Ptr_Is_64) +#define OVR_PTR_SIZE 8 +#elif defined(__CC_ARM) && (__sizeof_ptr == 8) +#define OVR_PTR_SIZE 8 +#else +#define OVR_PTR_SIZE 4 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_ON32 / OVR_ON64 +// +#if OVR_PTR_SIZE == 8 +#define OVR_ON32(x) +#define OVR_ON64(x) x +#else +#define OVR_ON32(x) x +#define OVR_ON64(x) +#endif + +//----------------------------------------------------------------------------------- +// ***** ovrBool + +typedef char ovrBool; ///< Boolean type +#define ovrFalse 0 ///< ovrBool value of false. +#define ovrTrue 1 ///< ovrBool value of true. + +//----------------------------------------------------------------------------------- +// ***** PFN_ovrVoidFunction +// +/// Defines a generic function pointer. +/// +/// \see ovr_GetInstanceProcAddr +/// +typedef void (*PFN_ovrVoidFunction)(void); + +//----------------------------------------------------------------------------------- +// ***** Simple Math Structures + +/// A RGBA color with normalized float components. +typedef struct OVR_ALIGNAS(4) ovrColorf_ { + float r, g, b, a; +} ovrColorf; + +/// A 2D vector with integer components. +typedef struct OVR_ALIGNAS(4) ovrVector2i_ { + int x, y; +} ovrVector2i; + +/// A 2D size with integer components. +typedef struct OVR_ALIGNAS(4) ovrSizei_ { + int w, h; +} ovrSizei; + +/// A 2D rectangle with a position and size. +/// All components are integers. +typedef struct OVR_ALIGNAS(4) ovrRecti_ { + ovrVector2i Pos; + ovrSizei Size; +} ovrRecti; + +/// A quaternion rotation. +typedef struct OVR_ALIGNAS(4) ovrQuatf_ { + float x, y, z, w; +} ovrQuatf; + +/// A 2D vector with float components. +typedef struct OVR_ALIGNAS(4) ovrVector2f_ { + float x, y; +} ovrVector2f; + +/// A 3D vector with float components. +typedef struct OVR_ALIGNAS(4) ovrVector3f_ { + float x, y, z; +} ovrVector3f; + +/// A 4D vector with float components. +typedef struct OVR_ALIGNAS(4) ovrVector4f_ { + float x, y, z, w; +} ovrVector4f; + +/// A 4D vector with int16_t components. +typedef struct OVR_ALIGNAS(4) ovrVector4s_ { + int16_t x, y, z, w; +} ovrVector4s; + +/// A 4x4 matrix with float elements. +typedef struct OVR_ALIGNAS(4) ovrMatrix4f_ { + float M[4][4]; +} ovrMatrix4f; + +/// Position and orientation together. +/// The coordinate system used is right-handed Cartesian. +typedef struct OVR_ALIGNAS(4) ovrPosef_ { + ovrQuatf Orientation; + ovrVector3f Position; +} ovrPosef; + +/// A full pose (rigid body) configuration with first and second derivatives. +/// +/// Body refers to any object for which ovrPoseStatef is providing data. +/// It can be the HMD, Touch controller, sensor or something else. The context +/// depends on the usage of the struct. +typedef struct OVR_ALIGNAS(8) ovrPoseStatef_ { + ovrPosef ThePose; ///< Position and orientation. + ovrVector3f AngularVelocity; ///< Angular velocity in radians per second. + ovrVector3f LinearVelocity; ///< Velocity in meters per second. + ovrVector3f AngularAcceleration; ///< Angular acceleration in radians per second per second. + ovrVector3f LinearAcceleration; ///< Acceleration in meters per second per second. + OVR_UNUSED_STRUCT_PAD(pad0, 4) ///< \internal struct pad. + double TimeInSeconds; ///< Absolute time that this pose refers to. \see ovr_GetTimeInSeconds +} ovrPoseStatef; + +/// Describes the up, down, left, and right angles of the field of view. +/// +/// Field Of View (FOV) tangent of the angle units. +/// \note For a standard 90 degree vertical FOV, we would +/// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }. +typedef struct OVR_ALIGNAS(4) ovrFovPort_ { + float UpTan; ///< Tangent of the angle between the viewing vector and top edge of the FOV. + float DownTan; ///< Tangent of the angle between the viewing vector and bottom edge of the FOV. + float LeftTan; ///< Tangent of the angle between the viewing vector and left edge of the FOV. + float RightTan; ///< Tangent of the angle between the viewing vector and right edge of the FOV. +} ovrFovPort; + +//----------------------------------------------------------------------------------- +// ***** HMD Types + +/// Enumerates all HMD types that we support. +/// +/// The currently released developer kits are ovrHmd_DK1 and ovrHmd_DK2. +/// The other enumerations are for internal use only. +typedef enum ovrHmdType_ { + ovrHmd_None = 0, + ovrHmd_DK1 = 3, + ovrHmd_DKHD = 4, + ovrHmd_DK2 = 6, + ovrHmd_CB = 8, + ovrHmd_Other = 9, + ovrHmd_E3_2015 = 10, + ovrHmd_ES06 = 11, + ovrHmd_ES09 = 12, + ovrHmd_ES11 = 13, + ovrHmd_CV1 = 14, + ovrHmd_RiftS = 16, + ovrHmd_Quest = 19, + ovrHmd_Quest2 = 20, + ovrHmd_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrHmdType; + +/// HMD capability bits reported by device. +/// +typedef enum ovrHmdCaps_ { + // Read-only flags + + /// (read only) Specifies that the HMD is a virtual debug device. + ovrHmdCap_DebugDevice = 0x0010, + + + ovrHmdCap_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrHmdCaps; + +/// Tracking capability bits reported by the device. +/// Used with ovr_GetTrackingCaps. +typedef enum ovrTrackingCaps_ { + ovrTrackingCap_Orientation = 0x0010, ///< Supports orientation tracking (IMU). + ovrTrackingCap_MagYawCorrection = 0x0020, ///< Supports yaw drift correction. + ovrTrackingCap_Position = 0x0040, ///< Supports positional tracking. + ovrTrackingCap_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrTrackingCaps; + +/// Defines the largest size for an extension name string, including the '\0' terminator. +/// +/// \see ovrExtensionProperties +/// +#define OVR_MAX_EXTENSION_NAME_SIZE 128 + +/// Describes the properties of an API extension. +/// +/// \see ovr_EnumerateInstanceExtensionProperties +/// +typedef struct ovrExtensionProperties_ { + int extensionId; // One of enum ovrExtensions or a dynamic value. + char extensionName[OVR_MAX_EXTENSION_NAME_SIZE]; + uint32_t extensionVersion; // OpenXR-like version. Version compatibility is identified by the + // extension documentation. +} ovrExtensionProperties; + +/// Optional extensions +typedef enum ovrExtensions_ { + ovrExtension_TextureLayout_Octilinear = 0, ///< Enable before first layer submission. + ovrExtension_Count, ///< \internal Sanity checking + ovrExtension_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrExtensions; + +/// Specifies which eye is being used for rendering. +/// This type explicitly does not include a third "NoStereo" monoscopic option, +/// as such is not required for an HMD-centered API. +typedef enum ovrEyeType_ { + ovrEye_Left = 0, ///< The left eye, from the viewer's perspective. + ovrEye_Right = 1, ///< The right eye, from the viewer's perspective. + ovrEye_Count = 2, ///< \internal Count of enumerated elements. + ovrEye_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrEyeType; + +/// Specifies the coordinate system ovrTrackingState returns tracking poses in. +/// Used with ovr_SetTrackingOriginType() +typedef enum ovrTrackingOrigin_ { + /// \brief Tracking system origin reported at eye (HMD) height + /// \details Prefer using this origin when your application requires + /// matching user's current physical head pose to a virtual head pose + /// without any regards to a the height of the floor. Cockpit-based, + /// or 3rd-person experiences are ideal candidates. + /// When used, all poses in ovrTrackingState are reported as an offset + /// transform from the profile calibrated or recentered HMD pose. + /// It is recommended that apps using this origin type call ovr_RecenterTrackingOrigin + /// prior to starting the VR experience, but notify the user before doing so + /// to make sure the user is in a comfortable pose, facing a comfortable + /// direction. + ovrTrackingOrigin_EyeLevel = 0, + + /// \brief Tracking system origin reported at floor height + /// \details Prefer using this origin when your application requires the + /// physical floor height to match the virtual floor height, such as + /// standing experiences. + /// When used, all poses in ovrTrackingState are reported as an offset + /// transform from the profile calibrated floor pose. Calling ovr_RecenterTrackingOrigin + /// will recenter the X & Z axes as well as yaw, but the Y-axis (i.e. height) will continue + /// to be reported using the floor height as the origin for all poses. + ovrTrackingOrigin_FloorLevel = 1, + + ovrTrackingOrigin_Count = 2, ///< \internal Count of enumerated elements. + ovrTrackingOrigin_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrTrackingOrigin; + +/// Color space types for HMDs +/// +/// Until ovr_SetClientColorDesc is called, for backwards compatibility, a new session will start +/// with 'ovrColorSpace_Unknown' which will default to 'ovrColorSpace_Rift_CV1'. This assumes the +/// app visuals were authored to be viewed in a Rift CV1 HMD. Therefore it does the following: +/// - For Rift CV1, assumes submitted images are authored for CV1 color space, and keeps them as is. +/// - For Rift S and Quest (via Oculus Link), converts images to reproduce CV1's color space. +/// +/// This API only handles color-space remapping. Unless specified, all color spaces use D65 white +/// point. This API will not affect brightness, contrast or gamma curves. Some of these aspects such +/// as gamma, is handled by the texture format being used. From the GPU samplers' point-of-view, +/// each texture will continue to be treated as linear luminance including the sRGB format which is +/// converted to linear by the texture sampler. +/// +/// It is recommended that content is authored for the Rift CV1 color space as it has a wider color +/// gamut than the Rift S. If content is authored to a narrow color space such as "Rec. 709" or +/// "Rift S", this can lead to content looking "dull", "washed out" or "desaturated" when viewed in +/// a wider-color-space-capable device such as Rift CV1 and Quest. This is because the colors stored +/// in the submitted images will no longer be able to hit the deeper saturated chromaticity values. +/// +/// Using 'ovrColorSpace_Unmanaged' will force the runtime to skip color correction on to the +/// provided content. This is not recommended unless the app developer is sure about what they're +/// doing. 'ovrColorSpace_Unmanaged' is mostly useful for research & experimentation, but not for +/// software distribution. This is because unless the client is applying the necessary corrections +/// for each HMD type, the results seen in the HMD will be uncalibrated. This is especially true for +/// future HMDs where the color space is not yet known or defined, leading to colors that might look +/// too dull or saturated. +/// +/// Requested rectilinear-mirror outputs are composited without any color space adjustment. +/// However, if client requests a post-distortion (i.e. non-rectilinear) mirror output, it will be +/// provided with the same color adjustment that was applied for the HMD output. Therefore, +/// post-distortion mirror output are not guaranteed to have acceptable color-space accuracy +/// for desktop viewing. +/// +/// Color Space Details with Chromaticity Primaries in CIE 1931 xy: +/// +/// Color Space: Rift CV1 between P3 & Adobe RGB using D75 white point +/// Red : (0.666, 0.334) +/// Green: (0.238, 0.714) +/// Blue : (0.139, 0.053) +/// White: (0.298, 0.318) +/// +/// Color Space: Quest similar to Rift CV1 using D75 white point +/// Red : (0.661, 0.338) +/// Green: (0.228, 0.718) +/// Blue : (0.142, 0.042) +/// White: (0.298, 0.318) +/// +/// Color Space: Rift S similar to Rec 709 using D75 +/// Red : (0.640, 0.330) +/// Green: (0.292, 0.586) +/// Blue : (0.156, 0.058) +/// White: (0.298, 0.318) +/// +/// Color Space: P3, similar to DCI-P3, but using D65 white point instead. +/// Red : (0.680, 0.320) +/// Green: (0.265, 0.690) +/// Blue : (0.150, 0.060) +/// White: (0.313, 0.329) +/// +/// Note: Due to LCD limitations, the Rift S display will not be able to meaningfully differentiate +/// brightness levels below 13 out of 255 for 8-bit sRGB or 0.0015 out of 1.0 max for linear-RGB +/// shader output values. To that end, it is recommended that reliance on a dark and narrow gamut is +/// avoided, and the content is instead spread across a larger brightness range when possible. +/// +typedef enum ovrColorSpace_ { + ovrColorSpace_Unknown = 0, ///< Default value until client sets calls ovr_SetClientColorDesc + ovrColorSpace_Unmanaged = 1, ///< See notes above. No correction, i.e. color space of active HMD + ovrColorSpace_Rift_CV1 = 2, ///< See notes above. Unique color space. + ovrColorSpace_Rift_S = 3, ///< See notes above. Unique color space. + ovrColorSpace_Quest = 4, ///< See notes above. Unique color space. + ovrColorSpace_Rec_2020 = 5, ///< Standard Rec. 2020 chromaticities + ovrColorSpace_Rec_709 = 6, ///< Standard Rec. 709 chromaticities, similar to sRGB + ovrColorSpace_P3 = 7, ///< See notes above + ovrColorSpace_Adobe_RGB = 8, ///< Standard AdobeRGB chromaticities + ovrColorSpace_Count = 9, + + ovrColorSpace_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrColorSpace; + +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrHmdColorDesc_ { + /// Approximate color space the HMD display can output. + /// Use ColorPrimaries for more precise color space definition including white point (e.g. DN75) + ovrColorSpace ColorSpace; + OVR_UNUSED_STRUCT_PAD(pad0, 4) ///< \internal struct pad. +} ovrHmdColorDesc; + +/// Identifies a graphics device in a platform-specific way. +/// For Windows this is a LUID type. +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrGraphicsLuid_ { + // Public definition reserves space for graphics API-specific implementation + char Reserved[8]; +} ovrGraphicsLuid; + +/// This is a complete descriptor of the HMD. +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrHmdDesc_ { + ovrHmdType Type; ///< The type of HMD. + OVR_ON64(OVR_UNUSED_STRUCT_PAD(pad0, 4)) ///< \internal struct padding. + char ProductName[64]; ///< UTF8-encoded product identification string (e.g. "Oculus Rift DK1"). + char Manufacturer[64]; ///< UTF8-encoded HMD manufacturer identification string. + short VendorId; ///< HID (USB) vendor identifier of the device. + short ProductId; ///< HID (USB) product identifier of the device. + char SerialNumber[24]; ///< HMD serial number. + short FirmwareMajor; ///< HMD firmware major version. + short FirmwareMinor; ///< HMD firmware minor version. + unsigned int AvailableHmdCaps; ///< Available ovrHmdCaps bits. + unsigned int DefaultHmdCaps; ///< Default ovrHmdCaps bits. + unsigned int AvailableTrackingCaps; ///< Available ovrTrackingCaps bits. + unsigned int DefaultTrackingCaps; ///< Default ovrTrackingCaps bits. + ovrFovPort DefaultEyeFov[ovrEye_Count]; ///< Defines the recommended FOVs for the HMD. + ovrFovPort MaxEyeFov[ovrEye_Count]; ///< Defines the maximum FOVs for the HMD. + ovrSizei Resolution; ///< Resolution of the full HMD screen (both eyes) in pixels. + float DisplayRefreshRate; ///< Refresh rate of the display in cycles per second. + OVR_ON64(OVR_UNUSED_STRUCT_PAD(pad1, 4)) ///< \internal struct padding. +} ovrHmdDesc; + +/// Used as an opaque pointer to an OVR session. +typedef struct ovrHmdStruct* ovrSession; + +#ifdef OVR_OS_WIN32 +typedef uint32_t ovrProcessId; +#else +typedef pid_t ovrProcessId; +#endif + +/// Fallback definitions for when the vulkan header isn't being included +#if !defined(VK_VERSION_1_0) +// From : +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; +#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || \ + defined(_M_X64) || defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || \ + defined(__powerpc64__) +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T* object; +#else +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#endif +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_HANDLE(VkPhysicalDevice) +VK_DEFINE_HANDLE(VkDevice) +VK_DEFINE_HANDLE(VkQueue) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) +#endif + +/// Bit flags describing the current status of sensor tracking. +/// The values must be the same as in enum StatusBits +/// +/// \see ovrTrackingState +/// +typedef enum ovrStatusBits_ { + // Device orientation is currently tracked. It's possible that the device orientation is not + // tracked, + // but its reported orientation is nevertheless valid (e.g. due to estimation) + ovrStatus_OrientationTracked = 0x0001, + + // Device position is currently tracked. It's possible that the device position is not tracked, + // but its reported position is nevertheless valid (e.g. due to estimation). + ovrStatus_PositionTracked = 0x0002, + + // The reported device orientation is valid for application use. In the case that OrientationValid + // is true and + // OrientationTracked is false, the runtime may be estimating the orientation of the device. + // In the case that OrientationValid is false, the application should not use the returned + // orientation value. + ovrStatus_OrientationValid = 0x0004, + + // The reported device orientation is valid for application use. In the case that PositionValid is + // true and + // PositionTracked is false, the runtime may be estimating the position of the device. + // In the case that PositionValid is false, the application should not use the returned position + // value. + ovrStatus_PositionValid = 0x0008 +} ovrStatusBits; + +/// Specifies the description of a single sensor. +/// +/// \see ovr_GetTrackerDesc +/// +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrTrackerDesc_ { + float FrustumHFovInRadians; ///< Sensor frustum horizontal field-of-view (if present). + float FrustumVFovInRadians; ///< Sensor frustum vertical field-of-view (if present). + float FrustumNearZInMeters; ///< Sensor frustum near Z (if present). + float FrustumFarZInMeters; ///< Sensor frustum far Z (if present). +} ovrTrackerDesc; + +/// Specifies sensor flags. +/// +/// /see ovrTrackerPose +/// +typedef enum ovrTrackerFlags_ { + /// The sensor is present, else the sensor is absent or offline. + ovrTracker_Connected = 0x0020, + + /// The sensor has a valid pose, else the pose is unavailable. + /// This will only be set if ovrTracker_Connected is set. + ovrTracker_PoseTracked = 0x0004 +} ovrTrackerFlags; + +/// Specifies the pose for a single sensor. +/// +typedef struct OVR_ALIGNAS(8) _ovrTrackerPose { + /// ovrTrackerFlags. + unsigned int TrackerFlags; + + /// The sensor's pose. This pose includes sensor tilt (roll and pitch). + /// For a leveled coordinate system use LeveledPose. + ovrPosef Pose; + + /// The sensor's leveled pose, aligned with gravity. This value includes pos and yaw of the + /// sensor, but not roll and pitch. It can be used as a reference point to render real-world + /// objects in the correct location. + ovrPosef LeveledPose; + + OVR_UNUSED_STRUCT_PAD(pad0, 4) ///< \internal struct pad. +} ovrTrackerPose; + +/// Tracking state at a given absolute time (describes predicted HMD pose, etc.). +/// Returned by ovr_GetTrackingState. +/// +/// \see ovr_GetTrackingState +/// +typedef struct OVR_ALIGNAS(8) ovrTrackingState_ { + /// Predicted head pose (and derivatives) at the requested absolute time. + ovrPoseStatef HeadPose; + + /// HeadPose tracking status described by ovrStatusBits. + unsigned int StatusFlags; + + /// The most recent calculated pose for each hand when hand controller tracking is present. + /// HandPoses[ovrHand_Left] refers to the left hand and HandPoses[ovrHand_Right] to the right. + /// These values can be combined with ovrInputState for complete hand controller information. + ovrPoseStatef HandPoses[2]; + + /// HandPoses status flags described by ovrStatusBits. + unsigned int HandStatusFlags[2]; + + /// The pose of the origin captured during calibration. + /// Like all other poses here, this is expressed in the space set by ovr_RecenterTrackingOrigin, + /// or ovr_SpecifyTrackingOrigin and so will change every time either of those functions are + /// called. This pose can be used to calculate where the calibrated origin lands in the new + /// recentered space. If an application never calls ovr_RecenterTrackingOrigin or + /// ovr_SpecifyTrackingOrigin, expect this value to be the identity pose and as such will point + /// respective origin based on ovrTrackingOrigin requested when calling ovr_GetTrackingState. + ovrPosef CalibratedOrigin; + +} ovrTrackingState; + + + +/// Rendering information for each eye. Computed by ovr_GetRenderDesc() based on the +/// specified FOV. Note that the rendering viewport is not included +/// here as it can be specified separately and modified per frame by +/// passing different Viewport values in the layer structure. +/// +/// \see ovr_GetRenderDesc +/// +typedef struct OVR_ALIGNAS(4) ovrEyeRenderDesc_ { + ovrEyeType Eye; ///< The eye index to which this instance corresponds. + ovrFovPort Fov; ///< The field of view. + ovrRecti DistortedViewport; ///< Distortion viewport. + ovrVector2f PixelsPerTanAngleAtCenter; ///< How many display pixels will fit in tan(angle) = 1. + ovrPosef HmdToEyePose; ///< Transform of eye from the HMD center, in meters. +} ovrEyeRenderDesc; + +/// Projection information for ovrLayerEyeFovDepth. +/// +/// Use the utility function ovrTimewarpProjectionDesc_FromProjection to +/// generate this structure from the application's projection matrix. +/// +/// \see ovrLayerEyeFovDepth, ovrTimewarpProjectionDesc_FromProjection +/// +typedef struct OVR_ALIGNAS(4) ovrTimewarpProjectionDesc_ { + float Projection22; ///< Projection matrix element [2][2]. + float Projection23; ///< Projection matrix element [2][3]. + float Projection32; ///< Projection matrix element [3][2]. +} ovrTimewarpProjectionDesc; + + +/// Contains the data necessary to properly calculate position info for various layer types. +/// - HmdToEyePose is the same value-pair provided in ovrEyeRenderDesc. Modifying this value is +/// suggested only if the app is forcing monoscopic rendering and requires that all layers +/// including quad layers show up in a monoscopic fashion. +/// - HmdSpaceToWorldScaleInMeters is used to scale player motion into in-application units. +/// In other words, it is how big an in-application unit is in the player's physical meters. +/// For example, if the application uses inches as its units then HmdSpaceToWorldScaleInMeters +/// would be 0.0254. +/// Note that if you are scaling the player in size, this must also scale. So if your application +/// units are inches, but you're shrinking the player to half their normal size, then +/// HmdSpaceToWorldScaleInMeters would be 0.0254*2.0. +/// +/// \see ovrEyeRenderDesc, ovr_SubmitFrame +/// +typedef struct OVR_ALIGNAS(4) ovrViewScaleDesc_ { + ovrPosef HmdToEyePose[ovrEye_Count]; ///< Transform of each eye from the HMD center, in meters. + float HmdSpaceToWorldScaleInMeters; ///< Ratio of viewer units to meter units. +} ovrViewScaleDesc; + +//----------------------------------------------------------------------------------- +// ***** Platform-independent Rendering Configuration + +/// The type of texture resource. +/// +/// \see ovrTextureSwapChainDesc +/// +typedef enum ovrTextureType_ { + ovrTexture_2D = 0, ///< 2D textures or texture arrays. + ovrTexture_2D_External = 1, ///< Application-provided 2D texture. Not supported on PC. + ovrTexture_Cube = 2, ///< Cube maps. ovrTextureSwapChainDesc::ArraySize must be 6 for this type. + ovrTexture_Count, + ovrTexture_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrTextureType; + +/// The bindings required for texture swap chain. +/// +/// All texture swap chains are automatically bindable as shader +/// input resources since the Oculus runtime needs this to read them. +/// +/// \see ovrTextureSwapChainDesc +/// +typedef enum ovrTextureBindFlags_ { + ovrTextureBind_None, + + /// The application can write into the chain with pixel shader. + ovrTextureBind_DX_RenderTarget = 0x0001, + + /// The application can write to the chain with compute shader. + ovrTextureBind_DX_UnorderedAccess = 0x0002, + + /// The chain buffers can be bound as depth and/or stencil buffers. + /// This flag cannot be combined with ovrTextureBind_DX_RenderTarget. + ovrTextureBind_DX_DepthStencil = 0x0004, + + + ovrTextureBind_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrTextureBindFlags; + +/// The format of a texture. +/// +/// \see ovrTextureSwapChainDesc +/// +typedef enum ovrTextureFormat_ { + OVR_FORMAT_UNKNOWN = 0, + OVR_FORMAT_B5G6R5_UNORM = 1, ///< Not currently supported on PC. Requires a DirectX 11.1 device. + OVR_FORMAT_B5G5R5A1_UNORM = 2, ///< Not currently supported on PC. Requires a DirectX 11.1 device. + OVR_FORMAT_B4G4R4A4_UNORM = 3, ///< Not currently supported on PC. Requires a DirectX 11.1 device. + OVR_FORMAT_R8G8B8A8_UNORM = 4, + OVR_FORMAT_R8G8B8A8_UNORM_SRGB = 5, + OVR_FORMAT_B8G8R8A8_UNORM = 6, + OVR_FORMAT_B8G8R8_UNORM = 27, ///< Not currently supported. + OVR_FORMAT_B8G8R8A8_UNORM_SRGB = 7, ///< Not supported for OpenGL applications + OVR_FORMAT_B8G8R8X8_UNORM = 8, ///< Not supported for OpenGL applications + OVR_FORMAT_B8G8R8X8_UNORM_SRGB = 9, ///< Not supported for OpenGL applications + OVR_FORMAT_R16G16B16A16_FLOAT = 10, + OVR_FORMAT_R11G11B10_FLOAT = 25, ///< Not supported for D3D12 applications. Introduced in v1.10 + + // Depth formats + OVR_FORMAT_D16_UNORM = 11, + OVR_FORMAT_D24_UNORM_S8_UINT = 12, + OVR_FORMAT_D32_FLOAT = 13, + OVR_FORMAT_D32_FLOAT_S8X24_UINT = 14, + + // Added in 1.5 compressed formats can be used for static layers + OVR_FORMAT_BC1_UNORM = 15, + OVR_FORMAT_BC1_UNORM_SRGB = 16, + OVR_FORMAT_BC2_UNORM = 17, + OVR_FORMAT_BC2_UNORM_SRGB = 18, + OVR_FORMAT_BC3_UNORM = 19, + OVR_FORMAT_BC3_UNORM_SRGB = 20, + OVR_FORMAT_BC6H_UF16 = 21, + OVR_FORMAT_BC6H_SF16 = 22, + OVR_FORMAT_BC7_UNORM = 23, + OVR_FORMAT_BC7_UNORM_SRGB = 24, + + + OVR_FORMAT_LAST, + OVR_FORMAT_ENUMSIZE = 0x7fffffff ///< \internal Force type int32_t. +} ovrTextureFormat; + +/// Misc flags overriding particular +/// behaviors of a texture swap chain +/// +/// \see ovrTextureSwapChainDesc +/// +typedef enum ovrTextureMiscFlags_ { + ovrTextureMisc_None, + + /// Vulkan and DX only: The underlying texture is created with a TYPELESS equivalent + /// of the format specified in the texture desc. The SDK will still access the + /// texture using the format specified in the texture desc, but the app can + /// create views with different formats if this is specified. + ovrTextureMisc_DX_Typeless = 0x0001, + + /// DX only: Allow generation of the mip chain on the GPU via the GenerateMips + /// call. This flag requires that RenderTarget binding also be specified. + ovrTextureMisc_AllowGenerateMips = 0x0002, + + /// Texture swap chain contains protected content, and requires + /// HDCP connection in order to display to HMD. Also prevents + /// mirroring or other redirection of any frame containing this contents + ovrTextureMisc_ProtectedContent = 0x0004, + + /// Automatically generate and use the mip chain in composition on each submission. + /// Mips are regenerated from highest quality level, ignoring other pre-existing mip levels. + /// Not supported for depth or compressed (BC) formats. + ovrTextureMisc_AutoGenerateMips = 0x0008, + + + ovrTextureMisc_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrTextureFlags; + +/// Description used to create a texture swap chain. +/// +/// \see ovr_CreateTextureSwapChainDX +/// \see ovr_CreateTextureSwapChainGL +/// \see ovr_CreateTextureSwapChainVk +/// +typedef struct ovrTextureSwapChainDesc_ { + ovrTextureType Type; ///< Must be ovrTexture_2D or ovrTexture_Cube. + ovrTextureFormat Format; + int ArraySize; ///< Must be 6 for ovrTexture_Cube, size of texture array otherwise. + int Width; + int Height; + int MipLevels; + int SampleCount; + ovrBool StaticImage; ///< Not buffered in a chain. For images that don't change + OVR_ALIGNAS(4) unsigned int MiscFlags; ///< ovrTextureFlags + OVR_ALIGNAS(4) unsigned int BindFlags; ///< ovrTextureBindFlags. Not used for GL. +} ovrTextureSwapChainDesc; + +/// Bit flags used as part of ovrMirrorTextureDesc's MirrorOptions field. +/// +/// \see ovr_CreateMirrorTextureWithOptionsDX +/// \see ovr_CreateMirrorTextureWithOptionsGL +/// \see ovr_CreateMirrorTextureWithOptionsVk +/// +typedef enum ovrMirrorOptions_ { + /// By default the mirror texture will be: + /// * Pre-distortion (i.e. rectilinear) + /// * Contain both eye textures + /// * Exclude Guardian, Notifications, System Menu GUI + ovrMirrorOption_Default = 0x0000, + + /// Retrieves the barrel distorted texture contents instead of the rectilinear one + /// This is only recommended for debugging purposes, and not for final desktop presentation + ovrMirrorOption_PostDistortion = 0x0001, + + /// Since ovrMirrorOption_Default renders both eyes into the mirror texture, + /// these two flags are exclusive (i.e. cannot use them simultaneously) + ovrMirrorOption_LeftEyeOnly = 0x0002, + ovrMirrorOption_RightEyeOnly = 0x0004, + + /// Shows the boundary system aka Guardian on the mirror texture + ovrMirrorOption_IncludeGuardian = 0x0008, + + /// Shows system notifications the user receives on the mirror texture + ovrMirrorOption_IncludeNotifications = 0x0010, + + /// Shows the system menu (triggered by hitting the Home button) on the mirror texture + ovrMirrorOption_IncludeSystemGui = 0x0020, + + /// Forces mirror output to use max symmetric FOV instead of asymmetric full FOV used by HMD. + /// Only valid for rectilinear mirrors i.e. using ovrMirrorOption_PostDistortion with + /// ovrMirrorOption_ForceSymmetricFov will result in ovrError_InvalidParameter error. + ovrMirrorOption_ForceSymmetricFov = 0x0040, + + + ovrMirrorOption_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrMirrorOptions; + +/// Description used to create a mirror texture. +/// +/// \see ovr_CreateMirrorTextureWithOptionsDX +/// \see ovr_CreateMirrorTextureWithOptionsGL +/// \see ovr_CreateMirrorTextureWithOptionsVk +/// +typedef struct ovrMirrorTextureDesc_ { + ovrTextureFormat Format; + int Width; + int Height; + unsigned int MiscFlags; ///< ovrTextureFlags + unsigned int MirrorOptions; ///< ovrMirrorOptions +} ovrMirrorTextureDesc; + +typedef struct ovrTextureSwapChainData* ovrTextureSwapChain; +typedef struct ovrMirrorTextureData* ovrMirrorTexture; + +//----------------------------------------------------------------------------------- + +/// Fov-stencil mesh for assisting in rendering efficiency for clients using EyeFov layers + +/// A fov-stencil mesh is used to cull out the parts of the eye render target used in +/// ovrLayerType_EyeFov & ovrLayerType_EyeFovDepth layers that would not normally be visible to +/// the user wearing the HMD. +/// +/// A rasterized eye render target is rectangular, but the parts of the render target visible to the +/// user do not necessarily follow a rectangular region. This is where the fov-stencil mesh +/// helps designate the boundaries of the visible parts for a given eye render target. +/// +/// To make effective use of this mesh, the client should render the mesh before kicking off any +/// other rendering work. Ideally the mesh would be rendered at the near-depth plane distance, or +/// into the stencil buffer right after clearing the depth-stencil buffer. The choice of using +/// depth vs. stencil is left up to the client, but the client should make sure that the mesh is +/// rendered in a way that it can make use of Hierarchical-Z or Hierarchical-Stencil for better +/// performance on rejected geometry post-vertex shading. + +/// Viewport stencil types provided by the ovr_GetFovStencil call. +/// \see ovr_GetFovStencil +typedef enum ovrFovStencilType_ { + ovrFovStencil_HiddenArea = 0, ///< Triangle list covering parts that are hidden to users + ovrFovStencil_VisibleArea = 1, ///< Triangle list covering parts that are visible to users + ovrFovStencil_BorderLine = 2, ///< Line list that draws the boundary visible to users + ovrFovStencil_VisibleRectangle = 3, ///< Axis-aligned rectangle fit in visible region + ///< 4x vertices: TopLeft, TopRight, BottomRight, BottomLeft + + ovrFovStencilType_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrFovStencilType; + +/// Identifies flags used by ovrFovStencilDesc and which are passed to ovr_GetFovStencil. +/// \see ovrFovStencilDesc +typedef enum ovrFovStencilFlags_ { + + /// When used, flips the Y component of the provided 2D mesh coordinates, such that Y increases + /// upwards. When not used, places mesh origin at top-left where Y increases downwards. + ovrFovStencilFlag_MeshOriginAtBottomLeft = 0x01, + + ovrFovStencilFlag_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrFovStencilFlags; + +/// Fov-stencil mesh descriptor passed into the function ovr_GetFovStencil +/// \see ovr_GetFovStencil +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrFovStencilDesc_ { + ovrFovStencilType StencilType; + uint32_t StencilFlags; ///< Bit flag combination of ovrFovStencilFlags + ovrEyeType Eye; + ovrFovPort FovPort; ///< Typically FOV obtained from ovrEyeRenderDesc + ovrQuatf HmdToEyeRotation; ///< Typically HmdToEyePose.Orientation obtained from ovrEyeRenderDesc + ///< Note: Currently unsupported, always treated as identity +} ovrFovStencilDesc; + +/// Contains the data for the fov-stencil mesh. Parts of the struct are filled by the caller +/// while some parts are filled by the SDK. +/// \see ovr_GetFovStencil +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrFovStencilMeshBuffer_ { + /// Vertex info + int AllocVertexCount; ///< To be filled in by caller of ovr_GetFovStencil + int UsedVertexCount; ///< To be filled in by SDK and returned to caller + ovrVector2f* VertexBuffer; ///< To be allocated by caller and filled in by SDK + + /// Index info + int AllocIndexCount; ///< To be filled in by caller of ovr_GetFovStencil + int UsedIndexCount; ///< To be filled in by SDK and returned to caller + uint16_t* IndexBuffer; ///< To be allocated by caller and filled in by SDK +} ovrFovStencilMeshBuffer; + +/// Returns a viewport stencil mesh to be used for defining the area or outline the user +/// can see through the lens on an area defined by a given ovrFovPort. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] fovStencilDesc Info provided by caller necessary to generate a stencil mesh. +/// \param[in] meshBuffer Mesh buffer to be partially filled in and returned by the SDK. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of +/// failure, use ovr_GetLastErrorInfo to get more information. +/// Return values include but aren't limited to: +/// - ovrSuccess: Completed successfully. +/// - ovrError_ServiceConnection: The service connection was lost and the application +/// must destroy the session. +/// - ovrError_InvalidParameter: One or more of the parameters +/// +/// To find out how big the vertex and index buffers in meshBuffer buffer should be, first call +/// this function setting AllocVertexCount & AllocIndexCount to 0 while also sending in nullptr +/// for VertexBuffer & IndexBuffer. The SDK will populate UsedVertexCount & UsedIndexCount values. +/// +/// If Alloc*Count fields in meshBuffer are smaller than the expected Used*Count fields, +/// (except when they are 0) then the SDK will return ovrError_InvalidParameter and leave +/// VertexBuffer and IndexBuffer untouched. +/// +/// 2D positions provided in the buffer will be in the [0,1] range where Y increases downward, +/// similar to texture-UV space. If Y coordinates need to be flipped upside down, use the +/// ovrFovStencilFlag_MeshOriginAtBottomLeft. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetFovStencil( + ovrSession session, + const ovrFovStencilDesc* fovStencilDesc, + ovrFovStencilMeshBuffer* meshBuffer); + +//----------------------------------------------------------------------------------- + +/// Describes button input types. +/// Button inputs are combined; that is they will be reported as pressed if they are +/// pressed on either one of the two devices. +/// The ovrButton_Up/Down/Left/Right map to both XBox D-Pad and directional buttons. +/// The ovrButton_Enter and ovrButton_Return map to Start and Back controller buttons, respectively. +typedef enum ovrButton_ { + /// A button on XBox controllers and right Touch controller. Not present on Oculus Remote. + ovrButton_A = 0x00000001, + + /// B button on XBox controllers and right Touch controller. Not present on Oculus Remote. + ovrButton_B = 0x00000002, + + /// Right thumbstick on XBox controllers and Touch controllers. Not present on Oculus Remote. + ovrButton_RThumb = 0x00000004, + + /// Right shoulder button on XBox controllers. Not present on Touch controllers or Oculus Remote. + ovrButton_RShoulder = 0x00000008, + + + /// X button on XBox controllers and left Touch controller. Not present on Oculus Remote. + ovrButton_X = 0x00000100, + + /// Y button on XBox controllers and left Touch controller. Not present on Oculus Remote. + ovrButton_Y = 0x00000200, + + /// Left thumbstick on XBox controllers and Touch controllers. Not present on Oculus Remote. + ovrButton_LThumb = 0x00000400, + + /// Left shoulder button on XBox controllers. Not present on Touch controllers or Oculus Remote. + ovrButton_LShoulder = 0x00000800, + + /// Up button on XBox controllers and Oculus Remote. Not present on Touch controllers. + ovrButton_Up = 0x00010000, + + /// Down button on XBox controllers and Oculus Remote. Not present on Touch controllers. + ovrButton_Down = 0x00020000, + + /// Left button on XBox controllers and Oculus Remote. Not present on Touch controllers. + ovrButton_Left = 0x00040000, + + /// Right button on XBox controllers and Oculus Remote. Not present on Touch controllers. + ovrButton_Right = 0x00080000, + + /// Start on XBox 360 controller. Menu on XBox One controller and Left Touch controller. + /// Select button on Oculus Remote. + /// Should be referred to as the Menu button in user-facing documentation. + ovrButton_Enter = 0x00100000, + + /// Back on Xbox 360 controller and Oculus Remote. View button on XBox One controller. + /// Not present on Touch controllers. + ovrButton_Back = 0x00200000, + + /// Volume button on Oculus Remote. Not present on XBox or Touch controllers. + ovrButton_VolUp = 0x00400000, + + /// Volume button on Oculus Remote. Not present on XBox or Touch controllers. + ovrButton_VolDown = 0x00800000, + + /// Home button on XBox controllers. Oculus button on Touch controllers and Oculus Remote. + ovrButton_Home = 0x01000000, + + // Bit mask of all buttons that are for private usage by Oculus + ovrButton_Private = ovrButton_VolUp | ovrButton_VolDown | ovrButton_Home, + + // Bit mask of all buttons on the right Touch controller + ovrButton_RMask = ovrButton_A | ovrButton_B | ovrButton_RThumb | ovrButton_RShoulder, + + // Bit mask of all buttons on the left Touch controller + ovrButton_LMask = + ovrButton_X | ovrButton_Y | ovrButton_LThumb | ovrButton_LShoulder | ovrButton_Enter, + + ovrButton_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrButton; + +/// Describes touch input types. +/// These values map to capacitive touch values reported ovrInputState::Touch. +/// Some of these values are mapped to button bits for consistency. +typedef enum ovrTouch_ { + ovrTouch_A = ovrButton_A, + ovrTouch_B = ovrButton_B, + ovrTouch_RThumb = ovrButton_RThumb, + ovrTouch_RThumbRest = 0x00000008, + ovrTouch_RIndexTrigger = 0x00000010, + + // Bit mask of all the button touches on the right controller + ovrTouch_RButtonMask = + ovrTouch_A | ovrTouch_B | ovrTouch_RThumb | ovrTouch_RThumbRest | ovrTouch_RIndexTrigger, + + ovrTouch_X = ovrButton_X, + ovrTouch_Y = ovrButton_Y, + ovrTouch_LThumb = ovrButton_LThumb, + ovrTouch_LThumbRest = 0x00000800, + ovrTouch_LIndexTrigger = 0x00001000, + + // Bit mask of all the button touches on the left controller + ovrTouch_LButtonMask = + ovrTouch_X | ovrTouch_Y | ovrTouch_LThumb | ovrTouch_LThumbRest | ovrTouch_LIndexTrigger, + + // Finger pose state + // Derived internally based on distance, proximity to sensors and filtering. + ovrTouch_RIndexPointing = 0x00000020, + ovrTouch_RThumbUp = 0x00000040, + ovrTouch_LIndexPointing = 0x00002000, + ovrTouch_LThumbUp = 0x00004000, + + // Bit mask of all right controller poses + ovrTouch_RPoseMask = ovrTouch_RIndexPointing | ovrTouch_RThumbUp, + + // Bit mask of all left controller poses + ovrTouch_LPoseMask = ovrTouch_LIndexPointing | ovrTouch_LThumbUp, + + ovrTouch_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrTouch; + +/// Describes the Touch Haptics engine. +/// Currently, those values will NOT change during a session. +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrTouchHapticsDesc_ { + // Haptics engine frequency/sample-rate, sample time in seconds equals 1.0/sampleRateHz + int SampleRateHz; + // Size of each Haptics sample, sample value range is [0, 2^(Bytes*8)-1] + int SampleSizeInBytes; + + // Queue size that would guarantee Haptics engine would not starve for data + // Make sure size doesn't drop below it for best results + int QueueMinSizeToAvoidStarvation; + + // Minimum, Maximum and Optimal number of samples that can be sent to Haptics through + // ovr_SubmitControllerVibration + int SubmitMinSamples; + int SubmitMaxSamples; + int SubmitOptimalSamples; +} ovrTouchHapticsDesc; + +/// Specifies which controller is connected; multiple can be connected at once. +typedef enum ovrControllerType_ { + ovrControllerType_None = 0x0000, + ovrControllerType_LTouch = 0x0001, + ovrControllerType_RTouch = 0x0002, + ovrControllerType_Touch = (ovrControllerType_LTouch | ovrControllerType_RTouch), + ovrControllerType_Remote = 0x0004, + + ovrControllerType_XBox = 0x0010, + + ovrControllerType_Object0 = 0x0100, + ovrControllerType_Object1 = 0x0200, + ovrControllerType_Object2 = 0x0400, + ovrControllerType_Object3 = 0x0800, + + + ovrControllerType_Active = 0xffffffff, ///< Operate on or query whichever controller is active. + + ovrControllerType_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrControllerType; + +/// Haptics buffer submit mode +typedef enum ovrHapticsBufferSubmitMode_ { + /// Enqueue buffer for later playback + ovrHapticsBufferSubmit_Enqueue +} ovrHapticsBufferSubmitMode; + +/// Maximum number of samples in ovrHapticsBuffer +#define OVR_HAPTICS_BUFFER_SAMPLES_MAX 256 + +/// Haptics buffer descriptor, contains amplitude samples used for Touch vibration +typedef struct ovrHapticsBuffer_ { + /// Samples stored in opaque format + const void* Samples; + /// Number of samples (up to OVR_HAPTICS_BUFFER_SAMPLES_MAX) + int SamplesCount; + /// How samples are submitted to the hardware + ovrHapticsBufferSubmitMode SubmitMode; +} ovrHapticsBuffer; + +/// State of the Haptics playback for Touch vibration +typedef struct ovrHapticsPlaybackState_ { + // Remaining space available to queue more samples + int RemainingQueueSpace; + + // Number of samples currently queued + int SamplesQueued; +} ovrHapticsPlaybackState; + +/// Position tracked devices +typedef enum ovrTrackedDeviceType_ { + ovrTrackedDevice_None = 0x0000, + ovrTrackedDevice_HMD = 0x0001, + ovrTrackedDevice_LTouch = 0x0002, + ovrTrackedDevice_RTouch = 0x0004, + ovrTrackedDevice_Touch = (ovrTrackedDevice_LTouch | ovrTrackedDevice_RTouch), + + ovrTrackedDevice_Object0 = 0x0010, + ovrTrackedDevice_Object1 = 0x0020, + ovrTrackedDevice_Object2 = 0x0040, + ovrTrackedDevice_Object3 = 0x0080, + + ovrTrackedDevice_All = 0xFFFF, +} ovrTrackedDeviceType; + +/// Boundary types that specified while using the boundary system +typedef enum ovrBoundaryType_ { + /// Outer boundary - closely represents user setup walls + ovrBoundary_Outer = 0x0001, + + /// Play area - safe rectangular area inside outer boundary which can optionally be used to + /// restrict user interactions and motion. + ovrBoundary_PlayArea = 0x0100, +} ovrBoundaryType; + +/// Boundary system look and feel +typedef struct ovrBoundaryLookAndFeel_ { + /// Boundary color (alpha channel is ignored) + ovrColorf Color; +} ovrBoundaryLookAndFeel; + +/// Provides boundary test information +typedef struct ovrBoundaryTestResult_ { + /// True if the boundary system is being triggered. Note that due to fade in/out effects this may + /// not exactly match visibility. + ovrBool IsTriggering; + + /// Distance to the closest play area or outer boundary surface. + float ClosestDistance; + + /// Closest point on the boundary surface. + ovrVector3f ClosestPoint; + + /// Unit surface normal of the closest boundary surface. + ovrVector3f ClosestPointNormal; +} ovrBoundaryTestResult; + +/// Provides names for the left and right hand array indexes. +/// +/// \see ovrInputState, ovrTrackingState +/// +typedef enum ovrHandType_ { + ovrHand_Left = 0, + ovrHand_Right = 1, + ovrHand_Count = 2, + ovrHand_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrHandType; + +/// ovrInputState describes the complete controller input state, including Oculus Touch, +/// and XBox gamepad. If multiple inputs are connected and used at the same time, +/// their inputs are combined. +typedef struct ovrInputState_ { + /// System type when the controller state was last updated. + double TimeInSeconds; + + /// Values for buttons described by ovrButton. + unsigned int Buttons; + + /// Touch values for buttons and sensors as described by ovrTouch. + unsigned int Touches; + + /// Left and right finger trigger values (ovrHand_Left and ovrHand_Right), in range 0.0 to 1.0f. + /// Returns 0 if the value would otherwise be less than 0.1176, for ovrControllerType_XBox. + /// This has been formally named simply "Trigger". We retain the name IndexTrigger for backwards + /// code compatibility. + /// User-facing documentation should refer to it as the Trigger. + float IndexTrigger[ovrHand_Count]; + + /// Left and right hand trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f. + /// This has been formally named "Grip Button". We retain the name HandTrigger for backwards code + /// compatibility. + /// User-facing documentation should refer to it as the Grip Button or simply Grip. + float HandTrigger[ovrHand_Count]; + + /// Horizontal and vertical thumbstick axis values (ovrHand_Left and ovrHand_Right), in the range + /// of -1.0f to 1.0f. + /// Returns a deadzone (value 0) per each axis if the value on that axis would otherwise have been + /// between -.2746 to +.2746, for ovrControllerType_XBox + ovrVector2f Thumbstick[ovrHand_Count]; + + /// The type of the controller this state is for. + ovrControllerType ControllerType; + + /// Left and right finger trigger values (ovrHand_Left and ovrHand_Right), in range 0.0 to 1.0f. + /// Does not apply a deadzone. Only touch applies a filter. + /// This has been formally named simply "Trigger". We retain the name IndexTrigger for backwards + /// code compatibility. + /// User-facing documentation should refer to it as the Trigger. + float IndexTriggerNoDeadzone[ovrHand_Count]; + + /// Left and right hand trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f. + /// Does not apply a deadzone. Only touch applies a filter. + /// This has been formally named "Grip Button". We retain the name HandTrigger for backwards code + /// compatibility. + /// User-facing documentation should refer to it as the Grip Button or simply Grip. + float HandTriggerNoDeadzone[ovrHand_Count]; + + /// Horizontal and vertical thumbstick axis values (ovrHand_Left and ovrHand_Right), in the range + /// -1.0f to 1.0f + /// Does not apply a deadzone or filter. + ovrVector2f ThumbstickNoDeadzone[ovrHand_Count]; + + /// Left and right finger trigger values (ovrHand_Left and ovrHand_Right), in range 0.0 to 1.0f. + /// No deadzone or filter + /// This has been formally named "Grip Button". We retain the name HandTrigger for backwards code + /// compatibility. + /// User-facing documentation should refer to it as the Grip Button or simply Grip. + float IndexTriggerRaw[ovrHand_Count]; + + /// Left and right hand trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f. + /// No deadzone or filter + /// This has been formally named "Grip Button". We retain the name HandTrigger for backwards code + /// compatibility. + /// User-facing documentation should refer to it as the Grip Button or simply Grip. + float HandTriggerRaw[ovrHand_Count]; + + /// Horizontal and vertical thumbstick axis values (ovrHand_Left and ovrHand_Right), in the range + /// -1.0f to 1.0f + /// No deadzone or filter + ovrVector2f ThumbstickRaw[ovrHand_Count]; + +} ovrInputState; + + +typedef struct ovrCameraIntrinsics_ { + /// Time in seconds from last change to the parameters + double LastChangedTime; + + /// Angles of all 4 sides of viewport + ovrFovPort FOVPort; + + /// Near plane of the virtual camera used to match the external camera + float VirtualNearPlaneDistanceMeters; + + /// Far plane of the virtual camera used to match the external camera + float VirtualFarPlaneDistanceMeters; + + /// Height in pixels of image sensor + ovrSizei ImageSensorPixelResolution; + + /// The lens distortion matrix of camera + ovrMatrix4f LensDistortionMatrix; + + /// How often, in seconds, the exposure is taken + double ExposurePeriodSeconds; + + /// length of the exposure time + double ExposureDurationSeconds; + +} ovrCameraIntrinsics; + +typedef enum ovrCameraStatusFlags_ { + /// Initial state of camera + ovrCameraStatus_None = 0x0, + + /// Bit set when the camera is connected to the system + ovrCameraStatus_Connected = 0x1, + + /// Bit set when the camera is undergoing calibration + ovrCameraStatus_Calibrating = 0x2, + + /// Bit set when the camera has tried & failed calibration + ovrCameraStatus_CalibrationFailed = 0x4, + + /// Bit set when the camera has tried & passed calibration + ovrCameraStatus_Calibrated = 0x8, + + /// Bit set when the camera is capturing + ovrCameraStatus_Capturing = 0x10, + + ovrCameraStatus_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrCameraStatusFlags; + +typedef struct ovrCameraExtrinsics_ { + /// Time in seconds from last change to the parameters. + /// For instance, if the pose changes, or a camera exposure happens, this struct will be updated. + double LastChangedTimeSeconds; + + /// Current Status of the camera, a mix of bits from ovrCameraStatusFlags + unsigned int CameraStatusFlags; + + /// Which Tracked device, if any, is the camera rigidly attached to + /// If set to ovrTrackedDevice_None, then the camera is not attached to a tracked object. + /// If the external camera moves while unattached (i.e. set to ovrTrackedDevice_None), its Pose + /// won't be updated + ovrTrackedDeviceType AttachedToDevice; + + /// The relative Pose of the External Camera. + /// If AttachedToDevice is ovrTrackedDevice_None, then this is a absolute pose in tracking space + ovrPosef RelativePose; + + /// The time, in seconds, when the last successful exposure was taken + double LastExposureTimeSeconds; + + /// Estimated exposure latency to get from the exposure time to the system + double ExposureLatencySeconds; + + /// Additional latency to get from the exposure time of the real camera to match the render time + /// of the virtual camera + double AdditionalLatencySeconds; + +} ovrCameraExtrinsics; +#define OVR_MAX_EXTERNAL_CAMERA_COUNT 16 +#define OVR_EXTERNAL_CAMERA_NAME_SIZE 32 +typedef struct ovrExternalCamera_ { + char Name[OVR_EXTERNAL_CAMERA_NAME_SIZE]; // camera identifier: vid + pid + serial number etc. + ovrCameraIntrinsics Intrinsics; + ovrCameraExtrinsics Extrinsics; +} ovrExternalCamera; + +//----------------------------------------------------------------------------------- +// ***** Initialize structures + +/// Initialization flags. +/// +/// \see ovrInitParams, ovr_Initialize +/// +typedef enum ovrInitFlags_ { + /// When a debug library is requested, a slower debugging version of the library will + /// run which can be used to help solve problems in the library and debug application code. + ovrInit_Debug = 0x00000001, + + + /// When a version is requested, the LibOVR runtime respects the RequestedMinorVersion + /// field and verifies that the RequestedMinorVersion is supported. Normally when you + /// specify this flag you simply use OVR_MINOR_VERSION for ovrInitParams::RequestedMinorVersion, + /// though you could use a lower version than OVR_MINOR_VERSION to specify previous + /// version behavior. + ovrInit_RequestVersion = 0x00000004, + + + /// This client will not be visible in the HMD. + /// Typically set by diagnostic or debugging utilities. + ovrInit_Invisible = 0x00000010, + + /// This client will alternate between VR and 2D rendering. + /// Typically set by game engine editors and VR-enabled web browsers. + ovrInit_MixedRendering = 0x00000020, + + /// This client is aware of ovrSessionStatus focus states (e.g. ovrSessionStatus::HasInputFocus), + /// and responds to them appropriately (e.g. pauses and stops drawing hands when lacking focus). + ovrInit_FocusAware = 0x00000040, + + + + + + + /// These bits are writable by user code. + ovrinit_WritableBits = 0x00ffffff, + + ovrInit_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrInitFlags; + +/// Logging levels +/// +/// \see ovrInitParams, ovrLogCallback +/// +typedef enum ovrLogLevel_ { + ovrLogLevel_Debug = 0, ///< Debug-level log event. + ovrLogLevel_Info = 1, ///< Info-level log event. + ovrLogLevel_Error = 2, ///< Error-level log event. + + ovrLogLevel_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrLogLevel; + +/// Signature of the logging callback function pointer type. +/// +/// \param[in] userData is an arbitrary value specified by the user of ovrInitParams. +/// \param[in] level is one of the ovrLogLevel constants. +/// \param[in] message is a UTF8-encoded null-terminated string. +/// \see ovrInitParams, ovrLogLevel, ovr_Initialize +/// +typedef void(OVR_CDECL* ovrLogCallback)(uintptr_t userData, int level, const char* message); + +/// Parameters for ovr_Initialize. +/// +/// \see ovr_Initialize +/// +typedef struct OVR_ALIGNAS(8) ovrInitParams_ { + /// Flags from ovrInitFlags to override default behavior. + /// Use 0 for the defaults. + uint32_t Flags; + + /// Requests a specific minor version of the LibOVR runtime. + /// Flags must include ovrInit_RequestVersion or this will be ignored and OVR_MINOR_VERSION + /// will be used. If you are directly calling the LibOVRRT version of ovr_Initialize + /// in the LibOVRRT DLL then this must be valid and include ovrInit_RequestVersion. + uint32_t RequestedMinorVersion; + + /// User-supplied log callback function, which may be called at any time + /// asynchronously from multiple threads until ovr_Shutdown completes. + /// Use NULL to specify no log callback. + ovrLogCallback LogCallback; + + /// User-supplied data which is passed as-is to LogCallback. Typically this + /// is used to store an application-specific pointer which is read in the + /// callback function. + uintptr_t UserData; + + /// Relative number of milliseconds to wait for a connection to the server + /// before failing. Use 0 for the default timeout. + uint32_t ConnectionTimeoutMS; + + OVR_ON64(OVR_UNUSED_STRUCT_PAD(pad0, 4)) ///< \internal + +} ovrInitParams; + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if !defined(OVR_EXPORTING_CAPI) + +// ----------------------------------------------------------------------------------- +// ***** API Interfaces + +/// Initializes LibOVR +/// +/// Initialize LibOVR for application usage. This includes finding and loading the LibOVRRT +/// shared library. No LibOVR API functions, other than ovr_GetLastErrorInfo and ovr_Detect, can +/// be called unless ovr_Initialize succeeds. A successful call to ovr_Initialize must be eventually +/// followed by a call to ovr_Shutdown. ovr_Initialize calls are idempotent. +/// Calling ovr_Initialize twice does not require two matching calls to ovr_Shutdown. +/// If already initialized, the return value is ovr_Success. +/// +/// LibOVRRT shared library search order: +/// -# Current working directory (often the same as the application directory). +/// -# Module directory (usually the same as the application directory, +/// but not if the module is a separate shared library). +/// -# Application directory +/// -# Standard OS shared library search location(s) (OS-specific). +/// +/// \param params Specifies custom initialization options. May be NULL to indicate default options +/// when using the CAPI shim. If you are directly calling the LibOVRRT version of +/// ovr_Initialize in the LibOVRRT DLL then this must be valid and +/// include ovrInit_RequestVersion. +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. Example failed results include: +/// - ovrError_Initialize: Generic initialization error. +/// - ovrError_LibLoad: Couldn't load LibOVRRT. +/// - ovrError_LibVersion: LibOVRRT version incompatibility. +/// - ovrError_ServiceConnection: Couldn't connect to the OVR Service. +/// - ovrError_ServiceVersion: OVR Service version incompatibility. +/// - ovrError_IncompatibleOS: The operating system version is incompatible. +/// - ovrError_DisplayInit: Unable to initialize the HMD display. +/// - ovrError_ServerStart: Unable to start the server. Is it already running? +/// - ovrError_Reinitialization: Attempted to re-initialize with a different version. +/// +/// Example code +/// \code{.cpp} +/// ovrInitParams initParams = { ovrInit_RequestVersion, OVR_MINOR_VERSION, NULL, 0, 0 }; +/// ovrResult result = ovr_Initialize(&initParams); +/// if(OVR_FAILURE(result)) { +/// ovrErrorInfo errorInfo; +/// ovr_GetLastErrorInfo(&errorInfo); +/// DebugLog("ovr_Initialize failed: %s", errorInfo.ErrorString); +/// return false; +/// } +/// [...] +/// \endcode +/// +/// \see ovr_Shutdown +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_Initialize(const ovrInitParams* params); + +/// Shuts down LibOVR +/// +/// A successful call to ovr_Initialize must be eventually matched by a call to ovr_Shutdown. +/// After calling ovr_Shutdown, no LibOVR functions can be called except ovr_GetLastErrorInfo +/// or another ovr_Initialize. ovr_Shutdown invalidates all pointers, references, and created +/// objects +/// previously returned by LibOVR functions. The LibOVRRT shared library can be unloaded by +/// ovr_Shutdown. +/// +/// \see ovr_Initialize +/// +OVR_PUBLIC_FUNCTION(void) ovr_Shutdown(); + +/// Returns information about the most recent failed return value by the +/// current thread for this library. +/// +/// This function itself can never generate an error. +/// The last error is never cleared by LibOVR, but will be overwritten by new errors. +/// Do not use this call to determine if there was an error in the last API +/// call as successful API calls don't clear the last ovrErrorInfo. +/// To avoid any inconsistency, ovr_GetLastErrorInfo should be called immediately +/// after an API function that returned a failed ovrResult, with no other API +/// functions called in the interim. +/// +/// \param[out] errorInfo The last ovrErrorInfo for the current thread. +/// +/// \see ovrErrorInfo +/// +OVR_PUBLIC_FUNCTION(void) ovr_GetLastErrorInfo(ovrErrorInfo* errorInfo); + +/// Returns the version string representing the LibOVRRT version. +/// +/// The returned string pointer is valid until the next call to ovr_Shutdown. +/// +/// Note that the returned version string doesn't necessarily match the current +/// OVR_MAJOR_VERSION, etc., as the returned string refers to the LibOVRRT shared +/// library version and not the locally compiled interface version. +/// +/// The format of this string is subject to change in future versions and its contents +/// should not be interpreted. +/// +/// \return Returns a UTF8-encoded null-terminated version string. +/// +OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString(); + +/// Writes a message string to the LibOVR tracing mechanism (if enabled). +/// +/// This message will be passed back to the application via the ovrLogCallback if +/// it was registered. +/// +/// \param[in] level One of the ovrLogLevel constants. +/// \param[in] message A UTF8-encoded null-terminated string. +/// \return returns the strlen of the message or a negative value if the message is too large. +/// +/// \see ovrLogLevel, ovrLogCallback +/// +OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message); + +/// Identify client application info. +/// +/// The string is one or more newline-delimited lines of optional info +/// indicating engine name, engine version, engine plugin name, engine plugin +/// version, engine editor. The order of the lines is not relevant. Individual +/// lines are optional. A newline is not necessary at the end of the last line. +/// Call after ovr_Initialize and before the first call to ovr_Create. +/// Each value is limited to 20 characters. Key names such as 'EngineName:' +/// 'EngineVersion:' do not count towards this limit. +/// +/// \param[in] identity Specifies one or more newline-delimited lines of optional info: +/// EngineName: %s\n +/// EngineVersion: %s\n +/// EnginePluginName: %s\n +/// EnginePluginVersion: %s\n +/// EngineEditor: ('true' or 'false')\n +/// +/// Example code +/// \code{.cpp} +/// ovr_IdentifyClient("EngineName: Unity\n" +/// "EngineVersion: 5.3.3\n" +/// "EnginePluginName: OVRPlugin\n" +/// "EnginePluginVersion: 1.2.0\n" +/// "EngineEditor: true"); +/// \endcode +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_IdentifyClient(const char* identity); + +//------------------------------------------------------------------------------------- +/// @name HMD Management +/// +/// Handles the enumeration, creation, destruction, and properties of an HMD (head-mounted display). +///@{ + +/// Returns native color space information about the current HMD. +/// +/// ovr_Initialize must be called prior to calling this function, otherwise call will fail. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create() or NULL. +/// +/// \return Returns an ovrHmdColorDesc. +/// +OVR_PUBLIC_FUNCTION(ovrHmdColorDesc) ovr_GetHmdColorDesc(ovrSession session); + +/// Sets the color space actively being used by the client app. +/// +/// This value does not have to follow the color space provided in ovr_GetHmdColorDesc. It should +/// reflect the color space the final rendered frame the client has submitted to the SDK. +/// If this function is never called, the session will keep using the default color space deemed +/// appropriate by the runtime. See remarks in ovrColorSpace enum for more info on default behavior. +/// +/// ovr_Initialize must be called prior to calling this function, otherwise call will fail. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create() or NULL. +/// \param[in] colorDesc Specifies the color description to use for the current HMD. +/// +/// \return Returns an ovrResult indicating success or failure. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SetClientColorDesc(ovrSession session, const ovrHmdColorDesc* colorDesc); + +/// Returns information about the current HMD. +/// +/// ovr_Initialize must be called prior to calling this function, +/// otherwise ovrHmdDesc::Type will be set to ovrHmd_None without +/// checking for the HMD presence. +/// +/// For newer headsets being used on a game built against an old SDK version, +/// we may return the ovrHmdType as ovrHmd_CV1 for backwards compatibility. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create() or NULL. +/// +/// \return Returns an ovrHmdDesc. If invoked with NULL session argument, ovrHmdDesc::Type +/// set to ovrHmd_None indicates that the HMD is not connected. +/// +OVR_PUBLIC_FUNCTION(ovrHmdDesc) ovr_GetHmdDesc(ovrSession session); + +/// Returns the number of attached trackers. +/// +/// The number of trackers may change at any time, so this function should be called before use +/// as opposed to once on startup. +/// +/// For newer headsets being used on a game built against an old SDK version, +/// we may simulate three CV1 trackers to maintain backwards compatibility. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// +/// \return Returns unsigned int count. +/// +OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetTrackerCount(ovrSession session); + +/// Returns a given attached tracker description. +/// +/// ovr_Initialize must have first been called in order for this to succeed, otherwise the returned +/// trackerDescArray will be zero-initialized. The data returned by this function can change at +/// runtime. +/// +/// For newer headsets being used on a game built against an old SDK version, +/// we may simulate three CV1 trackers to maintain backwards compatibility. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// +/// \param[in] trackerDescIndex Specifies a tracker index. The valid indexes are in the +/// range of 0 to the tracker count returned by ovr_GetTrackerCount. +/// +/// \return Returns ovrTrackerDesc. An empty ovrTrackerDesc will be returned if +/// trackerDescIndex is out of range. +/// +/// \see ovrTrackerDesc, ovr_GetTrackerCount +/// +OVR_PUBLIC_FUNCTION(ovrTrackerDesc) +ovr_GetTrackerDesc(ovrSession session, unsigned int trackerDescIndex); + +/// Creates a handle to a VR session. +/// +/// Upon success the returned ovrSession must be eventually freed with ovr_Destroy when it is no +/// longer needed. +/// A second call to ovr_Create will result in an error return value if the previous session has not +/// been destroyed. +/// +/// \param[out] pSession Provides a pointer to an ovrSession which will be written to upon success. +/// \param[out] pLuid Provides a system specific graphics adapter identifier that locates which +/// graphics adapter has the HMD attached. This must match the adapter used by the application +/// or no rendering output will be possible. This is important for stability on multi-adapter +/// systems. An +/// application that simply chooses the default adapter will not run reliably on multi-adapter +/// systems. +/// \return Returns an ovrResult indicating success or failure. Upon failure +/// the returned ovrSession will be NULL. +/// +/// Example code +/// \code{.cpp} +/// ovrSession session; +/// ovrGraphicsLuid luid; +/// ovrResult result = ovr_Create(&session, &luid); +/// if(OVR_FAILURE(result)) +/// ... +/// \endcode +/// +/// \see ovr_Destroy +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_Create(ovrSession* pSession, ovrGraphicsLuid* pLuid); + +/// Destroys the session. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \see ovr_Create +/// +OVR_PUBLIC_FUNCTION(void) ovr_Destroy(ovrSession session); + + +#endif // !defined(OVR_EXPORTING_CAPI) + +/// Specifies status information for the current session. +/// +/// \see ovr_GetSessionStatus +/// +typedef struct ovrSessionStatus_ { + /// True if the process has VR focus and thus is visible in the HMD. + ovrBool IsVisible; + + /// True if an HMD is present. + ovrBool HmdPresent; + + /// True if the HMD is on the user's head. + ovrBool HmdMounted; + + /// True if the session is in a display-lost state. See ovr_SubmitFrame. + ovrBool DisplayLost; + + /// True if the application should initiate shutdown. + ovrBool ShouldQuit; + + /// True if UX has requested re-centering. Must call ovr_ClearShouldRecenterFlag, + /// ovr_RecenterTrackingOrigin or ovr_SpecifyTrackingOrigin. + ovrBool ShouldRecenter; + + /// True if the application is the foreground application and receives input (e.g. Touch + /// controller state). If this is false then the application is in the background (but possibly + /// still visible) should hide any input representations such as hands. + ovrBool HasInputFocus; + + /// True if a system overlay is present, such as a dashboard. In this case the application + /// (if visible) should pause while still drawing, avoid drawing near-field graphics so they + /// don't visually fight with the system overlay, and consume fewer CPU and GPU resources. + /// \deprecated Do not use. + ovrBool OverlayPresent; + + /// True if runtime is requesting that the application provide depth buffers with projection + /// layers. + ovrBool DepthRequested; + +} ovrSessionStatus; + +#if !defined(OVR_EXPORTING_CAPI) + +/// Returns status information for the application. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[out] sessionStatus Provides an ovrSessionStatus that is filled in. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of +/// failure, use ovr_GetLastErrorInfo to get more information. +/// Return values include but aren't limited to: +/// - ovrSuccess: Completed successfully. +/// - ovrError_ServiceConnection: The service connection was lost and the application +/// must destroy the session. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetSessionStatus(ovrSession session, ovrSessionStatus* sessionStatus); + + +/// Query extension support status. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] extension Extension to query. +/// \param[out] outExtensionSupported Set to extension support status. ovrTrue if supported. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of +/// failure use ovr_GetLastErrorInfo to get more information. +/// +/// \see ovrExtensions +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_IsExtensionSupported( + ovrSession session, + ovrExtensions extension, + ovrBool* outExtensionSupported); + +/// Enable extension. Extensions must be enabled after ovr_Create is called. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] extension Extension to enable. +/// +/// \return Returns an ovrResult indicating success or failure. Extension is only +/// enabled if successful. In the case of failure use ovr_GetLastErrorInfo +/// to get more information. +/// +/// \see ovrExtensions +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_EnableExtension(ovrSession session, ovrExtensions extension); + + +//@} + +//------------------------------------------------------------------------------------- +/// @name Tracking +/// +/// Tracking functions handle the position, orientation, and movement of the HMD in space. +/// +/// All tracking interface functions are thread-safe, allowing tracking state to be sampled +/// from different threads. +/// +///@{ + + +/// Sets the tracking origin type +/// +/// When the tracking origin is changed, all of the calls that either provide +/// or accept ovrPosef will use the new tracking origin provided. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] origin Specifies an ovrTrackingOrigin to be used for all ovrPosef +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// \see ovrTrackingOrigin, ovr_GetTrackingOriginType +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SetTrackingOriginType(ovrSession session, ovrTrackingOrigin origin); + +/// Gets the tracking origin state +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// +/// \return Returns the ovrTrackingOrigin that was either set by default, or previous set by the +/// application. +/// +/// \see ovrTrackingOrigin, ovr_SetTrackingOriginType +OVR_PUBLIC_FUNCTION(ovrTrackingOrigin) ovr_GetTrackingOriginType(ovrSession session); + +/// Re-centers the sensor position and orientation. +/// +/// This resets the (x,y,z) positional components and the yaw orientation component of the +/// tracking space for the HMD and controllers using the HMD's current tracking pose. +/// If the caller requires some tweaks on top of the HMD's current tracking pose, consider using +/// ovr_SpecifyTrackingOrigin instead. +/// +/// The roll and pitch orientation components are always determined by gravity and cannot +/// be redefined. All future tracking will report values relative to this new reference position. +/// If you are using ovrTrackerPoses then you will need to call ovr_GetTrackerPose after +/// this, because the sensor position(s) will change as a result of this. +/// +/// The headset cannot be facing vertically upward or downward but rather must be roughly +/// level otherwise this function will fail with ovrError_InvalidHeadsetOrientation. +/// +/// For more info, see the notes on each ovrTrackingOrigin enumeration to understand how +/// recenter will vary slightly in its behavior based on the current ovrTrackingOrigin setting. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. Return values include but aren't limited +/// to: +/// - ovrSuccess: Completed successfully. +/// - ovrError_InvalidHeadsetOrientation: The headset was facing an invalid direction when +/// attempting recentering, such as facing vertically. +/// +/// \see ovrTrackingOrigin, ovr_GetTrackerPose, ovr_SpecifyTrackingOrigin +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_RecenterTrackingOrigin(ovrSession session); + +/// Allows manually tweaking the sensor position and orientation. +/// +/// This function is similar to ovr_RecenterTrackingOrigin in that it modifies the +/// (x,y,z) positional components and the yaw orientation component of the tracking space for +/// the HMD and controllers. +/// +/// While ovr_RecenterTrackingOrigin resets the tracking origin in reference to the HMD's +/// current pose, ovr_SpecifyTrackingOrigin allows the caller to explicitly specify a transform +/// for the tracking origin. This transform is expected to be an offset to the most recent +/// recentered origin, so calling this function repeatedly with the same originPose will keep +/// nudging the recentered origin in that direction. +/// +/// There are several use cases for this function. For example, if the application decides to +/// limit the yaw, or translation of the recentered pose instead of directly using the HMD pose +/// the application can query the current tracking state via ovr_GetTrackingState, and apply +/// some limitations to the HMD pose because feeding this pose back into this function. +/// Similarly, this can be used to "adjust the seating position" incrementally in apps that +/// feature seated experiences such as cockpit-based games. +/// +/// This function can emulate ovr_RecenterTrackingOrigin as such: +/// ovrTrackingState ts = ovr_GetTrackingState(session, 0.0, ovrFalse); +/// ovr_SpecifyTrackingOrigin(session, ts.HeadPose.ThePose); +/// +/// The roll and pitch orientation components are determined by gravity and cannot be redefined. +/// If you are using ovrTrackerPoses then you will need to call ovr_GetTrackerPose after +/// this, because the sensor position(s) will change as a result of this. +/// +/// For more info, see the notes on each ovrTrackingOrigin enumeration to understand how +/// recenter will vary slightly in its behavior based on the current ovrTrackingOrigin setting. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] originPose Specifies a pose that will be used to transform the current tracking +/// origin. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. Return values include but aren't limited +/// to: +/// - ovrSuccess: Completed successfully. +/// - ovrError_InvalidParameter: The heading direction in originPose was invalid, +/// such as facing vertically. This can happen if the caller is directly feeding the pose +/// of a position-tracked device such as an HMD or controller into this function. +/// +/// \see ovrTrackingOrigin, ovr_GetTrackerPose, ovr_RecenterTrackingOrigin +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_SpecifyTrackingOrigin(ovrSession session, ovrPosef originPose); + +/// Clears the ShouldRecenter status bit in ovrSessionStatus. +/// +/// Clears the ShouldRecenter status bit in ovrSessionStatus, allowing further recenter requests to +/// be detected. Since this is automatically done by ovr_RecenterTrackingOrigin and +/// ovr_SpecifyTrackingOrigin, this function only needs to be called when application is doing +/// its own re-centering logic. +OVR_PUBLIC_FUNCTION(void) ovr_ClearShouldRecenterFlag(ovrSession session); + +/// Returns tracking state reading based on the specified absolute system time. +/// +/// Pass an absTime value of 0.0 to request the most recent sensor reading. In this case +/// both PredictedPose and SamplePose will have the same value. +/// +/// This may also be used for more refined timing of front buffer rendering logic, and so on. +/// This may be called by multiple threads. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] absTime Specifies the absolute future time to predict the return +/// ovrTrackingState value. Use 0 to request the most recent tracking state. +/// \param[in] latencyMarker Specifies that this call is the point in time where +/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer +/// provides "SensorSampleTime", that will override the value stored here. +/// \return Returns the ovrTrackingState that is predicted for the given absTime. +/// +/// \see ovrTrackingState, ovr_GetEyePoses, ovr_GetTimeInSeconds +/// +OVR_PUBLIC_FUNCTION(ovrTrackingState) +ovr_GetTrackingState(ovrSession session, double absTime, ovrBool latencyMarker); + +/// Returns an array of poses, where each pose matches a device type provided by the deviceTypes +/// array parameter. If any pose cannot be retrieved, it will return a reason for the missing +/// pose and the device pose will be zeroed out with a pose quaternion [x=0, y=0, z=0, w=1]. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] deviceTypes Array of device types to query for their poses. +/// \param[in] deviceCount Number of queried poses. This number must match the length of the +/// outDevicePoses and deviceTypes array. +/// \param[in] absTime Specifies the absolute future time to predict the return +/// ovrTrackingState value. Use 0 to request the most recent tracking state. +/// \param[out] outDevicePoses Array of poses, one for each device type in deviceTypes arrays. +/// +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and +/// true upon success. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetDevicePoses( + ovrSession session, + ovrTrackedDeviceType* deviceTypes, + int deviceCount, + double absTime, + ovrPoseStatef* outDevicePoses); + + +/// Returns the ovrTrackerPose for the given attached tracker. +/// +/// For newer headsets being used on a game built against an old SDK version, +/// we may simulate three CV1 trackers to maintain backwards compatibility. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] trackerPoseIndex Index of the tracker being requested. +/// +/// \return Returns the requested ovrTrackerPose. An empty ovrTrackerPose will be returned if +/// trackerPoseIndex is out of range. +/// +/// \see ovr_GetTrackerCount +/// +OVR_PUBLIC_FUNCTION(ovrTrackerPose) +ovr_GetTrackerPose(ovrSession session, unsigned int trackerPoseIndex); + +/// Returns the most recent input state for controllers, without positional tracking info. +/// +/// \param[out] inputState Input state that will be filled in. +/// \param[in] controllerType Specifies which controller the input will be returned for. +/// \return Returns ovrSuccess if the new state was successfully obtained. +/// +/// \see ovrControllerType +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetInputState(ovrSession session, ovrControllerType controllerType, ovrInputState* inputState); + + +/// Returns controller types connected to the system OR'ed together. +/// +/// \return A bitmask of ovrControllerTypes connected to the system. +/// +/// \see ovrControllerType +/// +OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetConnectedControllerTypes(ovrSession session); + +/// Gets information about Haptics engine for the specified Touch controller. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] controllerType The controller to retrieve the information from. +/// +/// \return Returns an ovrTouchHapticsDesc. +/// +OVR_PUBLIC_FUNCTION(ovrTouchHapticsDesc) +ovr_GetTouchHapticsDesc(ovrSession session, ovrControllerType controllerType); + +/// Sets constant vibration (with specified frequency and amplitude) to a controller. +/// Note: ovr_SetControllerVibration cannot be used interchangeably with +/// ovr_SubmitControllerVibration. +/// +/// This method should be called periodically, vibration lasts for a maximum of 2.5 seconds. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] controllerType The controller to set the vibration to. +/// \param[in] frequency Vibration frequency. Supported values are: 0.0 (disabled), 0.5 and 1.0. Non +/// valid values will be clamped. +/// \param[in] amplitude Vibration amplitude in the [0.0, 1.0] range. +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: The call succeeded and a result was returned. +/// - ovrSuccess_DeviceUnavailable: The call succeeded but the device referred to by +/// controllerType is not available. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SetControllerVibration( + ovrSession session, + ovrControllerType controllerType, + float frequency, + float amplitude); + +/// Submits a Haptics buffer (used for vibration) to Touch (only) controllers. +/// Note: ovr_SubmitControllerVibration cannot be used interchangeably with +/// ovr_SetControllerVibration. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] controllerType Controller where the Haptics buffer will be played. +/// \param[in] buffer Haptics buffer containing amplitude samples to be played. +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: The call succeeded and a result was returned. +/// - ovrSuccess_DeviceUnavailable: The call succeeded but the device referred to by +/// controllerType is not available. +/// +/// \see ovrHapticsBuffer +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SubmitControllerVibration( + ovrSession session, + ovrControllerType controllerType, + const ovrHapticsBuffer* buffer); + +/// Gets the Haptics engine playback state of a specific Touch controller. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] controllerType Controller where the Haptics buffer wil be played. +/// \param[in] outState State of the haptics engine. +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: The call succeeded and a result was returned. +/// - ovrSuccess_DeviceUnavailable: The call succeeded but the device referred to by +/// controllerType is not available. +/// +/// \see ovrHapticsPlaybackState +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetControllerVibrationState( + ovrSession session, + ovrControllerType controllerType, + ovrHapticsPlaybackState* outState); + + +/// Tests collision/proximity of position tracked devices (e.g. HMD and/or Touch) against the +/// Boundary System. +/// Note: this method is similar to ovr_BoundaryTestPoint but can be more precise as it may take +/// into account device acceleration/momentum. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] deviceBitmask Bitmask of one or more tracked devices to test. +/// \param[in] boundaryType Must be either ovrBoundary_Outer or ovrBoundary_PlayArea. +/// \param[out] outTestResult Result of collision/proximity test, contains information such as +/// distance and closest point. +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: The call succeeded and a result was returned. +/// - ovrSuccess_BoundaryInvalid: The call succeeded but the result is not a valid boundary due +/// to not being set up. +/// - ovrSuccess_DeviceUnavailable: The call succeeded but the device referred to by +/// deviceBitmask is not available. +/// +/// \see ovrBoundaryTestResult +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_TestBoundary( + ovrSession session, + ovrTrackedDeviceType deviceBitmask, + ovrBoundaryType boundaryType, + ovrBoundaryTestResult* outTestResult); + +/// Tests collision/proximity of a 3D point against the Boundary System. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] point 3D point to test. +/// \param[in] singleBoundaryType Must be either ovrBoundary_Outer or ovrBoundary_PlayArea to test +/// against +/// \param[out] outTestResult Result of collision/proximity test, contains information such as +/// distance and closest point. +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: The call succeeded and a result was returned. +/// - ovrSuccess_BoundaryInvalid: The call succeeded but the result is not a valid boundary due +/// to not being set up. +/// +/// \see ovrBoundaryTestResult +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_TestBoundaryPoint( + ovrSession session, + const ovrVector3f* point, + ovrBoundaryType singleBoundaryType, + ovrBoundaryTestResult* outTestResult); + +/// Compatibility stub. +/// +/// \deprecated Previously set the look and feel of the Boundary System - this functionality has +/// been removed. +/// +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] lookAndFeel Look and feel parameters. +/// \return Returns ovrSuccess upon success. +/// \see ovrBoundaryLookAndFeel +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SetBoundaryLookAndFeel(ovrSession session, const ovrBoundaryLookAndFeel* lookAndFeel); + +/// Resets the look and feel of the Boundary System to its default state. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \return Returns ovrSuccess upon success. +/// \see ovrBoundaryLookAndFeel +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_ResetBoundaryLookAndFeel(ovrSession session); + +/// Gets the geometry of the Boundary System's "play area" or "outer boundary" as 3D floor points. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] boundaryType Must be either ovrBoundary_Outer or ovrBoundary_PlayArea. +/// \param[out] outFloorPoints Array of 3D points (in clockwise order) defining the boundary at +/// floor height (can be NULL to retrieve only the number of points). +/// \param[out] outFloorPointsCount Number of 3D points returned in the array. +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: The call succeeded and a result was returned. +/// - ovrSuccess_BoundaryInvalid: The call succeeded but the result is not a valid boundary due +/// to not being set up. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetBoundaryGeometry( + ovrSession session, + ovrBoundaryType boundaryType, + ovrVector3f* outFloorPoints, + int* outFloorPointsCount); + +/// Gets the dimension of the Boundary System's "play area" or "outer boundary". +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] boundaryType Must be either ovrBoundary_Outer or ovrBoundary_PlayArea. +/// \param[out] outDimensions Dimensions of the axis aligned bounding box that encloses the area in +/// meters (width, height and length). +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: The call succeeded and a result was returned. +/// - ovrSuccess_BoundaryInvalid: The call succeeded but the result is not a valid boundary due +/// to not being set up. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetBoundaryDimensions( + ovrSession session, + ovrBoundaryType boundaryType, + ovrVector3f* outDimensions); + +/// Returns if the boundary is currently visible. +/// Note: visibility is false if the user has turned off boundaries, otherwise, it's true if +/// the app has requested boundaries to be visible or if any tracked device is currently +/// triggering it. This may not exactly match rendering due to fade-in and fade-out effects. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[out] outIsVisible ovrTrue, if the boundary is visible. +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: Result was successful and a result was returned. +/// - ovrSuccess_BoundaryInvalid: The call succeeded but the result is not a valid boundary due +/// to not being set up. +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetBoundaryVisible(ovrSession session, ovrBool* outIsVisible); + +/// Requests boundary to be visible. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] visible forces the outer boundary to be visible. An application can't force it +/// to be invisible, but can cancel its request by passing false. +/// \return Returns ovrSuccess upon success. +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_RequestBoundaryVisible(ovrSession session, ovrBool visible); + +// ----------------------------------------------------------------------------------- +/// @name Mixed reality capture support +/// +/// Defines functions used for mixed reality capture / third person cameras. +/// + +/// Returns the number of camera properties of all cameras +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in, out] cameras Pointer to the array. If null and the provided array capacity is +/// sufficient, will return ovrError_NullArrayPointer. +/// \param[in, out] inoutCameraCount Supply the +/// array capacity, will return the actual # of cameras defined. If *inoutCameraCount is too small, +/// will return ovrError_InsufficientArraySize. +/// \return Returns the list of external cameras the system knows about. +/// Returns ovrError_NoExternalCameraInfo if there is not any eternal camera information. +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetExternalCameras( + ovrSession session, + ovrExternalCamera* cameras, + unsigned int* inoutCameraCount); + +/// Sets the camera intrinsics and/or extrinsics stored for the cameraName camera +/// Names must be < 32 characters and null-terminated. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] name Specifies which camera to set the intrinsics or extrinsics for. +/// The name must be at most OVR_EXTERNAL_CAMERA_NAME_SIZE - 1 +/// characters. Otherwise, ovrError_ExternalCameraNameWrongSize is returned. +/// \param[in] intrinsics Contains the intrinsic parameters to set, can be null +/// \param[in] extrinsics Contains the extrinsic parameters to set, can be null +/// \return Returns ovrSuccess or an ovrError code +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SetExternalCameraProperties( + ovrSession session, + const char* name, + const ovrCameraIntrinsics* const intrinsics, + const ovrCameraExtrinsics* const extrinsics); + +///@} + +#endif // !defined(OVR_EXPORTING_CAPI) + +//------------------------------------------------------------------------------------- +// @name Layers +// +///@{ + +/// Specifies the maximum number of layers supported by ovr_SubmitFrame. +/// +/// /see ovr_SubmitFrame +/// +enum { ovrMaxLayerCount = 16 }; + +/// Describes layer types that can be passed to ovr_SubmitFrame. +/// Each layer type has an associated struct, such as ovrLayerEyeFov. +/// +/// \see ovrLayerHeader +/// +typedef enum ovrLayerType_ { + /// Layer is disabled. + ovrLayerType_Disabled = 0, + + /// Described by ovrLayerEyeFov. + ovrLayerType_EyeFov = 1, + + /// Described by ovrLayerEyeFovDepth. + ovrLayerType_EyeFovDepth = 2, + + /// Described by ovrLayerQuad. Previously called ovrLayerType_QuadInWorld. + ovrLayerType_Quad = 3, + + // enum 4 used to be ovrLayerType_QuadHeadLocked. Instead, use ovrLayerType_Quad with + // ovrLayerFlag_HeadLocked. + + /// Described by ovrLayerEyeMatrix. + ovrLayerType_EyeMatrix = 5, + + + /// Described by ovrLayerEyeFovMultires. + ovrLayerType_EyeFovMultires = 7, + + /// Described by ovrLayerCylinder. + ovrLayerType_Cylinder = 8, + + /// Described by ovrLayerCube + ovrLayerType_Cube = 10, + + + + + ovrLayerType_EnumSize = 0x7fffffff ///< Force type int32_t. + +} ovrLayerType; + +/// Identifies flags used by ovrLayerHeader and which are passed to ovr_SubmitFrame. +/// +/// \see ovrLayerHeader +/// +typedef enum ovrLayerFlags_ { + /// ovrLayerFlag_HighQuality enables 4x anisotropic sampling during the composition of the layer. + /// The benefits are mostly visible at the periphery for high-frequency & high-contrast visuals. + /// For best results consider combining this flag with an ovrTextureSwapChain that has mipmaps and + /// instead of using arbitrary sized textures, prefer texture sizes that are powers-of-two. + /// Actual rendered viewport and doesn't necessarily have to fill the whole texture. + ovrLayerFlag_HighQuality = 0x01, + + /// ovrLayerFlag_TextureOriginAtBottomLeft: the opposite is TopLeft. + /// Generally this is false for D3D, true for OpenGL. + ovrLayerFlag_TextureOriginAtBottomLeft = 0x02, + + /// Mark this surface as "headlocked", which means it is specified + /// relative to the HMD and moves with it, rather than being specified + /// relative to sensor/torso space and remaining still while the head moves. + /// What used to be ovrLayerType_QuadHeadLocked is now ovrLayerType_Quad plus this flag. + /// However the flag can be applied to any layer type to achieve a similar effect. + ovrLayerFlag_HeadLocked = 0x04, + + + ovrLayerFlags_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrLayerFlags; + +/// Defines properties shared by all ovrLayer structs, such as ovrLayerEyeFov. +/// +/// ovrLayerHeader is used as a base member in these larger structs. +/// This struct cannot be used by itself except for the case that Type is ovrLayerType_Disabled. +/// +/// \see ovrLayerType, ovrLayerFlags +/// +typedef struct ovrLayerHeader_ ovrLayerHeader; +struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerHeader_ { + ovrLayerType Type; ///< Described by ovrLayerType. + unsigned Flags; ///< Described by ovrLayerFlags. + + char Reserved[128]; +}; + +/// Describes a layer that specifies a monoscopic or stereoscopic view. +/// This is the kind of layer that's typically used as layer 0 to ovr_SubmitFrame, +/// as it is the kind of layer used to render a 3D stereoscopic view. +/// +/// Three options exist with respect to mono/stereo texture usage: +/// - ColorTexture[0] and ColorTexture[1] contain the left and right stereo renderings, +/// respectively. +/// Viewport[0] and Viewport[1] refer to ColorTexture[0] and ColorTexture[1], respectively. +/// - ColorTexture[0] contains both the left and right renderings, ColorTexture[1] is NULL, +/// and Viewport[0] and Viewport[1] refer to sub-rects with ColorTexture[0]. +/// - ColorTexture[0] contains a single monoscopic rendering, and Viewport[0] and +/// Viewport[1] both refer to that rendering. +/// +/// \see ovrTextureSwapChain, ovr_SubmitFrame +/// +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerEyeFov_ { + /// Header.Type must be ovrLayerType_EyeFov. + ovrLayerHeader Header; + + /// ovrTextureSwapChains for the left and right eye respectively. + /// The second one of which can be NULL for cases described above. + ovrTextureSwapChain ColorTexture[ovrEye_Count]; + + /// Specifies the ColorTexture sub-rect UV coordinates. + /// Both Viewport[0] and Viewport[1] must be valid. + ovrRecti Viewport[ovrEye_Count]; + + /// The viewport field of view. + ovrFovPort Fov[ovrEye_Count]; + + /// Specifies the position and orientation of each eye view, with position specified in meters. + /// RenderPose will typically be the value returned from ovr_CalcEyePoses, + /// but can be different in special cases if a different head pose is used for rendering. + ovrPosef RenderPose[ovrEye_Count]; + + /// Specifies the timestamp when the source ovrPosef (used in calculating RenderPose) + /// was sampled from the SDK. Typically retrieved by calling ovr_GetTimeInSeconds + /// around the instant the application calls ovr_GetTrackingState + /// The main purpose for this is to accurately track app tracking latency. + double SensorSampleTime; +} ovrLayerEyeFov; + +/// Describes a layer that specifies a monoscopic or stereoscopic view, +/// with depth textures in addition to color textures. This is typically used to support +/// positional time warp. This struct is the same as ovrLayerEyeFov, but with the addition +/// of DepthTexture and ProjectionDesc. +/// +/// ProjectionDesc can be created using ovrTimewarpProjectionDesc_FromProjection. +/// +/// Three options exist with respect to mono/stereo texture usage: +/// - ColorTexture[0] and ColorTexture[1] contain the left and right stereo renderings, +/// respectively. +/// Viewport[0] and Viewport[1] refer to ColorTexture[0] and ColorTexture[1], respectively. +/// - ColorTexture[0] contains both the left and right renderings, ColorTexture[1] is NULL, +/// and Viewport[0] and Viewport[1] refer to sub-rects with ColorTexture[0]. +/// - ColorTexture[0] contains a single monoscopic rendering, and Viewport[0] and +/// Viewport[1] both refer to that rendering. +/// +/// \see ovrTextureSwapChain, ovr_SubmitFrame +/// +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerEyeFovDepth_ { + /// Header.Type must be ovrLayerType_EyeFovDepth. + ovrLayerHeader Header; + + /// ovrTextureSwapChains for the left and right eye respectively. + /// The second one of which can be NULL for cases described above. + ovrTextureSwapChain ColorTexture[ovrEye_Count]; + + /// Specifies the ColorTexture sub-rect UV coordinates. + /// Both Viewport[0] and Viewport[1] must be valid. + ovrRecti Viewport[ovrEye_Count]; + + /// The viewport field of view. + ovrFovPort Fov[ovrEye_Count]; + + /// Specifies the position and orientation of each eye view, with position specified in meters. + /// RenderPose will typically be the value returned from ovr_CalcEyePoses, + /// but can be different in special cases if a different head pose is used for rendering. + ovrPosef RenderPose[ovrEye_Count]; + + /// Specifies the timestamp when the source ovrPosef (used in calculating RenderPose) + /// was sampled from the SDK. Typically retrieved by calling ovr_GetTimeInSeconds + /// around the instant the application calls ovr_GetTrackingState + /// The main purpose for this is to accurately track app tracking latency. + double SensorSampleTime; + + /// Depth texture for depth composition with overlays + /// Must map 1:1 to the ColorTexture. + ovrTextureSwapChain DepthTexture[ovrEye_Count]; + + /// Specifies how to convert DepthTexture information into meters. + /// \see ovrTimewarpProjectionDesc_FromProjection + ovrTimewarpProjectionDesc ProjectionDesc; +} ovrLayerEyeFovDepth; + + +/// Describes eye texture layouts. Used with ovrLayerEyeFovMultires. +/// +typedef enum ovrTextureLayout_ { + ovrTextureLayout_Rectilinear = 0, ///< Regular eyeFov layer. + ovrTextureLayout_Octilinear = 1, ///< Octilinear extension must be enabled. + ovrTextureLayout_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrTextureLayout; + +/// Multiresolution descriptor for Octilinear. +/// +/// Usage of this layer must be successfully enabled via ovr_EnableExtension +/// before it can be used. +/// +/// \see ovrLayerEyeFovMultres +/// +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrTextureLayoutOctilinear_ { + // W warping + float WarpLeft; + float WarpRight; + float WarpUp; + float WarpDown; + + // Size of W quadrants. + // + // SizeLeft + SizeRight <= Viewport.Size.w + // SizeUp + sizeDown <= Viewport.Size.h + // + // Clip space (0,0) is located at Viewport.Pos + (SizeLeft,SizeUp) where + // Viewport is given in the layer description. + // + // Viewport Top left + // +-----------------------------------------------------+ + // | ^ | | + // | | | | + // | 0 SizeUp 1 | | + // | | |<--Portion of viewport + // | | | determined by sizes + // | | | | + // |<--------SizeLeft-------+-------SizeRight------>| | + // | | | | + // | | | | + // | 2 SizeDown 3 | | + // | | | | + // | | | | + // | v | | + // +------------------------------------------------+ | + // | | + // +-----------------------------------------------------+ + // Viewport bottom right + // + // For example, when rendering quadrant 0 its scissor rectangle will be + // + // Top = 0 + // Left = 0 + // Right = SizeLeft + // Bottom = SizeUp + // + // and the scissor rectangle for quadrant 1 will be: + // + // Top = 0 + // Left = SizeLeft + // Right = SizeLeft + SizeRight + // Bottom = SizeUp + // + float SizeLeft; + float SizeRight; + float SizeUp; + float SizeDown; + +} ovrTextureLayoutOctilinear; + +/// Combines texture layout descriptors. +/// +typedef union OVR_ALIGNAS(OVR_PTR_SIZE) ovrTextureLayoutDesc_Union_ { + ovrTextureLayoutOctilinear Octilinear[ovrEye_Count]; +} ovrTextureLayoutDesc_Union; + +/// Describes a layer that specifies a monoscopic or stereoscopic view with +/// support for optional multiresolution textures. This struct is the same as +/// ovrLayerEyeFov plus texture layout parameters. +/// +/// Three options exist with respect to mono/stereo texture usage: +/// - ColorTexture[0] and ColorTexture[1] contain the left and right stereo renderings, +/// respectively. +/// Viewport[0] and Viewport[1] refer to ColorTexture[0] and ColorTexture[1], respectively. +/// - ColorTexture[0] contains both the left and right renderings, ColorTexture[1] is NULL, +/// and Viewport[0] and Viewport[1] refer to sub-rects with ColorTexture[0]. +/// - ColorTexture[0] contains a single monoscopic rendering, and Viewport[0] and +/// Viewport[1] both refer to that rendering. +/// +/// \see ovrTextureSwapChain, ovr_SubmitFrame +/// +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerEyeFovMultires_ { + /// Header.Type must be ovrLayerType_EyeFovMultires. + ovrLayerHeader Header; + + /// ovrTextureSwapChains for the left and right eye respectively. + /// The second one of which can be NULL for cases described above. + ovrTextureSwapChain ColorTexture[ovrEye_Count]; + + /// Specifies the ColorTexture sub-rect UV coordinates. + /// Both Viewport[0] and Viewport[1] must be valid. + ovrRecti Viewport[ovrEye_Count]; + + /// The viewport field of view. + ovrFovPort Fov[ovrEye_Count]; + + /// Specifies the position and orientation of each eye view, with position specified in meters. + /// RenderPose will typically be the value returned from ovr_CalcEyePoses, + /// but can be different in special cases if a different head pose is used for rendering. + ovrPosef RenderPose[ovrEye_Count]; + + /// Specifies the timestamp when the source ovrPosef (used in calculating RenderPose) + /// was sampled from the SDK. Typically retrieved by calling ovr_GetTimeInSeconds + /// around the instant the application calls ovr_GetTrackingState + /// The main purpose for this is to accurately track app tracking latency. + double SensorSampleTime; + + /// Specifies layout type of textures. + ovrTextureLayout TextureLayout; + + /// Specifies texture layout parameters. + ovrTextureLayoutDesc_Union TextureLayoutDesc; +} ovrLayerEyeFovMultires; + +/// Describes a layer that specifies a monoscopic or stereoscopic view. +/// This uses a direct 3x4 matrix to map from view space to the UV coordinates. +/// It is essentially the same thing as ovrLayerEyeFov but using a much +/// lower level. This is mainly to provide compatibility with specific apps. +/// Unless the application really requires this flexibility, it is usually better +/// to use ovrLayerEyeFov. +/// +/// Three options exist with respect to mono/stereo texture usage: +/// - ColorTexture[0] and ColorTexture[1] contain the left and right stereo renderings, +/// respectively. +/// Viewport[0] and Viewport[1] refer to ColorTexture[0] and ColorTexture[1], respectively. +/// - ColorTexture[0] contains both the left and right renderings, ColorTexture[1] is NULL, +/// and Viewport[0] and Viewport[1] refer to sub-rects with ColorTexture[0]. +/// - ColorTexture[0] contains a single monoscopic rendering, and Viewport[0] and +/// Viewport[1] both refer to that rendering. +/// +/// \see ovrTextureSwapChain, ovr_SubmitFrame +/// +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerEyeMatrix_ { + /// Header.Type must be ovrLayerType_EyeMatrix. + ovrLayerHeader Header; + + /// ovrTextureSwapChains for the left and right eye respectively. + /// The second one of which can be NULL for cases described above. + ovrTextureSwapChain ColorTexture[ovrEye_Count]; + + /// Specifies the ColorTexture sub-rect UV coordinates. + /// Both Viewport[0] and Viewport[1] must be valid. + ovrRecti Viewport[ovrEye_Count]; + + /// Specifies the position and orientation of each eye view, with position specified in meters. + /// RenderPose will typically be the value returned from ovr_CalcEyePoses, + /// but can be different in special cases if a different head pose is used for rendering. + ovrPosef RenderPose[ovrEye_Count]; + + /// Specifies the mapping from a view-space vector + /// to a UV coordinate on the textures given above. + /// P = (x,y,z,1)*Matrix + /// TexU = P.x/P.z + /// TexV = P.y/P.z + ovrMatrix4f Matrix[ovrEye_Count]; + + /// Specifies the timestamp when the source ovrPosef (used in calculating RenderPose) + /// was sampled from the SDK. Typically retrieved by calling ovr_GetTimeInSeconds + /// around the instant the application calls ovr_GetTrackingState + /// The main purpose for this is to accurately track app tracking latency. + double SensorSampleTime; +} ovrLayerEyeMatrix; + +/// Describes a layer of Quad type, which is a single quad in world or viewer space. +/// It is used for ovrLayerType_Quad. This type of layer represents a single +/// object placed in the world and not a stereo view of the world itself. +/// +/// A typical use of ovrLayerType_Quad is to draw a television screen in a room +/// that for some reason is more convenient to draw as a layer than as part of the main +/// view in layer 0. For example, it could implement a 3D popup GUI that is drawn at a +/// higher resolution than layer 0 to improve fidelity of the GUI. +/// +/// Quad layers are visible from both sides; they are not back-face culled. +/// +/// \see ovrTextureSwapChain, ovr_SubmitFrame +/// +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerQuad_ { + /// Header.Type must be ovrLayerType_Quad. + ovrLayerHeader Header; + + /// Contains a single image, never with any stereo view. + ovrTextureSwapChain ColorTexture; + + /// Specifies the ColorTexture sub-rect UV coordinates. + ovrRecti Viewport; + + /// Specifies the orientation and position of the center point of a Quad layer type. + /// The supplied direction is the vector perpendicular to the quad. + /// The position is in real-world meters (not the application's virtual world, + /// the physical world the user is in) and is relative to the "zero" position + /// set by ovr_RecenterTrackingOrigin unless the ovrLayerFlag_HeadLocked flag is used. + ovrPosef QuadPoseCenter; + + /// Width and height (respectively) of the quad in meters. + ovrVector2f QuadSize; +} ovrLayerQuad; + +/// Describes a layer of type ovrLayerType_Cylinder which is a single cylinder +/// relative to the recentered origin. This type of layer represents a single +/// object placed in the world and not a stereo view of the world itself. +/// +/// -Z +Y +/// U=0 +--+--+ U=1 +/// +---+ | +---+ +-----------------+ - V=0 +/// +--+ \ | / +--+ | | | +/// +-+ \ / +-+ | | | +/// ++ \ A / ++ | | | +/// ++ \---/ ++ | | | +/// | \ / | | +X | | +/// +-------------C------R------+ +X +--------C--------+ | <--- Height +/// (+Y is out of screen) | | | +/// | | | +/// R = Radius | | | +/// A = Angle (0,2*Pi) | | | +/// C = CylinderPoseCenter | | | +/// U/V = UV Coordinates +-----------------+ - V=1 +/// +/// An identity CylinderPoseCenter places the center of the cylinder +/// at the recentered origin unless the headlocked flag is set. +/// +/// Does not utilize HmdSpaceToWorldScaleInMeters. If necessary, adjust +/// translation and radius. +/// +/// \note Only the interior surface of the cylinder is visible. Use cylinder +/// layers when the user cannot leave the extents of the cylinder. Artifacts may +/// appear when viewing the cylinder's exterior surface. Additionally, while the +/// interface supports an Angle that ranges from [0,2*Pi] the angle should +/// remain less than 1.9*PI to avoid artifacts where the cylinder edges +/// converge. +/// +/// \see ovrTextureSwapChain, ovr_SubmitFrame +/// +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerCylinder_ { + /// Header.Type must be ovrLayerType_Cylinder. + ovrLayerHeader Header; + + /// Contains a single image, never with any stereo view. + ovrTextureSwapChain ColorTexture; + + /// Specifies the ColorTexture sub-rect UV coordinates. + ovrRecti Viewport; + + /// Specifies the orientation and position of the center point of a cylinder layer type. + /// The position is in real-world meters not the application's virtual world, + /// but the physical world the user is in. It is relative to the "zero" position + /// set by ovr_RecenterTrackingOrigin unless the ovrLayerFlag_HeadLocked flag is used. + ovrPosef CylinderPoseCenter; + + /// Radius of the cylinder in meters. + float CylinderRadius; + + /// Angle in radians. Range is from 0 to 2*Pi exclusive covering the entire + /// cylinder (see diagram and note above). + float CylinderAngle; + + /// Custom aspect ratio presumably set based on 'Viewport'. Used to + /// calculate the height of the cylinder based on the arc-length (CylinderAngle) + /// and radius (CylinderRadius) given above. The height of the cylinder is + /// given by: height = (CylinderRadius * CylinderAngle) / CylinderAspectRatio. + /// Aspect ratio is width / height. + float CylinderAspectRatio; +} ovrLayerCylinder; + +/// Describes a layer of type ovrLayerType_Cube which is a single timewarped +/// cubemap at infinity. When looking down the recentered origin's -Z axis, +X +/// face is left and +Y face is up. Similarly, if headlocked the +X face is +/// left, +Y face is up and -Z face is forward. Note that the coordinate system +/// is left-handed. +/// +/// ovrLayerFlag_TextureOriginAtBottomLeft flag is not supported by ovrLayerCube. +/// +/// \see ovrTextureSwapChain, ovr_SubmitFrame +/// +typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerCube_ { + /// Header.Type must be ovrLayerType_Cube. + ovrLayerHeader Header; + + /// Orientation of the cube. + ovrQuatf Orientation; + + /// Contains a single cubemap swapchain (not a stereo pair of swapchains). + ovrTextureSwapChain CubeMapTexture; +} ovrLayerCube; + + +/// Union that combines ovrLayer types in a way that allows them +/// to be used in a polymorphic way. +typedef union ovrLayer_Union_ { + ovrLayerHeader Header; + ovrLayerEyeFov EyeFov; + ovrLayerEyeFovDepth EyeFovDepth; + ovrLayerQuad Quad; + ovrLayerEyeMatrix EyeMatrix; + ovrLayerEyeFovMultires Multires; + ovrLayerCylinder Cylinder; + ovrLayerCube Cube; +} ovrLayer_Union; + +//@} + +#if !defined(OVR_EXPORTING_CAPI) + +/// @name SDK Distortion Rendering +/// +/// All of rendering functions including the configure and frame functions +/// are not thread safe. It is OK to use ConfigureRendering on one thread and handle +/// frames on another thread, but explicit synchronization must be done since +/// functions that depend on configured state are not reentrant. +/// +/// These functions support rendering of distortion by the SDK. +/// +//@{ + +/// TextureSwapChain creation is rendering API-specific. +/// ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL and ovr_CreateTextureSwapChainVk +/// can be found in the rendering API-specific headers, such as OVR_CAPI_D3D.h, OVR_CAPI_GL.h +/// and OVR_CAPI_Vk.h. +/// +/// Gets the number of buffers in an ovrTextureSwapChain. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] chain Specifies the ovrTextureSwapChain for which the length should be retrieved. +/// \param[out] out_Length Returns the number of buffers in the specified chain. +/// +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error. +/// +/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL, ovr_CreateTextureSwapChainVk +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainLength(ovrSession session, ovrTextureSwapChain chain, int* out_Length); + +/// Gets the current index in an ovrTextureSwapChain. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] chain Specifies the ovrTextureSwapChain for which the index should be retrieved. +/// \param[out] out_Index Returns the current (free) index in specified chain. +/// +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error. +/// +/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL, ovr_CreateTextureSwapChainVk +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainCurrentIndex(ovrSession session, ovrTextureSwapChain chain, int* out_Index); + +/// Gets the description of the buffers in an ovrTextureSwapChain +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] chain Specifies the ovrTextureSwapChain for which the description +/// should be retrieved. +/// \param[out] out_Desc Returns the description of the specified chain. +/// +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error. +/// +/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL, ovr_CreateTextureSwapChainVk +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainDesc( + ovrSession session, + ovrTextureSwapChain chain, + ovrTextureSwapChainDesc* out_Desc); + +/// Commits any pending changes to an ovrTextureSwapChain, and advances its current index +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] chain Specifies the ovrTextureSwapChain to commit. +/// +/// \note When Commit is called, the texture at the current index is considered ready for use by the +/// runtime, and further writes to it should be avoided. The swap chain's current index is advanced, +/// providing there's room in the chain. The next time the SDK dereferences this texture swap chain, +/// it will synchronize with the app's graphics context and pick up the submitted index, opening up +/// room in the swap chain for further commits. +/// +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error. +/// Failures include but aren't limited to: +/// - ovrError_TextureSwapChainFull: ovr_CommitTextureSwapChain was called too many times on a +/// texture swapchain without calling submit to use the chain. +/// +/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL, ovr_CreateTextureSwapChainVk +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CommitTextureSwapChain(ovrSession session, ovrTextureSwapChain chain); + +/// Destroys an ovrTextureSwapChain and frees all the resources associated with it. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] chain Specifies the ovrTextureSwapChain to destroy. If it is NULL then +/// this function has no effect. +/// +/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL, ovr_CreateTextureSwapChainVk +/// +OVR_PUBLIC_FUNCTION(void) +ovr_DestroyTextureSwapChain(ovrSession session, ovrTextureSwapChain chain); + +/// MirrorTexture creation is rendering API-specific. +/// ovr_CreateMirrorTextureWithOptionsDX and ovr_CreateMirrorTextureWithOptionsGL can be found in +/// rendering API-specific headers, such as OVR_CAPI_D3D.h and OVR_CAPI_GL.h + +/// Destroys a mirror texture previously created by one of the mirror texture creation functions. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] mirrorTexture Specifies the ovrTexture to destroy. If it is NULL then +/// this function has no effect. +/// +/// \see ovr_CreateMirrorTextureWithOptionsDX, ovr_CreateMirrorTextureWithOptionsGL +/// +OVR_PUBLIC_FUNCTION(void) +ovr_DestroyMirrorTexture(ovrSession session, ovrMirrorTexture mirrorTexture); + +/// Calculates the recommended viewport size for rendering a given eye within the HMD +/// with a given FOV cone. +/// +/// Higher FOV will generally require larger textures to maintain quality. +/// Apps packing multiple eye views together on the same texture should ensure there are +/// at least 8 pixels of padding between them to prevent texture filtering and chromatic +/// aberration causing images to leak between the two eye views. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] eye Specifies which eye (left or right) to calculate for. +/// \param[in] fov Specifies the ovrFovPort to use. +/// \param[in] pixelsPerDisplayPixel Specifies the ratio of the number of render target pixels +/// to display pixels at the center of distortion. 1.0 is the default value. Lower +/// values can improve performance, higher values give improved quality. +/// +/// Example code +/// \code{.cpp} +/// ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session); +/// ovrSizei eyeSizeLeft = ovr_GetFovTextureSize(session, ovrEye_Left, +/// hmdDesc.DefaultEyeFov[ovrEye_Left], 1.0f); +/// ovrSizei eyeSizeRight = ovr_GetFovTextureSize(session, ovrEye_Right, +/// hmdDesc.DefaultEyeFov[ovrEye_Right], 1.0f); +/// \endcode +/// +/// \return Returns the texture width and height size. +/// +OVR_PUBLIC_FUNCTION(ovrSizei) +ovr_GetFovTextureSize( + ovrSession session, + ovrEyeType eye, + ovrFovPort fov, + float pixelsPerDisplayPixel); + +/// Computes the distortion viewport, view adjust, and other rendering parameters for +/// the specified eye. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] eyeType Specifies which eye (left or right) for which to perform calculations. +/// \param[in] fov Specifies the ovrFovPort to use. +/// +/// \return Returns the computed ovrEyeRenderDesc for the given eyeType and field of view. +/// +/// \see ovrEyeRenderDesc +/// +OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) +ovr_GetRenderDesc(ovrSession session, ovrEyeType eyeType, ovrFovPort fov); + +/// Waits until surfaces are available and it is time to begin rendering the frame. Must be +/// called before ovr_BeginFrame, but not necessarily from the same thread. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// +/// \param[in] frameIndex Specifies the targeted application frame index. +/// +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: command completed successfully. +/// - ovrSuccess_NotVisible: rendering of a previous frame completed successfully but was not +/// displayed on the HMD, usually because another application currently has ownership of the +/// HMD. Applications receiving this result should stop rendering new content and call +/// ovr_GetSessionStatus to detect visibility. +/// - ovrError_DisplayLost: The session has become invalid (such as due to a device removal) +/// and the shared resources need to be released (ovr_DestroyTextureSwapChain), the session +/// needs to destroyed (ovr_Destroy) and recreated (ovr_Create), and new resources need to be +/// created (ovr_CreateTextureSwapChainXXX). The application's existing private graphics +/// resources do not need to be recreated unless the new ovr_Create call returns a different +/// GraphicsLuid. +/// +/// \see ovr_BeginFrame, ovr_EndFrame, ovr_GetSessionStatus +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_WaitToBeginFrame(ovrSession session, long long frameIndex); + +/// Called from render thread before application begins rendering. Must be called after +/// ovr_WaitToBeginFrame and before ovr_EndFrame, but not necessarily from the same threads. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// +/// \param[in] frameIndex Specifies the targeted application frame index. It must match what was +/// passed to ovr_WaitToBeginFrame. +/// +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: command completed successfully. +/// - ovrError_DisplayLost: The session has become invalid (such as due to a device removal) +/// and the shared resources need to be released (ovr_DestroyTextureSwapChain), the session +/// needs to destroyed (ovr_Destroy) and recreated (ovr_Create), and new resources need to be +/// created (ovr_CreateTextureSwapChainXXX). The application's existing private graphics +/// resources do not need to be recreated unless the new ovr_Create call returns a different +/// GraphicsLuid. +/// +/// \see ovr_WaitToBeginFrame, ovr_EndFrame +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_BeginFrame(ovrSession session, long long frameIndex); + +/// Called from render thread after application has finished rendering. Must be called after +/// ovr_BeginFrame, but not necessarily from the same thread. Submits layers for distortion and +/// display, which will happen asynchronously. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// +/// \param[in] frameIndex Specifies the targeted application frame index. It must match what was +/// passed to ovr_BeginFrame. +/// +/// \param[in] viewScaleDesc Provides additional information needed only if layerPtrList contains +/// an ovrLayerType_Quad. If NULL, a default version is used based on the current +/// configuration and a 1.0 world scale. +/// +/// \param[in] layerPtrList Specifies a list of ovrLayer pointers, which can include NULL entries to +/// indicate that any previously shown layer at that index is to not be displayed. +/// Each layer header must be a part of a layer structure such as ovrLayerEyeFov or +/// ovrLayerQuad, with Header.Type identifying its type. A NULL layerPtrList entry in the +/// array indicates the absence of the given layer. +/// +/// \param[in] layerCount Indicates the number of valid elements in layerPtrList. The maximum +/// supported layerCount is not currently specified, but may be specified in a future +/// version. +/// +/// - Layers are drawn in the order they are specified in the array, regardless of the layer type. +/// +/// - Layers are not remembered between successive calls to ovr_EndFrame. A layer must be +/// specified in every call to ovr_EndFrame or it won't be displayed. +/// +/// - If a layerPtrList entry that was specified in a previous call to ovr_EndFrame is +/// passed as NULL or is of type ovrLayerType_Disabled, that layer is no longer displayed. +/// +/// - A layerPtrList entry can be of any layer type and multiple entries of the same layer type +/// are allowed. No layerPtrList entry may be duplicated (i.e. the same pointer as an earlier +/// entry). +/// +/// Example code +/// \code{.cpp} +/// ovrLayerEyeFov layer0; +/// ovrLayerQuad layer1; +/// ... +/// ovrLayerHeader* layers[2] = { &layer0.Header, &layer1.Header }; +/// ovrResult result = ovr_EndFrame(session, frameIndex, nullptr, layers, 2); +/// \endcode +/// +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: rendering completed successfully. +/// - ovrError_DisplayLost: The session has become invalid (such as due to a device removal) +/// and the shared resources need to be released (ovr_DestroyTextureSwapChain), the session +/// needs to destroyed (ovr_Destroy) and recreated (ovr_Create), and new resources need to be +/// created (ovr_CreateTextureSwapChainXXX). The application's existing private graphics +/// resources do not need to be recreated unless the new ovr_Create call returns a different +/// GraphicsLuid. +/// - ovrError_TextureSwapChainInvalid: The ovrTextureSwapChain is in an incomplete or +/// inconsistent state. Ensure ovr_CommitTextureSwapChain was called at least once first. +/// +/// \see ovr_WaitToBeginFrame, ovr_BeginFrame, ovrViewScaleDesc, ovrLayerHeader +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_EndFrame( + ovrSession session, + long long frameIndex, + const ovrViewScaleDesc* viewScaleDesc, + ovrLayerHeader const* const* layerPtrList, + unsigned int layerCount); + +/// Submits layers for distortion and display. +/// +/// \deprecated Use ovr_WaitToBeginFrame, ovr_BeginFrame, and ovr_EndFrame instead. +/// +/// ovr_SubmitFrame triggers distortion and processing which might happen asynchronously. +/// The function will return when there is room in the submission queue and surfaces +/// are available. Distortion might or might not have completed. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// +/// \param[in] frameIndex Specifies the targeted application frame index, or 0 to refer to one frame +/// after the last time ovr_SubmitFrame was called. +/// +/// \param[in] viewScaleDesc Provides additional information needed only if layerPtrList contains +/// an ovrLayerType_Quad. If NULL, a default version is used based on the current +/// configuration and a 1.0 world scale. +/// +/// \param[in] layerPtrList Specifies a list of ovrLayer pointers, which can include NULL entries to +/// indicate that any previously shown layer at that index is to not be displayed. +/// Each layer header must be a part of a layer structure such as ovrLayerEyeFov or +/// ovrLayerQuad, with Header.Type identifying its type. A NULL layerPtrList entry in the +/// array indicates the absence of the given layer. +/// +/// \param[in] layerCount Indicates the number of valid elements in layerPtrList. The maximum +/// supported layerCount is not currently specified, but may be specified in a future +/// version. +/// +/// - Layers are drawn in the order they are specified in the array, regardless of the layer type. +/// +/// - Layers are not remembered between successive calls to ovr_SubmitFrame. A layer must be +/// specified in every call to ovr_SubmitFrame or it won't be displayed. +/// +/// - If a layerPtrList entry that was specified in a previous call to ovr_SubmitFrame is +/// passed as NULL or is of type ovrLayerType_Disabled, that layer is no longer displayed. +/// +/// - A layerPtrList entry can be of any layer type and multiple entries of the same layer type +/// are allowed. No layerPtrList entry may be duplicated (i.e. the same pointer as an earlier +/// entry). +/// +/// Example code +/// \code{.cpp} +/// ovrLayerEyeFov layer0; +/// ovrLayerQuad layer1; +/// ... +/// ovrLayerHeader* layers[2] = { &layer0.Header, &layer1.Header }; +/// ovrResult result = ovr_SubmitFrame(session, frameIndex, nullptr, layers, 2); +/// \endcode +/// +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. Return values include but aren't limited to: +/// - ovrSuccess: rendering completed successfully. +/// - ovrSuccess_NotVisible: rendering completed successfully but was not displayed on the HMD, +/// usually because another application currently has ownership of the HMD. Applications +/// receiving this result should stop rendering new content, call ovr_GetSessionStatus +/// to detect visibility. +/// - ovrError_DisplayLost: The session has become invalid (such as due to a device removal) +/// and the shared resources need to be released (ovr_DestroyTextureSwapChain), the session +/// needs to destroyed (ovr_Destroy) and recreated (ovr_Create), and new resources need to be +/// created (ovr_CreateTextureSwapChainXXX). The application's existing private graphics +/// resources do not need to be recreated unless the new ovr_Create call returns a different +/// GraphicsLuid. +/// - ovrError_TextureSwapChainInvalid: The ovrTextureSwapChain is in an incomplete or +/// inconsistent state. Ensure ovr_CommitTextureSwapChain was called at least once first. +/// +/// \see ovr_GetPredictedDisplayTime, ovrViewScaleDesc, ovrLayerHeader, ovr_GetSessionStatus +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SubmitFrame( + ovrSession session, + long long frameIndex, + const ovrViewScaleDesc* viewScaleDesc, + ovrLayerHeader const* const* layerPtrList, + unsigned int layerCount); + +///@} + +#endif // !defined(OVR_EXPORTING_CAPI) + +//------------------------------------------------------------------------------------- +/// @name Frame Timing +/// +//@{ + +/// +/// Contains the performance stats for a given SDK compositor frame +/// +/// All of the 'int' typed fields can be reset via the ovr_ResetPerfStats call. +/// +typedef struct OVR_ALIGNAS(4) ovrPerfStatsPerCompositorFrame_ { + /// Vsync Frame Index - increments with each HMD vertical synchronization signal (i.e. vsync or + /// refresh rate) + /// If the compositor drops a frame, expect this value to increment more than 1 at a time. + int HmdVsyncIndex; + + /// + /// Application stats + /// + + /// Index that increments with each successive ovr_SubmitFrame call + int AppFrameIndex; + + /// If the app fails to call ovr_SubmitFrame on time, then expect this value to increment with + /// each missed frame + int AppDroppedFrameCount; + + /// Motion-to-photon latency for the application + /// This value is calculated by either using the SensorSampleTime provided for the ovrLayerEyeFov + /// or if that + /// is not available, then the call to ovr_GetTrackingState which has latencyMarker set to ovrTrue + float AppMotionToPhotonLatency; + + /// Amount of queue-ahead in seconds provided to the app based on performance and overlap of + /// CPU and GPU utilization. A value of 0.0 would mean the CPU & GPU workload is being completed + /// in 1 frame's worth of time, while 11 ms (on the CV1) of queue ahead would indicate that the + /// app's CPU workload for the next frame is overlapping the GPU workload for the current frame. + float AppQueueAheadTime; + + /// Amount of time in seconds spent on the CPU by the app's render-thread that calls + /// ovr_SubmitFram. Measured as elapsed time between from when app regains control from + /// ovr_SubmitFrame to the next time the app calls ovr_SubmitFrame. + float AppCpuElapsedTime; + + /// Amount of time in seconds spent on the GPU by the app. + /// Measured as elapsed time between each ovr_SubmitFrame call using GPU timing queries. + float AppGpuElapsedTime; + + /// + /// SDK Compositor stats + /// + + /// Index that increments each time the SDK compositor completes a distortion and timewarp pass + /// Since the compositor operates asynchronously, even if the app calls ovr_SubmitFrame too late, + /// the compositor will kick off for each vsync. + int CompositorFrameIndex; + + /// Increments each time the SDK compositor fails to complete in time + /// This is not tied to the app's performance, but failure to complete can be related to other + /// factors such as OS capabilities, overall available hardware cycles to execute the compositor + /// in time and other factors outside of the app's control. + int CompositorDroppedFrameCount; + + /// Motion-to-photon latency of the SDK compositor in seconds. + /// This is the latency of timewarp which corrects the higher app latency as well as dropped app + /// frames. + float CompositorLatency; + + /// The amount of time in seconds spent on the CPU by the SDK compositor. Unless the + /// VR app is utilizing all of the CPU cores at their peak performance, there is a good chance the + /// compositor CPU times will not affect the app's CPU performance in a major way. + float CompositorCpuElapsedTime; + + /// The amount of time in seconds spent on the GPU by the SDK compositor. Any time spent on the + /// compositor will eat away from the available GPU time for the app. + float CompositorGpuElapsedTime; + + /// The amount of time in seconds spent from the point the CPU kicks off the compositor to the + /// point in time the compositor completes the distortion & timewarp on the GPU. In the event the + /// GPU time is not available, expect this value to be -1.0f. + float CompositorCpuStartToGpuEndElapsedTime; + + /// The amount of time in seconds left after the compositor is done on the GPU to the associated + /// V-Sync time. In the event the GPU time is not available, expect this value to be -1.0f. + float CompositorGpuEndToVsyncElapsedTime; + + /// + /// Async Spacewarp stats (ASW) + /// + + /// Will be true if ASW is active for the given frame such that the application is being forced + /// into half the frame-rate while the compositor continues to run at full frame-rate. + ovrBool AswIsActive; + + /// Increments each time ASW it activated where the app was forced in and out of + /// half-rate rendering. + int AswActivatedToggleCount; + + /// Accumulates the number of frames presented by the compositor which had extrapolated + /// ASW frames presented. + int AswPresentedFrameCount; + + /// Accumulates the number of frames that the compositor tried to present when ASW is + /// active but failed. + int AswFailedFrameCount; + +} ovrPerfStatsPerCompositorFrame; + +/// +/// Maximum number of frames of performance stats provided back to the caller of ovr_GetPerfStats +/// +enum { ovrMaxProvidedFrameStats = 5 }; + +/// +/// This is a complete descriptor of the performance stats provided by the SDK +/// +/// \see ovr_GetPerfStats, ovrPerfStatsPerCompositorFrame +typedef struct OVR_ALIGNAS(4) ovrPerfStats_ { + /// FrameStatsCount will have a maximum value set by ovrMaxProvidedFrameStats + /// If the application calls ovr_GetPerfStats at the native refresh rate of the HMD + /// then FrameStatsCount will be 1. If the app's workload happens to force + /// ovr_GetPerfStats to be called at a lower rate, then FrameStatsCount will be 2 or more. + /// If the app does not want to miss any performance data for any frame, it needs to + /// ensure that it is calling ovr_SubmitFrame and ovr_GetPerfStats at a rate that is at least: + /// "HMD_refresh_rate / ovrMaxProvidedFrameStats". On the Oculus Rift CV1 HMD, this will + /// be equal to 18 times per second. + /// + /// The performance entries will be ordered in reverse chronological order such that the + /// first entry will be the most recent one. + ovrPerfStatsPerCompositorFrame FrameStats[ovrMaxProvidedFrameStats]; + int FrameStatsCount; + + /// If the app calls ovr_GetPerfStats at less than 18 fps for CV1, then AnyFrameStatsDropped + /// will be ovrTrue and FrameStatsCount will be equal to ovrMaxProvidedFrameStats. + ovrBool AnyFrameStatsDropped; + + /// AdaptiveGpuPerformanceScale is an edge-filtered value that a caller can use to adjust + /// the graphics quality of the application to keep the GPU utilization in check. The value + /// is calculated as: (desired_GPU_utilization / current_GPU_utilization) + /// As such, when this value is 1.0, the GPU is doing the right amount of work for the app. + /// Lower values mean the app needs to pull back on the GPU utilization. + /// If the app is going to directly drive render-target resolution using this value, then + /// be sure to take the square-root of the value before scaling the resolution with it. + /// Changing render target resolutions however is one of the many things an app can do + /// increase or decrease the amount of GPU utilization. + /// Since AdaptiveGpuPerformanceScale is edge-filtered and does not change rapidly + /// (i.e. reports non-1.0 values once every couple of seconds) the app can make the + /// necessary adjustments and then keep watching the value to see if it has been satisfied. + float AdaptiveGpuPerformanceScale; + + /// Will be true if Async Spacewarp (ASW) is available for this system which is dependent on + /// several factors such as choice of GPU, OS and debug overrides + ovrBool AswIsAvailable; + + /// Contains the Process ID of the VR application the stats are being polled for + /// If an app continues to grab perf stats even when it is not visible, then expect this + /// value to point to the other VR app that has grabbed focus (i.e. became visible) + ovrProcessId VisibleProcessId; +} ovrPerfStats; + +#if !defined(OVR_EXPORTING_CAPI) + +/// Retrieves performance stats for the VR app as well as the SDK compositor. +/// +/// This function will return stats for the VR app that is currently visible in the HMD +/// regardless of what VR app is actually calling this function. +/// +/// If the VR app is trying to make sure the stats returned belong to the same application, +/// the caller can compare the VisibleProcessId with their own process ID. Normally this will +/// be the case if the caller is only calling ovr_GetPerfStats when ovr_GetSessionStatus has +/// IsVisible flag set to be true. +/// +/// If the VR app calling ovr_GetPerfStats is actually the one visible in the HMD, +/// then new perf stats will only be populated after a new call to ovr_SubmitFrame. +/// That means subsequent calls to ovr_GetPerfStats after the first one without calling +/// ovr_SubmitFrame will receive a FrameStatsCount of zero. +/// +/// If the VR app is not visible, or was initially marked as ovrInit_Invisible, then each call +/// to ovr_GetPerfStats will immediately fetch new perf stats from the compositor without +/// a need for the ovr_SubmitFrame call. +/// +/// Even though invisible VR apps do not require ovr_SubmitFrame to be called to gather new +/// perf stats, since stats are generated at the native refresh rate of the HMD (i.e. 90 Hz +/// for CV1), calling it at a higher rate than that would be unnecessary. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[out] outStats Contains the performance stats for the application and SDK compositor +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. +/// +/// \see ovrPerfStats, ovrPerfStatsPerCompositorFrame, ovr_ResetPerfStats +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetPerfStats(ovrSession session, ovrPerfStats* outStats); + +/// Resets the accumulated stats reported in each ovrPerfStatsPerCompositorFrame back to zero. +/// +/// Only the integer values such as HmdVsyncIndex, AppDroppedFrameCount etc. will be reset +/// as the other fields such as AppMotionToPhotonLatency are independent timing values updated +/// per-frame. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true +/// upon success. +/// +/// \see ovrPerfStats, ovrPerfStatsPerCompositorFrame, ovr_GetPerfStats +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_ResetPerfStats(ovrSession session); + +/// Gets the time of the specified frame midpoint. +/// +/// Predicts the time at which the given frame will be displayed. The predicted time +/// is the middle of the time period during which the corresponding eye images will +/// be displayed. +/// +/// The application should increment frameIndex for each successively targeted frame, +/// and pass that index to any relevant OVR functions that need to apply to the frame +/// identified by that index. +/// +/// This function is thread-safe and allows for multiple application threads to target +/// their processing to the same displayed frame. +/// +/// In the even that prediction fails due to various reasons (e.g. the display being off +/// or app has yet to present any frames), the return value will be current CPU time. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] frameIndex Identifies the frame the caller wishes to target. +/// A value of zero returns the next frame index. +/// \return Returns the absolute frame midpoint time for the given frameIndex. +/// \see ovr_GetTimeInSeconds +/// +OVR_PUBLIC_FUNCTION(double) ovr_GetPredictedDisplayTime(ovrSession session, long long frameIndex); + +/// Returns global, absolute high-resolution time in seconds. +/// +/// The time frame of reference for this function is not specified and should not be +/// depended upon. +/// +/// \return Returns seconds as a floating point value. +/// \see ovrPoseStatef, ovrFrameTiming +/// +OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds(); + +#endif // !defined(OVR_EXPORTING_CAPI) + +/// Performance HUD enables the HMD user to see information critical to +/// the real-time operation of the VR application such as latency timing, +/// and CPU & GPU performance metrics +/// +/// App can toggle performance HUD modes as such: +/// \code{.cpp} +/// ovrPerfHudMode PerfHudMode = ovrPerfHud_LatencyTiming; +/// ovr_SetInt(session, OVR_PERF_HUD_MODE, (int)PerfHudMode); +/// \endcode +/// +typedef enum ovrPerfHudMode_ { + ovrPerfHud_Off = 0, ///< Turns off the performance HUD + ovrPerfHud_PerfSummary = 1, ///< Shows performance summary and headroom + ovrPerfHud_LatencyTiming = 2, ///< Shows latency related timing info + ovrPerfHud_AppRenderTiming = 3, ///< Shows render timing info for application + ovrPerfHud_CompRenderTiming = 4, ///< Shows render timing info for OVR compositor + ovrPerfHud_AswStats = 6, ///< Shows Async Spacewarp-specific info + ovrPerfHud_VersionInfo = 5, ///< Shows SDK & HMD version Info + ovrPerfHud_LinkPerf = 7, ///< Shows Oculus Link performance. + ovrPerfHud_Count = 8, ///< \internal Count of enumerated elements. + ovrPerfHud_EnumSize = 0x7fffffff ///< \internal Force type int32_t. +} ovrPerfHudMode; + +/// Layer HUD enables the HMD user to see information about a layer +/// +/// App can toggle layer HUD modes as such: +/// \code{.cpp} +/// ovrLayerHudMode LayerHudMode = ovrLayerHud_Info; +/// ovr_SetInt(session, OVR_LAYER_HUD_MODE, (int)LayerHudMode); +/// \endcode +/// +typedef enum ovrLayerHudMode_ { + ovrLayerHud_Off = 0, ///< Turns off the layer HUD + ovrLayerHud_Info = 1, ///< Shows info about a specific layer + ovrLayerHud_EnumSize = 0x7fffffff +} ovrLayerHudMode; + +///@} + +/// Debug HUD is provided to help developers gauge and debug the fidelity of their app's +/// stereo rendering characteristics. Using the provided quad and crosshair guides, +/// the developer can verify various aspects such as VR tracking units (e.g. meters), +/// stereo camera-parallax properties (e.g. making sure objects at infinity are rendered +/// with the proper separation), measuring VR geometry sizes and distances and more. +/// +/// App can toggle the debug HUD modes as such: +/// \code{.cpp} +/// ovrDebugHudStereoMode DebugHudMode = ovrDebugHudStereo_QuadWithCrosshair; +/// ovr_SetInt(session, OVR_DEBUG_HUD_STEREO_MODE, (int)DebugHudMode); +/// \endcode +/// +/// The app can modify the visual properties of the stereo guide (i.e. quad, crosshair) +/// using the ovr_SetFloatArray function. For a list of tweakable properties, +/// see the OVR_DEBUG_HUD_STEREO_GUIDE_* keys in the OVR_CAPI_Keys.h header file. +typedef enum ovrDebugHudStereoMode_ { + /// Turns off the Stereo Debug HUD. + ovrDebugHudStereo_Off = 0, + + /// Renders Quad in world for Stereo Debugging. + ovrDebugHudStereo_Quad = 1, + + /// Renders Quad+crosshair in world for Stereo Debugging + ovrDebugHudStereo_QuadWithCrosshair = 2, + + /// Renders screen-space crosshair at infinity for Stereo Debugging + ovrDebugHudStereo_CrosshairAtInfinity = 3, + + /// \internal Count of enumerated elements + ovrDebugHudStereo_Count, + + ovrDebugHudStereo_EnumSize = 0x7fffffff ///< \internal Force type int32_t +} ovrDebugHudStereoMode; + +#if !defined(OVR_EXPORTING_CAPI) + +// ----------------------------------------------------------------------------------- +/// @name Property Access +/// +/// These functions read and write OVR properties. Supported properties +/// are defined in OVR_CAPI_Keys.h +/// +//@{ + +/// Reads a boolean property. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] propertyName The name of the property, which needs to be valid for only the call. +/// \param[in] defaultVal specifes the value to return if the property couldn't be read. +/// \return Returns the property interpreted as a boolean value. Returns defaultVal if +/// the property doesn't exist. +OVR_PUBLIC_FUNCTION(ovrBool) +ovr_GetBool(ovrSession session, const char* propertyName, ovrBool defaultVal); + +/// Writes or creates a boolean property. +/// If the property wasn't previously a boolean property, it is changed to a boolean property. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] propertyName The name of the property, which needs to be valid only for the call. +/// \param[in] value The value to write. +/// \return Returns true if successful, otherwise false. A false result should only occur if the +/// property +/// name is empty or if the property is read-only. +OVR_PUBLIC_FUNCTION(ovrBool) +ovr_SetBool(ovrSession session, const char* propertyName, ovrBool value); + +/// Reads an integer property. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] propertyName The name of the property, which needs to be valid only for the call. +/// \param[in] defaultVal Specifes the value to return if the property couldn't be read. +/// \return Returns the property interpreted as an integer value. Returns defaultVal if +/// the property doesn't exist. +OVR_PUBLIC_FUNCTION(int) ovr_GetInt(ovrSession session, const char* propertyName, int defaultVal); + +/// Writes or creates an integer property. +/// +/// If the property wasn't previously a boolean property, it is changed to an integer property. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] propertyName The name of the property, which needs to be valid only for the call. +/// \param[in] value The value to write. +/// \return Returns true if successful, otherwise false. A false result should only occur if the +/// property name is empty or if the property is read-only. +OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetInt(ovrSession session, const char* propertyName, int value); + +/// Reads a float property. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] propertyName The name of the property, which needs to be valid only for the call. +/// \param[in] defaultVal specifes the value to return if the property couldn't be read. +/// \return Returns the property interpreted as an float value. Returns defaultVal if +/// the property doesn't exist. +OVR_PUBLIC_FUNCTION(float) +ovr_GetFloat(ovrSession session, const char* propertyName, float defaultVal); + +/// Writes or creates a float property. +/// If the property wasn't previously a float property, it's changed to a float property. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] propertyName The name of the property, which needs to be valid only for the call. +/// \param[in] value The value to write. +/// \return Returns true if successful, otherwise false. A false result should only occur if the +/// property name is empty or if the property is read-only. +OVR_PUBLIC_FUNCTION(ovrBool) +ovr_SetFloat(ovrSession session, const char* propertyName, float value); + +/// Reads a float array property. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] propertyName The name of the property, which needs to be valid only for the call. +/// \param[in] values An array of float to write to. +/// \param[in] valuesCapacity Specifies the maximum number of elements to write to the values array. +/// \return Returns the number of elements read, or 0 if property doesn't exist or is empty. +OVR_PUBLIC_FUNCTION(unsigned int) +ovr_GetFloatArray( + ovrSession session, + const char* propertyName, + float values[], + unsigned int valuesCapacity); + +/// Writes or creates a float array property. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] propertyName The name of the property, which needs to be valid only for the call. +/// \param[in] values An array of float to write from. +/// \param[in] valuesSize Specifies the number of elements to write. +/// \return Returns true if successful, otherwise false. A false result should only occur if the +/// property name is empty or if the property is read-only. +OVR_PUBLIC_FUNCTION(ovrBool) +ovr_SetFloatArray( + ovrSession session, + const char* propertyName, + const float values[], + unsigned int valuesSize); + +/// Reads a string property. +/// Strings are UTF8-encoded and null-terminated. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] propertyName The name of the property, which needs to be valid only for the call. +/// \param[in] defaultVal Specifes the value to return if the property couldn't be read. +/// \return Returns the string property if it exists. Otherwise returns defaultVal, which can be +/// specified as NULL. The return memory is guaranteed to be valid until next call to +/// ovr_GetString or until the session is destroyed, whichever occurs first. +OVR_PUBLIC_FUNCTION(const char*) +ovr_GetString(ovrSession session, const char* propertyName, const char* defaultVal); + +/// Writes or creates a string property. +/// Strings are UTF8-encoded and null-terminated. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] propertyName The name of the property, which needs to be valid only for the call. +/// \param[in] value The string property, which only needs to be valid for the duration of the call. +/// \return Returns true if successful, otherwise false. A false result should only occur if the +/// property name is empty or if the property is read-only. +OVR_PUBLIC_FUNCTION(ovrBool) +ovr_SetString(ovrSession session, const char* propertyName, const char* value); + +///@} + +#endif // !defined(OVR_EXPORTING_CAPI) + +#ifdef __cplusplus +} // extern "C" +#endif + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +/// @cond DoxygenIgnore + + +OVR_STATIC_ASSERT( + sizeof(ovrTextureSwapChainDesc) == 10 * 4, + "ovrTextureSwapChainDesc size mismatch"); + +// ----------------------------------------------------------------------------------- +// ***** Backward compatibility #includes +// +// This is at the bottom of this file because the following is dependent on the +// declarations above. + +#if !defined(OVR_CAPI_NO_UTILS) +#include "Extras/OVR_CAPI_Util.h" +#endif + +/// @endcond + +#endif // OVR_CAPI_h diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Audio.h b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Audio.h new file mode 100644 index 0000000..8650208 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Audio.h @@ -0,0 +1,85 @@ +/********************************************************************************/ /** + \file OVR_CAPI_Audio.h + \brief CAPI audio functions. + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + ************************************************************************************/ + +#ifndef OVR_CAPI_Audio_h +#define OVR_CAPI_Audio_h + +#ifdef _WIN32 +// Prevents from defining min() and max() macro symbols. +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include "OVR_CAPI.h" +#define OVR_AUDIO_MAX_DEVICE_STR_SIZE 128 + +#if !defined(OVR_EXPORTING_CAPI) + +/// Gets the ID of the preferred VR audio output device. +/// +/// \param[out] deviceOutId The ID of the user's preferred VR audio device to use, +/// which will be valid upon a successful return value, else it will be WAVE_MAPPER. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutWaveId(UINT* deviceOutId); + +/// Gets the ID of the preferred VR audio input device. +/// +/// \param[out] deviceInId The ID of the user's preferred VR audio device to use, +/// which will be valid upon a successful return value, else it will be WAVE_MAPPER. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInWaveId(UINT* deviceInId); + +/// Gets the GUID of the preferred VR audio device as a string. +/// +/// \param[out] deviceOutStrBuffer A buffer where the GUID string for the device will copied to. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetAudioDeviceOutGuidStr(WCHAR deviceOutStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE]); + +/// Gets the GUID of the preferred VR audio device. +/// +/// \param[out] deviceOutGuid The GUID of the user's preferred VR audio device to use, +/// which will be valid upon a successful return value, else it will be NULL. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuid(GUID* deviceOutGuid); + +/// Gets the GUID of the preferred VR microphone device as a string. +/// +/// \param[out] deviceInStrBuffer A buffer where the GUID string for the device will copied to. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetAudioDeviceInGuidStr(WCHAR deviceInStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE]); + +/// Gets the GUID of the preferred VR microphone device. +/// +/// \param[out] deviceInGuid The GUID of the user's preferred VR audio device to use, +/// which will be valid upon a successful return value, else it will be NULL. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuid(GUID* deviceInGuid); + +#endif // !defined(OVR_EXPORTING_CAPI) + +#endif // OVR_OS_MS + +#endif // OVR_CAPI_Audio_h diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_D3D.h b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_D3D.h new file mode 100644 index 0000000..c8bbc91 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_D3D.h @@ -0,0 +1,203 @@ +/********************************************************************************/ /** + \file OVR_CAPI_D3D.h + \brief D3D specific structures used by the CAPI interface. + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + ************************************************************************************/ + +#ifndef OVR_CAPI_D3D_h +#define OVR_CAPI_D3D_h + +#include "OVR_CAPI.h" +#include "OVR_Version.h" + +#if defined(_WIN32) +#include +#include + +#if !defined(OVR_EXPORTING_CAPI) + +//----------------------------------------------------------------------------------- +// ***** Direct3D Specific + +/// Create Texture Swap Chain suitable for use with Direct3D 11 and 12. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] d3dPtr Specifies the application's D3D11Device to create resources with +/// or the D3D12CommandQueue which must be the same one the application renders +/// to the eye textures with. +/// \param[in] desc Specifies requested texture properties. See notes for more info +/// about texture format. +/// \param[in] bindFlags Specifies what ovrTextureBindFlags the application requires +/// for this texture chain. +/// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, which will +/// be valid upon a successful return value, else it will be NULL. +/// This texture chain must be eventually destroyed via ovr_DestroyTextureSwapChain +/// before destroying the session with ovr_Destroy. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// \note The texture format provided in \a desc should be thought of as the format the +/// distortion-compositor will use for the ShaderResourceView when reading the contents of +/// the texture. To that end, it is highly recommended that the application requests texture +// swapchain formats that are in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) +/// as the compositor does sRGB-correct rendering. As such, the compositor relies on the +/// GPU's hardware sampler to do the sRGB-to-linear conversion. If the application still +/// prefers to render to a linear format (e.g. OVR_FORMAT_R8G8B8A8_UNORM) while handling the +/// linear-to-gamma conversion via HLSL code, then the application must still request the +/// corresponding sRGB format and also use the \a ovrTextureMisc_DX_Typeless flag in the +/// ovrTextureSwapChainDesc's Flag field. This will allow the application to create +/// a RenderTargetView that is the desired linear format while the compositor continues to +/// treat it as sRGB. Failure to do so will cause the compositor to apply unexpected gamma +/// conversions leading to gamma-curve artifacts. The \a ovrTextureMisc_DX_Typeless +/// flag for depth buffer formats (e.g. OVR_FORMAT_D32_FLOAT) is ignored as they are always +/// converted to be typeless. +/// +/// \see ovr_GetTextureSwapChainLength +/// \see ovr_GetTextureSwapChainCurrentIndex +/// \see ovr_GetTextureSwapChainDesc +/// \see ovr_GetTextureSwapChainBufferDX +/// \see ovr_DestroyTextureSwapChain +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateTextureSwapChainDX( + ovrSession session, + IUnknown* d3dPtr, + const ovrTextureSwapChainDesc* desc, + ovrTextureSwapChain* out_TextureSwapChain); + +/// Get a specific buffer within the chain as any compatible COM interface (similar to +/// QueryInterface) +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] chain Specifies an ovrTextureSwapChain previously returned +/// by ovr_CreateTextureSwapChainDX +/// \param[in] index Specifies the index within the chain to retrieve. +/// Must be between 0 and length (see ovr_GetTextureSwapChainLength), +/// or may pass -1 to get the buffer at the CurrentIndex location. (Saving a call to +/// GetTextureSwapChainCurrentIndex) +/// \param[in] iid Specifies the interface ID of the interface pointer to query the buffer for. +/// \param[out] out_Buffer Returns the COM interface pointer retrieved. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// Example code +/// \code{.cpp} +/// ovr_GetTextureSwapChainBufferDX(s, d3d11Chain, 0, IID_ID3D11Texture2D, &d3d11Texture); +/// ovr_GetTextureSwapChainBufferDX(s, d3d11Chain, 1, IID_PPV_ARGS(&dxgiResource)); +/// ovr_GetTextureSwapChainBufferDX(s, d3d12Chain, 0, IID_ID3D12Resource, &d3d12Texture); +/// \endcode +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainBufferDX( + ovrSession session, + ovrTextureSwapChain chain, + int index, + IID iid, + void** out_Buffer); + +/// Create Mirror Texture which is auto-refreshed to mirror Rift contents produced by this +/// application. +/// +/// A second call to ovr_CreateMirrorTextureWithOptionsDX for a given ovrSession before destroying +/// the first one is not supported and will result in an error return. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] d3dPtr Specifies the application's D3D11Device to create resources with +/// or the D3D12CommandQueue which must be the same one the application renders to +/// the textures with. +/// \param[in] desc Specifies requested texture properties. +/// See notes for more info about texture format. +/// \param[out] out_MirrorTexture Returns the created ovrMirrorTexture, which will be valid upon a +/// successful return value, else it will be NULL. +/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before +/// destroying the session with ovr_Destroy. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// \note The texture format provided in \a desc should be thought of as the format the compositor +/// will use for the RenderTargetView when writing into mirror texture. To that end, it is +/// highly recommended that the application requests a mirror texture format that is +/// in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the compositor does sRGB-correct +/// rendering. If however the application wants to still read the mirror texture as a linear +/// format (e.g. OVR_FORMAT_R8G8B8A8_UNORM) and handle the sRGB-to-linear conversion in +/// HLSL code, then it is recommended the application still requests an sRGB format and also +/// use the \a ovrTextureMisc_DX_Typeless flag in the ovrMirrorTextureDesc's Flags field. +/// This will allow the application to bind a ShaderResourceView that is a linear format +/// while the compositor continues to treat is as sRGB. Failure to do so will cause the +/// compositor to apply unexpected gamma conversions leading to gamma-curve artifacts. +/// +/// +/// Example code +/// \code{.cpp} +/// ovrMirrorTexture mirrorTexture = nullptr; +/// ovrMirrorTextureDesc mirrorDesc = {}; +/// mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; +/// mirrorDesc.Width = mirrorWindowWidth; +/// mirrorDesc.Height = mirrorWindowHeight; +/// ovrResult result = ovr_CreateMirrorTextureWithOptionsDX(session, d3d11Device, +/// &mirrorDesc, &mirrorTexture); +/// [...] +/// // Destroy the texture when done with it. +/// ovr_DestroyMirrorTexture(session, mirrorTexture); +/// mirrorTexture = nullptr; +/// \endcode +/// +/// \see ovr_GetMirrorTextureBufferDX +/// \see ovr_DestroyMirrorTexture +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateMirrorTextureWithOptionsDX( + ovrSession session, + IUnknown* d3dPtr, + const ovrMirrorTextureDesc* desc, + ovrMirrorTexture* out_MirrorTexture); + +/// Deprecated. Use ovr_CreateMirrorTextureWithOptionsDX instead +/// +/// Same as ovr_CreateMirrorTextureWithOptionsDX except doesn't use ovrMirrorOptions flags as part +/// of ovrMirrorTextureDesc's MirrorOptions field, and defaults to ovrMirrorOption_PostDistortion +/// +/// \see ovrMirrorOptions, ovr_CreateMirrorTextureWithOptionsDX +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateMirrorTextureDX( + ovrSession session, + IUnknown* d3dPtr, + const ovrMirrorTextureDesc* desc, + ovrMirrorTexture* out_MirrorTexture); + +/// Get a the underlying buffer as any compatible COM interface (similar to QueryInterface) +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] mirrorTexture Specifies an ovrMirrorTexture previously returned +/// by ovr_CreateMirrorTextureWithOptionsDX +/// \param[in] iid Specifies the interface ID of the interface pointer to query the buffer for. +/// \param[out] out_Buffer Returns the COM interface pointer retrieved. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// Example code +/// \code{.cpp} +/// ID3D11Texture2D* d3d11Texture = nullptr; +/// ovr_GetMirrorTextureBufferDX(session, mirrorTexture, IID_PPV_ARGS(&d3d11Texture)); +/// d3d11DeviceContext->CopyResource(d3d11TextureBackBuffer, d3d11Texture); +/// d3d11Texture->Release(); +/// dxgiSwapChain->Present(0, 0); +/// \endcode +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetMirrorTextureBufferDX( + ovrSession session, + ovrMirrorTexture mirrorTexture, + IID iid, + void** out_Buffer); + +#endif // !defined(OVR_EXPORTING_CAPI) + +#endif // _WIN32 + +#endif // OVR_CAPI_D3D_h diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_GL.h b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_GL.h new file mode 100644 index 0000000..6c1b9bf --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_GL.h @@ -0,0 +1,137 @@ +/********************************************************************************/ /** + \file OVR_CAPI_GL.h + \brief OpenGL-specific structures used by the CAPI interface. + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + ************************************************************************************/ + +#ifndef OVR_CAPI_GL_h +#define OVR_CAPI_GL_h + +#include "OVR_CAPI.h" + +#if !defined(OVR_EXPORTING_CAPI) + +/// Creates a TextureSwapChain suitable for use with OpenGL. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] desc Specifies the requested texture properties. +/// See notes for more info about texture format. +/// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, +/// which will be valid upon a successful return value, else it will be NULL. +/// This texture swap chain must be eventually destroyed via +// ovr_DestroyTextureSwapChain before destroying the session with ovr_Destroy. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// \note The \a format provided should be thought of as the format the distortion compositor will +/// use when reading the contents of the texture. To that end, it is highly recommended +/// that the application requests texture swap chain formats that are in sRGB-space +/// (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the distortion compositor does sRGB-correct +/// rendering. Furthermore, the app should then make sure "glEnable(GL_FRAMEBUFFER_SRGB);" +/// is called before rendering into these textures. Even though it is not recommended, +/// if the application would like to treat the texture as a linear format and do +/// linear-to-gamma conversion in GLSL, then the application can avoid +/// calling "glEnable(GL_FRAMEBUFFER_SRGB);", but should still pass in an sRGB variant for +/// the \a format. Failure to do so will cause the distortion compositor to apply incorrect +/// gamma conversions leading to gamma-curve artifacts. +/// +/// \see ovr_GetTextureSwapChainLength +/// \see ovr_GetTextureSwapChainCurrentIndex +/// \see ovr_GetTextureSwapChainDesc +/// \see ovr_GetTextureSwapChainBufferGL +/// \see ovr_DestroyTextureSwapChain +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateTextureSwapChainGL( + ovrSession session, + const ovrTextureSwapChainDesc* desc, + ovrTextureSwapChain* out_TextureSwapChain); + +/// Get a specific buffer within the chain as a GL texture name +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] chain Specifies an ovrTextureSwapChain previously returned +/// by ovr_CreateTextureSwapChainGL +/// \param[in] index Specifies the index within the chain to retrieve. +/// Must be between 0 and length (see ovr_GetTextureSwapChainLength) +/// or may pass -1 to get the buffer at the CurrentIndex location. +/// (Saving a call to GetTextureSwapChainCurrentIndex) +/// \param[out] out_TexId Returns the GL texture object name associated with +/// the specific index requested +/// +/// \return Returns an ovrResult indicating success or failure. +/// In the case of failure, use ovr_GetLastErrorInfo to get more information. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainBufferGL( + ovrSession session, + ovrTextureSwapChain chain, + int index, + unsigned int* out_TexId); + +/// Creates a Mirror Texture which is auto-refreshed to mirror Rift contents produced by this +/// application. +/// +/// A second call to ovr_CreateMirrorTextureWithOptionsGL for a given ovrSession before destroying +/// the first one is not supported and will result in an error return. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] desc Specifies the requested mirror texture description. +/// \param[out] out_MirrorTexture Specifies the created ovrMirrorTexture, which will be +/// valid upon a successful return value, else it will be NULL. +/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before +/// destroying the session with ovr_Destroy. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// \note The \a format provided should be thought of as the format the distortion compositor will +/// use when writing into the mirror texture. It is highly recommended that mirror textures +// are requested as sRGB formats because the distortion compositor does sRGB-correct +/// rendering. If the application requests a non-sRGB format (e.g. R8G8B8A8_UNORM) as the +/// mirror texture, then the application might have to apply a manual linear-to-gamma +/// conversion when reading from the mirror texture. Failure to do so can result in +// incorrect gamma conversions leading to gamma-curve artifacts and color banding. +/// +/// \see ovr_GetMirrorTextureBufferGL +/// \see ovr_DestroyMirrorTexture +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateMirrorTextureWithOptionsGL( + ovrSession session, + const ovrMirrorTextureDesc* desc, + ovrMirrorTexture* out_MirrorTexture); + +/// Deprecated. Use ovr_CreateMirrorTextureWithOptionsGL instead +/// +/// Same as ovr_CreateMirrorTextureWithOptionsGL except doesn't use ovrMirrorOptions flags as part +/// of ovrMirrorTextureDesc's MirrorOptions field, and defaults to ovrMirrorOption_PostDistortion +/// +/// \see ovrMirrorOptions, ovr_CreateMirrorTextureWithOptionsGL +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateMirrorTextureGL( + ovrSession session, + const ovrMirrorTextureDesc* desc, + ovrMirrorTexture* out_MirrorTexture); + +/// Get a the underlying buffer as a GL texture name +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] mirrorTexture Specifies an ovrMirrorTexture previously returned +// by ovr_CreateMirrorTextureWithOptionsGL +/// \param[out] out_TexId Specifies the GL texture object name associated with the mirror texture +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetMirrorTextureBufferGL( + ovrSession session, + ovrMirrorTexture mirrorTexture, + unsigned int* out_TexId); + +#endif // !defined(OVR_EXPORTING_CAPI) + +#endif // OVR_CAPI_GL_h diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Keys.h b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Keys.h new file mode 100644 index 0000000..7c37357 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Keys.h @@ -0,0 +1,49 @@ +/********************************************************************************/ /** + \file OVR_CAPI.h + \brief Keys for CAPI property function calls + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + ************************************************************************************/ + +#ifndef OVR_CAPI_Keys_h +#define OVR_CAPI_Keys_h + +#include "OVR_Version.h" + + + +#define OVR_KEY_USER "User" // string + +#define OVR_KEY_NAME "Name" // string + +#define OVR_KEY_GENDER "Gender" // string "Male", "Female", or "Unknown" +#define OVR_DEFAULT_GENDER "Unknown" + +#define OVR_KEY_PLAYER_HEIGHT "PlayerHeight" // float meters +#define OVR_DEFAULT_PLAYER_HEIGHT 1.778f + +#define OVR_KEY_EYE_HEIGHT "EyeHeight" // float meters +#define OVR_DEFAULT_EYE_HEIGHT 1.675f + +#define OVR_KEY_NECK_TO_EYE_DISTANCE "NeckEyeDistance" // float[2] meters +#define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.0805f +#define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.075f + +#define OVR_KEY_EYE_TO_NOSE_DISTANCE "EyeToNoseDist" // float[2] meters + + + +#define OVR_PERF_HUD_MODE "PerfHudMode" // int, allowed values are defined in enum ovrPerfHudMode + +#define OVR_LAYER_HUD_MODE "LayerHudMode" // int, allowed values are defined in enum ovrLayerHudMode +#define OVR_LAYER_HUD_CURRENT_LAYER "LayerHudCurrentLayer" // int, The layer to show +#define OVR_LAYER_HUD_SHOW_ALL_LAYERS "LayerHudShowAll" // bool, Hide other layers when hud enabled + +#define OVR_DEBUG_HUD_STEREO_MODE "DebugHudStereoMode" // int, see enum ovrDebugHudStereoMode +#define OVR_DEBUG_HUD_STEREO_GUIDE_INFO_ENABLE "DebugHudStereoGuideInfoEnable" // bool +#define OVR_DEBUG_HUD_STEREO_GUIDE_SIZE "DebugHudStereoGuideSize2f" // float[2] +#define OVR_DEBUG_HUD_STEREO_GUIDE_POSITION "DebugHudStereoGuidePosition3f" // float[3] +#define OVR_DEBUG_HUD_STEREO_GUIDE_YAWPITCHROLL "DebugHudStereoGuideYawPitchRoll3f" // float[3] +#define OVR_DEBUG_HUD_STEREO_GUIDE_COLOR "DebugHudStereoGuideColor4f" // float[4] + + +#endif // OVR_CAPI_Keys_h diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Vk.h b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Vk.h new file mode 100644 index 0000000..feae83f --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_CAPI_Vk.h @@ -0,0 +1,285 @@ +/********************************************************************************/ /** + \file OVR_CAPI_Vk.h + \brief Vulkan specific structures used by the CAPI interface. + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + ************************************************************************************/ + +#ifndef OVR_CAPI_Vk_h +#define OVR_CAPI_Vk_h + +#include "OVR_CAPI.h" +#include "OVR_Version.h" + +#if !defined(OVR_EXPORTING_CAPI) + +//----------------------------------------------------------------------------------- +// ***** Vulkan Specific + +/// Get a list of Vulkan vkInstance extensions required for VR. +/// +/// Returns a list of strings delimited by a single space identifying Vulkan extensions that must +/// be enabled in order for the VR runtime to support Vulkan-based applications. The returned +/// list reflects the current runtime version and the GPU the VR system is currently connected to. +/// +/// \param[in] luid Specifies the luid for the relevant GPU, which is returned from ovr_Create. +/// \param[in] extensionNames is a character buffer which will receive a list of extension name +/// strings, separated by a single space char between each extension. +/// \param[in] inoutExtensionNamesSize indicates on input the capacity of extensionNames in chars. +/// On output it returns the number of characters written to extensionNames, +/// including the terminating 0 char. In the case of this function returning +/// ovrError_InsufficientArraySize, the required inoutExtensionNamesSize is returned. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. Returns ovrError_InsufficientArraySize in +/// the case that inoutExtensionNameSize didn't have enough space, in which case +/// inoutExtensionNameSize will return the required inoutExtensionNamesSize. +/// +/// Example code +/// \code{.cpp} +/// char extensionNames[4096]; +/// uint32_t extensionNamesSize = sizeof(extensionNames); +/// ovr_GetInstanceExtensionsVk(luid, extensionsnames, &extensionNamesSize); +/// +/// uint32_t extensionCount = 0; +/// const char* extensionNamePtrs[256]; +/// for(const char* p = extensionNames; *p; ++p) { +/// if((p == extensionNames) || (p[-1] == ' ')) { +/// extensionNamePtrs[extensionCount++] = p; +/// if (p[-1] == ' ') +/// p[-1] = '\0'; +/// } +/// } +/// +/// VkInstanceCreateInfo info = { ... }; +/// info.enabledExtensionCount = extensionCount; +/// info.ppEnabledExtensionNames = extensionNamePtrs; +/// [...] +/// \endcode +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetInstanceExtensionsVk( + ovrGraphicsLuid luid, + char* extensionNames, + uint32_t* inoutExtensionNamesSize); + +/// Get a list of Vulkan vkDevice extensions required for VR. +/// +/// Returns a list of strings delimited by a single space identifying Vulkan extensions that must +/// be enabled in order for the VR runtime to support Vulkan-based applications. The returned +/// list reflects the current runtime version and the GPU the VR system is currently connected to. +/// +/// \param[in] luid Specifies the luid for the relevant GPU, which is returned from ovr_Create. +/// \param[in] extensionNames is a character buffer which will receive a list of extension name +/// strings, separated by a single space char between each extension. +/// \param[in] inoutExtensionNamesSize indicates on input the capacity of extensionNames in chars. +/// On output it returns the number of characters written to extensionNames, +/// including the terminating 0 char. In the case of this function returning +/// ovrError_InsufficientArraySize, the required inoutExtensionNamesSize is returned. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. Returns ovrError_InsufficientArraySize in +/// the case that inoutExtensionNameSize didn't have enough space, in which case +/// inoutExtensionNameSize will return the required inoutExtensionNamesSize. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetDeviceExtensionsVk( + ovrGraphicsLuid luid, + char* extensionNames, + uint32_t* inoutExtensionNamesSize); + +/// Find VkPhysicalDevice matching ovrGraphicsLuid +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] luid Specifies the luid returned from ovr_Create. +/// \param[in] instance Specifies a VkInstance to search for matching luids in. +/// \param[out] out_physicalDevice Returns the VkPhysicalDevice matching the instance and luid. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// \note This function enumerates the current physical devices and returns the one matching the +/// luid. It must be called at least once prior to any ovr_CreateTextureSwapChainVk or +/// ovr_CreateMirrorTextureWithOptionsVk calls, and the instance must remain valid for the lifetime +/// of the returned objects. It is assumed the VkDevice created by the application will be for the +/// returned physical device. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetSessionPhysicalDeviceVk( + ovrSession session, + ovrGraphicsLuid luid, + VkInstance instance, + VkPhysicalDevice* out_physicalDevice); + +/// Select VkQueue to block on till rendering is complete +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] queue Specifies a VkQueue to add a VkFence operation to and wait on. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// \note The queue may be changed at any time but only the value at the time ovr_SubmitFrame +/// is called will be used. ovr_SetSynchronizationQueueVk must be called with a valid VkQueue +/// created on the same VkDevice the texture sets were created on prior to the first call to +/// ovr_SubmitFrame. An internally created VkFence object will be signalled by the completion +/// of operations on queue and waited on to synchronize the VR compositor. +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetSynchronizationQueueVk(ovrSession session, VkQueue queue); +// Backwards compatibility for the original typoed version +#define ovr_SetSynchonizationQueueVk ovr_SetSynchronizationQueueVk +// Define OVR_PREVIEW_DEPRECATION to generate warnings for upcoming API deprecations +#if defined(OVR_PREVIEW_DEPRECATION) +#pragma deprecated("ovr_SetSynchonizationQueueVk") +#endif + +/// Create Texture Swap Chain suitable for use with Vulkan +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] device Specifies the application's VkDevice to create resources with. +/// \param[in] desc Specifies requested texture properties. See notes for more info +/// about texture format. +/// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, which will be valid +/// upon a successful return value, else it will be NULL. +/// This texture chain must be eventually destroyed via ovr_DestroyTextureSwapChain +/// before destroying the session with ovr_Destroy. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// \note The texture format provided in \a desc should be thought of as the format the +/// distortion-compositor will use for the ShaderResourceView when reading the contents +/// of the texture. To that end, it is highly recommended that the application +/// requests texture swapchain formats that are in sRGB-space +/// (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the compositor does sRGB-correct rendering. +/// As such, the compositor relies on the GPU's hardware sampler to do the sRGB-to-linear +/// conversion. If the application still prefers to render to a linear format (e.g. +/// OVR_FORMAT_R8G8B8A8_UNORM) while handling the linear-to-gamma conversion via +/// SPIRV code, then the application must still request the corresponding sRGB format and +/// also use the \a ovrTextureMisc_DX_Typeless flag in the ovrTextureSwapChainDesc's +/// Flag field. This will allow the application to create a RenderTargetView that is the +/// desired linear format while the compositor continues to treat it as sRGB. Failure to +/// do so will cause the compositor to apply unexpected gamma conversions leading to +/// gamma-curve artifacts. The \a ovrTextureMisc_DX_Typeless flag for depth buffer formats +/// (e.g. OVR_FORMAT_D32_FLOAT) is ignored as they are always +/// converted to be typeless. +/// +/// \see ovr_GetTextureSwapChainLength +/// \see ovr_GetTextureSwapChainCurrentIndex +/// \see ovr_GetTextureSwapChainDesc +/// \see ovr_GetTextureSwapChainBufferVk +/// \see ovr_DestroyTextureSwapChain +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateTextureSwapChainVk( + ovrSession session, + VkDevice device, + const ovrTextureSwapChainDesc* desc, + ovrTextureSwapChain* out_TextureSwapChain); + +/// Get a specific VkImage within the chain +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] chain Specifies an ovrTextureSwapChain previously returned by +/// ovr_CreateTextureSwapChainVk +/// \param[in] index Specifies the index within the chain to retrieve. +/// Must be between 0 and length (see ovr_GetTextureSwapChainLength), +/// or may pass -1 to get the buffer at the CurrentIndex location (saving a +/// call to GetTextureSwapChainCurrentIndex). +/// \param[out] out_Image Returns the VkImage retrieved. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainBufferVk( + ovrSession session, + ovrTextureSwapChain chain, + int index, + VkImage* out_Image); + +/// Create Mirror Texture which is auto-refreshed to mirror Rift contents produced by this +/// application. +/// +/// A second call to ovr_CreateMirrorTextureWithOptionsVk for a given ovrSession before destroying +/// the first one is not supported and will result in an error return. +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] device Specifies the VkDevice to create resources with. +/// \param[in] desc Specifies requested texture properties. See notes for more info +/// about texture format. +/// \param[out] out_MirrorTexture Returns the created ovrMirrorTexture, which will be +/// valid upon a successful return value, else it will be NULL. +/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before +/// destroying the session with ovr_Destroy. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// \note The texture format provided in \a desc should be thought of as the format the +/// compositor will use for the VkImageView when writing into mirror texture. To that end, +/// it is highly recommended that the application requests a mirror texture format that is +/// in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the compositor does sRGB-correct +/// rendering. If however the application wants to still read the mirror texture as a +/// linear format (e.g. OVR_FORMAT_R8G8B8A8_UNORM) and handle the sRGB-to-linear conversion +/// in SPIRV code, then it is recommended the application still requests an sRGB format and +/// also use the \a ovrTextureMisc_DX_Typeless flag in the ovrMirrorTextureDesc's +/// Flags field. This will allow the application to bind a ShaderResourceView that is a +/// linear format while the compositor continues to treat is as sRGB. Failure to do so will +/// cause the compositor to apply unexpected gamma conversions leading to +/// gamma-curve artifacts. +/// +/// Example code +/// \code{.cpp} +/// ovrMirrorTexture mirrorTexture = nullptr; +/// ovrMirrorTextureDesc mirrorDesc = {}; +/// mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; +/// mirrorDesc.Width = mirrorWindowWidth; +/// mirrorDesc.Height = mirrorWindowHeight; +/// ovrResult result = ovr_CreateMirrorTextureWithOptionsVk(session, vkDevice, &mirrorDesc, +/// &mirrorTexture); +/// [...] +/// // Destroy the texture when done with it. +/// ovr_DestroyMirrorTexture(session, mirrorTexture); +/// mirrorTexture = nullptr; +/// \endcode +/// +/// \see ovr_GetMirrorTextureBufferVk +/// \see ovr_DestroyMirrorTexture +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateMirrorTextureWithOptionsVk( + ovrSession session, + VkDevice device, + const ovrMirrorTextureDesc* desc, + ovrMirrorTexture* out_MirrorTexture); + +/// Get a the underlying mirror VkImage +/// +/// \param[in] session Specifies an ovrSession previously returned by ovr_Create. +/// \param[in] mirrorTexture Specifies an ovrMirrorTexture previously returned by +/// ovr_CreateMirrorTextureWithOptionsVk +/// \param[out] out_Image Returns the VkImage pointer retrieved. +/// +/// \return Returns an ovrResult indicating success or failure. In the case of failure, use +/// ovr_GetLastErrorInfo to get more information. +/// +/// Example code +/// \code{.cpp} +/// VkImage mirrorImage = VK_NULL_HANDLE; +/// ovr_GetMirrorTextureBufferVk(session, mirrorTexture, &mirrorImage); +/// ... +/// vkCmdBlitImage(commandBuffer, mirrorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, +/// presentImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion, VK_FILTER_LINEAR); +/// ... +/// vkQueuePresentKHR(queue, &presentInfo); +/// \endcode +/// +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetMirrorTextureBufferVk( + ovrSession session, + ovrMirrorTexture mirrorTexture, + VkImage* out_Image); + +#endif // !defined(OVR_EXPORTING_CAPI) + +#endif // OVR_CAPI_Vk_h diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_ErrorCode.h b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_ErrorCode.h new file mode 100644 index 0000000..80a67d0 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_ErrorCode.h @@ -0,0 +1,330 @@ +/********************************************************************************/ /** + \file OVR_ErrorCode.h + \brief This header provides LibOVR error code declarations. + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + *************************************************************************************/ + +#ifndef OVR_ErrorCode_h +#define OVR_ErrorCode_h + +#include +#include "OVR_Version.h" + + + +#ifndef OVR_RESULT_DEFINED +#define OVR_RESULT_DEFINED ///< Allows ovrResult to be independently defined. +/// API call results are represented at the highest level by a single ovrResult. +typedef int32_t ovrResult; +#endif + +/// \brief Indicates if an ovrResult indicates success. +/// +/// Some functions return additional successful values other than ovrSucces and +/// require usage of this macro to indicate successs. +/// +#if !defined(OVR_SUCCESS) +#define OVR_SUCCESS(result) (result >= 0) +#endif + +/// \brief Indicates if an ovrResult indicates an unqualified success. +/// +/// This is useful for indicating that the code intentionally wants to +/// check for result == ovrSuccess as opposed to OVR_SUCCESS(), which +/// checks for result >= ovrSuccess. +/// +#if !defined(OVR_UNQUALIFIED_SUCCESS) +#define OVR_UNQUALIFIED_SUCCESS(result) (result == ovrSuccess) +#endif + +/// \brief Indicates if an ovrResult indicates failure. +/// +#if !defined(OVR_FAILURE) +#define OVR_FAILURE(result) (!OVR_SUCCESS(result)) +#endif + +// Success is a value greater or equal to 0, while all error types are negative values. +#ifndef OVR_SUCCESS_DEFINED +#define OVR_SUCCESS_DEFINED ///< Allows ovrResult to be independently defined. +typedef enum ovrSuccessType_ { + /// This is a general success result. Use OVR_SUCCESS to test for success. + ovrSuccess = 0, +} ovrSuccessType; +#endif + +// Public success types +// Success is a value greater or equal to 0, while all error types are negative values. +typedef enum ovrSuccessTypes_ { + /// Returned from a call to SubmitFrame. The call succeeded, but what the app + /// rendered will not be visible on the HMD. Ideally the app should continue + /// calling SubmitFrame, but not do any rendering. When the result becomes + /// ovrSuccess, rendering should continue as usual. + ovrSuccess_NotVisible = 1000, + + /// Boundary is invalid due to sensor change or was not setup. + ovrSuccess_BoundaryInvalid = 1001, + + /// Device is not available for the requested operation. + ovrSuccess_DeviceUnavailable = 1002, +} ovrSuccessTypes; + +// Public error types +typedef enum ovrErrorType_ { + /******************/ + /* General errors */ + /******************/ + + /// Failure to allocate memory. + ovrError_MemoryAllocationFailure = -1000, + + /// Invalid ovrSession parameter provided. + ovrError_InvalidSession = -1002, + + /// The operation timed out. + ovrError_Timeout = -1003, + + /// The system or component has not been initialized. + ovrError_NotInitialized = -1004, + + /// Invalid parameter provided. See error info or log for details. + ovrError_InvalidParameter = -1005, + + /// Generic service error. See error info or log for details. + ovrError_ServiceError = -1006, + + /// The given HMD doesn't exist. + ovrError_NoHmd = -1007, + + /// Function call is not supported on this hardware/software + ovrError_Unsupported = -1009, + + /// Specified device type isn't available. + ovrError_DeviceUnavailable = -1010, + + /// The headset was in an invalid orientation for the requested + /// operation (e.g. vertically oriented during ovr_RecenterPose). + ovrError_InvalidHeadsetOrientation = -1011, + + /// The client failed to call ovr_Destroy on an active session before calling ovr_Shutdown. + /// Or the client crashed. + ovrError_ClientSkippedDestroy = -1012, + + /// The client failed to call ovr_Shutdown or the client crashed. + ovrError_ClientSkippedShutdown = -1013, + + ///< The service watchdog discovered a deadlock. + ovrError_ServiceDeadlockDetected = -1014, + + ///< Function call is invalid for object's current state + ovrError_InvalidOperation = -1015, + + ///< Increase size of output array + ovrError_InsufficientArraySize = -1016, + + /// There is not any external camera information stored by ovrServer. + ovrError_NoExternalCameraInfo = -1017, + + /// Tracking is lost when ovr_GetDevicePoses() is called. + ovrError_LostTracking = -1018, + + /// There was a problem initializing the external camera for capture + ovrError_ExternalCameraInitializedFailed = -1019, + + /// There was a problem capturing external camera frames + ovrError_ExternalCameraCaptureFailed = -1020, + + /// The external camera friendly name list and the external camera name list + /// are not the fixed size(OVR_MAX_EXTERNAL_CAMERA_NAME_BUFFER_SIZE). + ovrError_ExternalCameraNameListsBufferSize = -1021, + + /// The external camera friendly name list is not the same size as + /// the external camera name list. + ovrError_ExternalCameraNameListsMistmatch = -1022, + + /// The external camera property has not been sent to OVRServer + /// when the user tries to open the camera. + ovrError_ExternalCameraNotCalibrated = -1023, + + /// The external camera name is larger than OVR_EXTERNAL_CAMERA_NAME_SIZE-1 + ovrError_ExternalCameraNameWrongSize = -1024, + + /// The caller doesn't have permissions for the requested action. + ovrError_AccessDenied = -1025, + + /*************************************************/ + /* Audio error range, reserved for Audio errors. */ + /*************************************************/ + + /// Failure to find neither audio input or output device. + ovrError_AudioDeviceNotFound = -2001, + + /// Generic COM error. + ovrError_AudioComError = -2002, + + /// Failure to find the specified audio input device. + ovrError_AudioInputDeviceNotFound = -2003, + + /// Failure to find the specified audio output device. + ovrError_AudioOutputDeviceNotFound = -2004, + + /**************************/ + /* Initialization errors. */ + /**************************/ + + /// Generic initialization error. + ovrError_Initialize = -3000, + + /// Couldn't load LibOVRRT. + ovrError_LibLoad = -3001, + + /// LibOVRRT version incompatibility. + ovrError_LibVersion = -3002, + + /// Couldn't connect to the OVR Service. + ovrError_ServiceConnection = -3003, + + /// OVR Service version incompatibility. + ovrError_ServiceVersion = -3004, + + /// The operating system version is incompatible. + ovrError_IncompatibleOS = -3005, + + /// Unable to initialize the HMD display. + ovrError_DisplayInit = -3006, + + /// Unable to start the server. Is it already running? + ovrError_ServerStart = -3007, + + /// Attempting to re-initialize with a different version. + ovrError_Reinitialization = -3008, + + /// Chosen rendering adapters between client and service do not match + ovrError_MismatchedAdapters = -3009, + + /// Calling application has leaked resources + ovrError_LeakingResources = -3010, + + /// Client version too old to connect to service + ovrError_ClientVersion = -3011, + + /// The operating system is out of date. + ovrError_OutOfDateOS = -3012, + + /// The graphics driver is out of date. + ovrError_OutOfDateGfxDriver = -3013, + + /// The graphics hardware is not supported + ovrError_IncompatibleGPU = -3014, + + /// No valid VR display system found. + ovrError_NoValidVRDisplaySystem = -3015, + + /// Feature or API is obsolete and no longer supported. + ovrError_Obsolete = -3016, + + /// No supported VR display system found, but disabled or driverless adapter found. + ovrError_DisabledOrDefaultAdapter = -3017, + + /// The system is using hybrid graphics (Optimus, etc...), which is not support. + ovrError_HybridGraphicsNotSupported = -3018, + + /// Initialization of the DisplayManager failed. + ovrError_DisplayManagerInit = -3019, + + /// Failed to get the interface for an attached tracker + ovrError_TrackerDriverInit = -3020, + + /// LibOVRRT signature check failure. + ovrError_LibSignCheck = -3021, + + /// LibOVRRT path failure. + ovrError_LibPath = -3022, + + /// LibOVRRT symbol resolution failure. + ovrError_LibSymbols = -3023, + + /// Failed to connect to the service because remote connections to the service are not allowed. + ovrError_RemoteSession = -3024, + + /// Vulkan initialization error. + ovrError_InitializeVulkan = -3025, + + /// The graphics driver is black-listed. + ovrError_BlacklistedGfxDriver = -3026, + + /********************/ + /* Rendering errors */ + /********************/ + + /// In the event of a system-wide graphics reset or cable unplug this is returned to the app. + ovrError_DisplayLost = -6000, + + /// ovr_CommitTextureSwapChain was called too many times on a texture swapchain without + /// calling submit to use the chain. + ovrError_TextureSwapChainFull = -6001, + + /// The ovrTextureSwapChain is in an incomplete or inconsistent state. + /// Ensure ovr_CommitTextureSwapChain was called at least once first. + ovrError_TextureSwapChainInvalid = -6002, + + /// Graphics device has been reset (TDR, etc...) + ovrError_GraphicsDeviceReset = -6003, + + /// HMD removed from the display adapter + ovrError_DisplayRemoved = -6004, + + /// Content protection is not available for the display. + ovrError_ContentProtectionNotAvailable = -6005, + + /// Application declared itself as an invisible type and is not allowed to submit frames. + ovrError_ApplicationInvisible = -6006, + + /// The given request is disallowed under the current conditions. + ovrError_Disallowed = -6007, + + /// Display portion of HMD is plugged into an incompatible port (ex: IGP) + ovrError_DisplayPluggedIncorrectly = -6008, + + /// Returned in the event a virtual display system reaches a display limit + ovrError_DisplayLimitReached = -6009, + + /****************/ + /* Fatal errors */ + /****************/ + + ///< A runtime exception occurred. The application is required to shutdown LibOVR and + /// re-initialize it before this error state will be cleared. + ovrError_RuntimeException = -7000, + + /**********************/ + /* Calibration errors */ + /**********************/ + + /// Result of a missing calibration block + ovrError_NoCalibration = -9000, + + /// Result of an old calibration block + ovrError_OldVersion = -9001, + + /// Result of a bad calibration block due to lengths + ovrError_MisformattedBlock = -9002, + +/****************/ +/* Other errors */ +/****************/ + + +} ovrErrorType; + +/// Provides information about the last error. +/// \see ovr_GetLastErrorInfo +typedef struct ovrErrorInfo_ { + /// The result from the last API call that generated an error ovrResult. + ovrResult Result; + + /// A UTF8-encoded null-terminated English string describing the problem. + /// The format of this string is subject to change in future versions. + char ErrorString[512]; +} ovrErrorInfo; + +#endif /* OVR_ErrorCode_h */ diff --git a/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_Version.h b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_Version.h new file mode 100644 index 0000000..7955554 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Include/OVR_Version.h @@ -0,0 +1,42 @@ +/************************************************************************************* + \file OVR_Version.h + \brief This header provides LibOVR version identification. + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + *************************************************************************************/ + +#ifndef OVR_Version_h +#define OVR_Version_h + + +/// Conventional string-ification macro. +#if !defined(OVR_STRINGIZE) +#define OVR_STRINGIZEIMPL(x) #x +#define OVR_STRINGIZE(x) OVR_STRINGIZEIMPL(x) +#endif + +// Master version numbers +#define OVR_PRODUCT_VERSION 1 // Product version doesn't participate in semantic versioning. +#define OVR_MAJOR_VERSION 1 // If you change these values then you need to also make sure to change +// LibOVR/Projects/Windows/LibOVR.props in parallel. +#define OVR_MINOR_VERSION 55 // +#define OVR_PATCH_VERSION 0 + +// This is the ((product * 100) + major) version of the service that the DLL is compatible with. +// When we backport changes to old versions of the DLL we update the old DLLs +// to move this version number up to the latest version. +// The DLL is responsible for checking that the service is the version it supports +// and returning an appropriate error message if it has not been made compatible. +#define OVR_DLL_COMPATIBLE_VERSION 101 + +// This is the minor version representing the minimum version an application can query with this +// SDK. Calls ovr_Initialize will fail if the application requests a version that is less than this. +#define OVR_MIN_REQUESTABLE_MINOR_VERSION 17 + +#define OVR_FEATURE_VERSION 0 + +/// "Major.Minor.Patch" +#if !defined(OVR_VERSION_STRING) +#define OVR_VERSION_STRING OVR_STRINGIZE(OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION) +#endif + +#endif // OVR_Version_h diff --git a/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/Win32/Release/VS2015/LibOVR.lib b/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/Win32/Release/VS2015/LibOVR.lib new file mode 100644 index 0000000..bed059b Binary files /dev/null and b/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/Win32/Release/VS2015/LibOVR.lib differ diff --git a/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/Win32/Release/VS2017/LibOVR.lib b/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/Win32/Release/VS2017/LibOVR.lib new file mode 100644 index 0000000..b08a68a Binary files /dev/null and b/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/Win32/Release/VS2017/LibOVR.lib differ diff --git a/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/x64/Release/VS2015/LibOVR.lib b/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/x64/Release/VS2015/LibOVR.lib new file mode 100644 index 0000000..594a337 Binary files /dev/null and b/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/x64/Release/VS2015/LibOVR.lib differ diff --git a/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/x64/Release/VS2017/LibOVR.lib b/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/x64/Release/VS2017/LibOVR.lib new file mode 100644 index 0000000..c0328da Binary files /dev/null and b/ovr_sdk_win_23.0.0/LibOVR/Lib/Windows/x64/Release/VS2017/LibOVR.lib differ diff --git a/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/LibOVR.props b/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/LibOVR.props new file mode 100644 index 0000000..324a7c6 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/LibOVR.props @@ -0,0 +1,30 @@ + + + + + 1 + 1 + 55 + 0 + 0 + + + + + + $(OVR_PRODUCT_VERSION) + + + $(OVR_MAJOR_VERSION) + + + $(OVR_MINOR_VERSION) + + + $(OVR_PATCH_VERSION) + + + $(OVR_BUILD_VERSION) + + + diff --git a/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2015/LibOVR.vcxproj b/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2015/LibOVR.vcxproj new file mode 100644 index 0000000..fc9a8fc --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2015/LibOVR.vcxproj @@ -0,0 +1,456 @@ + + + + + DebugSingleProcess + Win32 + + + DebugSingleProcess + x64 + + + Debug + Win32 + + + Debug + x64 + + + ReleaseSingleProcess + Win32 + + + ReleaseSingleProcess + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + {EA50E705-5113-49E5-B105-2512EDC8DDC6} + Win32Proj + LibOVR + LibOVR + 8.1 + + + + StaticLibrary + true + Unicode + v140 + + + StaticLibrary + true + Unicode + v140 + + + StaticLibrary + true + Unicode + v140 + + + StaticLibrary + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + LibOVR + + + LibOVR + + + LibOVR + + + LibOVR + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + LibOVR + + + LibOVR + + + LibOVR + + + LibOVR + + + + + + Level4 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + OldStyle + true + false + true + MultiThreadedDebug + %(AdditionalIncludeDirectories);../../../Include + false + /FC %(AdditionalOptions) + false + false + + + + Windows + true + + + + + + + + + + + Level4 + Disabled + OVR_SINGLE_PROCESS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + OldStyle + true + false + true + MultiThreadedDebug + %(AdditionalIncludeDirectories);../../../Include + false + /FC %(AdditionalOptions) + false + false + + + Windows + true + + + + + + + + + + + Level4 + Disabled + _WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + OldStyle + true + false + true + MultiThreadedDebug + %(AdditionalIncludeDirectories);../../../Include + false + false + /FC %(AdditionalOptions) + false + false + + + Windows + true + + + + + + + + + + + Level4 + Disabled + OVR_SINGLE_PROCESS;_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + OldStyle + true + false + true + MultiThreadedDebug + %(AdditionalIncludeDirectories);../../../Include + false + false + /FC %(AdditionalOptions) + false + false + + + Windows + true + + + + + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + true + true + OldStyle + %(AdditionalIncludeDirectories);../../../Include + false + /FC /d2Zi+ %(AdditionalOptions) + false + false + + + Windows + true + true + true + + + + + + + + + Level4 + + + MaxSpeed + true + true + OVR_SINGLE_PROCESS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + true + true + OldStyle + %(AdditionalIncludeDirectories);../../../Include + false + /FC /d2Zi+ %(AdditionalOptions) + false + false + + + Windows + true + true + true + + + + + + + + + Level4 + + + MaxSpeed + true + true + _WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + true + true + OldStyle + %(AdditionalIncludeDirectories);../../../Include + false + /FC /d2Zi+ %(AdditionalOptions) + false + false + + + Windows + true + true + true + + + + + + + + + Level4 + + + MaxSpeed + true + true + OVR_SINGLE_PROCESS;_WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + true + true + OldStyle + %(AdditionalIncludeDirectories);../../../Include + false + /FC /d2Zi+ %(AdditionalOptions) + false + false + + + Windows + true + true + true + + + + + + + + + + diff --git a/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2015/LibOVR.vcxproj.filters b/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2015/LibOVR.vcxproj.filters new file mode 100644 index 0000000..6c51d6c --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2015/LibOVR.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {19aff241-4a7e-4895-92de-c834a9ebc8f1} + + + {77dd6d03-7839-4fcb-a38a-c0535d6f0ff8} + + + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Shim + + + + + Shim + + + Shim + + + Shim + + + diff --git a/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2017/LibOVR.vcxproj b/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2017/LibOVR.vcxproj new file mode 100644 index 0000000..a882a92 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2017/LibOVR.vcxproj @@ -0,0 +1,463 @@ + + + + + DebugSingleProcess + Win32 + + + DebugSingleProcess + x64 + + + Debug + Win32 + + + Debug + x64 + + + ReleaseSingleProcess + Win32 + + + ReleaseSingleProcess + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + {EA50E705-5113-49E5-B105-2512EDC8DDC6} + Win32Proj + LibOVR + LibOVR + + + + StaticLibrary + true + Unicode + v141 + + + StaticLibrary + true + Unicode + v141 + + + StaticLibrary + true + Unicode + v141 + + + StaticLibrary + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + LibOVR + + + LibOVR + + + LibOVR + + + LibOVR + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/$(VSDIR)/ + + + LibOVR + + + LibOVR + + + LibOVR + $(OVRSDKROOT)3rdParty\DirectXTex\lib\BuildRelease;$(LibraryPath) + + + LibOVR + + + + + + Level4 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + OldStyle + true + false + true + MultiThreadedDebug + %(AdditionalIncludeDirectories);../../../Include + false + /FC %(AdditionalOptions) + false + false + + + + Windows + true + + + + + + + + + + + Level4 + Disabled + OVR_SINGLE_PROCESS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + OldStyle + true + false + true + MultiThreadedDebug + %(AdditionalIncludeDirectories);../../../Include + false + /FC %(AdditionalOptions) + false + false + + + Windows + true + + + + + + + + + + + Level4 + Disabled + _WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + OldStyle + true + false + true + MultiThreadedDebug + %(AdditionalIncludeDirectories);../../../Include + false + false + /FC %(AdditionalOptions) + false + false + + + Windows + true + + + + + + + + + + + Level4 + Disabled + OVR_SINGLE_PROCESS;_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + OldStyle + true + false + true + MultiThreadedDebug + %(AdditionalIncludeDirectories);../../../Include + false + false + /FC %(AdditionalOptions) + false + false + + + Windows + true + + + + + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + true + true + OldStyle + %(AdditionalIncludeDirectories);../../../Include + false + /FC /d2Zi+ %(AdditionalOptions) + false + false + + + Windows + true + true + true + + + + + + + + + Level4 + + + MaxSpeed + true + true + OVR_SINGLE_PROCESS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + true + true + OldStyle + %(AdditionalIncludeDirectories);../../../Include + false + /FC /d2Zi+ %(AdditionalOptions) + false + false + + + Windows + true + true + true + + + + + + + + + Level4 + + + MaxSpeed + true + true + _WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + true + true + OldStyle + %(AdditionalIncludeDirectories);../../../Include + false + /FC /d2Zi+ %(AdditionalOptions) + false + false + + + Windows + true + true + true + + + + + + + + + + + + + + + Level4 + + + MaxSpeed + true + true + OVR_SINGLE_PROCESS;_WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + true + true + OldStyle + %(AdditionalIncludeDirectories);../../../Include + false + /FC /d2Zi+ %(AdditionalOptions) + false + false + + + Windows + true + true + true + + + + + + + + + + diff --git a/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2017/LibOVR.vcxproj.filters b/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2017/LibOVR.vcxproj.filters new file mode 100644 index 0000000..07a6852 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Projects/Windows/VS2017/LibOVR.vcxproj.filters @@ -0,0 +1,57 @@ + + + + + {19aff241-4a7e-4895-92de-c834a9ebc8f1} + + + {77dd6d03-7839-4fcb-a38a-c0535d6f0ff8} + + + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Shim + + + Include + + + + + Shim + + + Shim + + + Shim + + + diff --git a/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c b/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c new file mode 100644 index 0000000..014af83 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c @@ -0,0 +1,1961 @@ +/************************************************************************************ + +Filename : OVR_CAPIShim.c +Content : CAPI DLL user library +Created : November 20, 2014 +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include "OVR_CAPI.h" +#include "OVR_CAPI_Prototypes.h" +#include "OVR_ErrorCode.h" +#include "OVR_Version.h" + +#if defined(_WIN32) +#if defined(_MSC_VER) +#pragma warning(push, 0) +#endif +#include +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#include "OVR_CAPI_D3D.h" +#else +#if defined(__APPLE__) +#include +#include +#include +#include +#include +#endif +#include +#include +#include +#endif +#include "OVR_CAPI_GL.h" +#include "OVR_CAPI_Vk.h" + + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4996) // 'getenv': This function or variable may be unsafe. +#endif + +// clang-format off +static const uint8_t OculusSDKUniqueIdentifier[] = { + 0x9E, 0xB2, 0x0B, 0x1A, 0xB7, 0x97, 0x09, 0x20, 0xE0, 0xFB, 0x83, 0xED, 0xF8, 0x33, 0x5A, 0xEB, + 0x80, 0x4D, 0x8E, 0x92, 0x20, 0x69, 0x13, 0x56, 0xB4, 0xBB, 0xC4, 0x85, 0xA7, 0x9E, 0xA4, 0xFE, + OVR_MAJOR_VERSION, OVR_MINOR_VERSION, OVR_PATCH_VERSION +}; + +// clang-format on + +static const uint8_t OculusSDKUniqueIdentifierXORResult = 0xcb; + +// ----------------------------------------------------------------------------------- +// ***** OVR_BUILD_DEBUG +// +// Defines OVR_BUILD_DEBUG when the compiler default debug preprocessor is set. +// +// If you want to control the behavior of these flags, then explicitly define +// either -DOVR_BUILD_RELEASE or -DOVR_BUILD_DEBUG in the compiler arguments. + +#if !defined(OVR_BUILD_DEBUG) && !defined(OVR_BUILD_RELEASE) +#if defined(_MSC_VER) +#if defined(_DEBUG) +#define OVR_BUILD_DEBUG +#endif +#else +#if defined(DEBUG) +#define OVR_BUILD_DEBUG +#endif +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** FilePathCharType, ModuleHandleType, ModuleFunctionType +// +#if defined(_WIN32) // We need to use wchar_t on Microsoft platforms, as that's the native file +// system character type. +#define FilePathCharType \ + wchar_t // #define instead of typedef because debuggers (VC++, XCode) don't recognize typedef'd +// types as a string type. +typedef HMODULE ModuleHandleType; +typedef FARPROC ModuleFunctionType; +#else +#define FilePathCharType char +typedef void* ModuleHandleType; +typedef void* ModuleFunctionType; +#endif + +#define ModuleHandleTypeNull ((ModuleHandleType)NULL) +#define ModuleFunctionTypeNull ((ModuleFunctionType)NULL) + +//----------------------------------------------------------------------------------- +// ***** OVR_MAX_PATH +// +#if !defined(OVR_MAX_PATH) +#if defined(_WIN32) +#define OVR_MAX_PATH _MAX_PATH +#elif defined(__APPLE__) +#define OVR_MAX_PATH PATH_MAX +#else +#define OVR_MAX_PATH 1024 +#endif +#endif + +#if !defined(OVR_DLSYM) +#if defined(_WIN32) +#define OVR_DLSYM(dlImage, name) GetProcAddress(dlImage, name) +#else +#define OVR_DLSYM(dlImage, name) dlsym(dlImage, name) +#endif +#endif + +static size_t OVR_strlcpy(char* dest, const char* src, size_t destsize) { + const char* s = src; + size_t n = destsize; + + if (n && --n) { + do { + if ((*dest++ = *s++) == 0) + break; + } while (--n); + } + + if (!n) { + if (destsize) + *dest = 0; + while (*s++) { + } + } + + return (size_t)((s - src) - 1); +} + +static size_t OVR_strlcat(char* dest, const char* src, size_t destsize) { + const size_t d = destsize ? strlen(dest) : 0; + const size_t s = strlen(src); + const size_t t = s + d; + + if (t < destsize) + memcpy(dest + d, src, (s + 1) * sizeof(*src)); + else { + if (destsize) { + memcpy(dest + d, src, ((destsize - d) - 1) * sizeof(*src)); + dest[destsize - 1] = 0; + } + } + + return t; +} + +#if defined(__APPLE__) +static ovrBool +OVR_strend(const char* pStr, const char* pFind, size_t strLength, size_t findLength) { + if (strLength == (size_t)-1) + strLength = strlen(pStr); + if (findLength == (size_t)-1) + findLength = strlen(pFind); + if (strLength >= findLength) + return (strcmp(pStr + strLength - findLength, pFind) == 0); + return ovrFalse; +} + +static ovrBool OVR_isBundleFolder(const char* filePath) { + static const char* extensionArray[] = {".app", ".bundle", ".framework", ".plugin", ".kext"}; + size_t i; + + for (i = 0; i < sizeof(extensionArray) / sizeof(extensionArray[0]); i++) { + if (OVR_strend(filePath, extensionArray[i], (size_t)-1, (size_t)-1)) + return ovrTrue; + } + + return ovrFalse; +} +#endif + +#if !defined(_WIN32) +static ovrBool OVR_GetCurrentWorkingDirectory( + FilePathCharType* directoryPath, + size_t directoryPathCapacity) { +#if defined(_WIN32) + DWORD dwSize = GetCurrentDirectoryW((DWORD)directoryPathCapacity, directoryPath); + + if ((dwSize > 0) && + (directoryPathCapacity > 1)) // Test > 1 so we have room to possibly append a \ char. + { + size_t length = wcslen(directoryPath); + + if ((length == 0) || + ((directoryPath[length - 1] != L'\\') && (directoryPath[length - 1] != L'/'))) { + directoryPath[length++] = L'\\'; + directoryPath[length] = L'\0'; + } + + return ovrTrue; + } + +#else + char* cwd = getcwd(directoryPath, directoryPathCapacity); + + if (cwd && directoryPath[0] && + (directoryPathCapacity > 1)) // Test > 1 so we have room to possibly append a / char. + { + size_t length = strlen(directoryPath); + + if ((length == 0) || (directoryPath[length - 1] != '/')) { + directoryPath[length++] = '/'; + directoryPath[length] = '\0'; + } + + return ovrTrue; + } +#endif + + if (directoryPathCapacity > 0) + directoryPath[0] = '\0'; + + return ovrFalse; +} + +// The appContainer argument is specific currently to only Macintosh. If true and the application is +// a .app bundle then it returns the +// location of the bundle and not the path to the executable within the bundle. Else return the path +// to the executable binary itself. +// The moduleHandle refers to the relevant dynamic (a.k.a. shared) library. The main executable is +// the main module, and each of the shared +// libraries is a module. This way you can specify that you want to know the directory of the given +// shared library, which may be different +// from the main executable. If the moduleHandle is NULL then the current application module is +// used. +static ovrBool OVR_GetCurrentApplicationDirectory( + FilePathCharType* directoryPath, + size_t directoryPathCapacity, + ovrBool appContainer, + ModuleHandleType moduleHandle) { +#if defined(_WIN32) + DWORD length = GetModuleFileNameW(moduleHandle, directoryPath, (DWORD)directoryPathCapacity); + DWORD pos; + + if ((length != 0) && + (length < + (DWORD)directoryPathCapacity)) // If there wasn't an error and there was enough capacity... + { + for (pos = length; (pos > 0) && (directoryPath[pos] != '\\') && (directoryPath[pos] != '/'); + --pos) { + if ((directoryPath[pos - 1] != '\\') && (directoryPath[pos - 1] != '/')) + directoryPath[pos - 1] = 0; + } + + return ovrTrue; + } + + (void)appContainer; // Not used on this platform. + +#elif defined(__APPLE__) + uint32_t directoryPathCapacity32 = (uint32_t)directoryPathCapacity; + int result = _NSGetExecutablePath(directoryPath, &directoryPathCapacity32); + + if (result == 0) // If success... + { + char realPath[OVR_MAX_PATH]; + + if (realpath(directoryPath, realPath)) // realpath returns the canonicalized absolute file path. + { + size_t length = 0; + + if (appContainer) // If the caller wants the path to the containing bundle... + { + char containerPath[OVR_MAX_PATH]; + ovrBool pathIsContainer; + + OVR_strlcpy(containerPath, realPath, sizeof(containerPath)); + pathIsContainer = OVR_isBundleFolder(containerPath); + + while (!pathIsContainer && strncmp(containerPath, ".", OVR_MAX_PATH) && + strncmp(containerPath, "/", OVR_MAX_PATH)) // While the container we're looking for + // is not found and while the path doesn't + // start with a . or / + { + OVR_strlcpy(containerPath, dirname(containerPath), sizeof(containerPath)); + pathIsContainer = OVR_isBundleFolder(containerPath); + } + + if (pathIsContainer) + length = OVR_strlcpy(directoryPath, containerPath, directoryPathCapacity); + } + + if (length == 0) // If not set above in the appContainer block... + length = OVR_strlcpy(directoryPath, realPath, directoryPathCapacity); + + while (length-- && (directoryPath[length] != '/')) + directoryPath[length] = + '\0'; // Strip the file name from the file path, leaving a trailing / char. + + return ovrTrue; + } + } + + (void)moduleHandle; // Not used on this platform. + +#else + ssize_t length = readlink("/proc/self/exe", directoryPath, directoryPathCapacity); + ssize_t pos; + + if (length > 0) { + for (pos = length; (pos > 0) && (directoryPath[pos] != '/'); --pos) { + if (directoryPath[pos - 1] != '/') + directoryPath[pos - 1] = '\0'; + } + + return ovrTrue; + } + + (void)appContainer; // Not used on this platform. + (void)moduleHandle; +#endif + + if (directoryPathCapacity > 0) + directoryPath[0] = '\0'; + + return ovrFalse; +} +#endif // !defined(_WIN32) + +#if defined(_WIN32) + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4201) +#endif + +#include +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// Expected certificates: +#define ExpectedNumCertificates 3 +typedef struct CertificateEntry_t { + const wchar_t* Issuer; + const wchar_t* Subject; +} CertificateEntry; + +CertificateEntry NewCertificateChain[ExpectedNumCertificates] = { + {L"DigiCert SHA2 Assured ID Code Signing CA", L"Oculus VR, LLC"}, + {L"DigiCert Assured ID Root CA", L"DigiCert SHA2 Assured ID Code Signing CA"}, + {L"DigiCert Assured ID Root CA", L"DigiCert Assured ID Root CA"}, +}; + +#define CertificateChainCount 1 +CertificateEntry* AllowedCertificateChains[CertificateChainCount] = {NewCertificateChain}; + +typedef DWORD(WINAPI* PtrCertGetNameStringW)( + PCCERT_CONTEXT pCertContext, + DWORD dwType, + DWORD dwFlags, + void* pvTypePara, + LPWSTR pszNameString, + DWORD cchNameString); +typedef LONG(WINAPI* PtrWinVerifyTrust)(HWND hwnd, GUID* pgActionID, LPVOID pWVTData); +typedef CRYPT_PROVIDER_DATA*(WINAPI* PtrWTHelperProvDataFromStateData)(HANDLE hStateData); +typedef CRYPT_PROVIDER_SGNR*(WINAPI* PtrWTHelperGetProvSignerFromChain)( + CRYPT_PROVIDER_DATA* pProvData, + DWORD idxSigner, + BOOL fCounterSigner, + DWORD idxCounterSigner); + +PtrCertGetNameStringW m_PtrCertGetNameStringW = 0; +PtrWinVerifyTrust m_PtrWinVerifyTrust = 0; +PtrWTHelperProvDataFromStateData m_PtrWTHelperProvDataFromStateData = 0; +PtrWTHelperGetProvSignerFromChain m_PtrWTHelperGetProvSignerFromChain = 0; + +typedef enum ValidateCertificateContentsResult_ { + VCCRSuccess = 0, + VCCRErrorCertCount = -1, + VCCRErrorTrust = -2, + VCCRErrorValidation = -3 +} ValidateCertificateContentsResult; + +static ValidateCertificateContentsResult ValidateCertificateContents( + CertificateEntry* chain, + CRYPT_PROVIDER_SGNR* cps) { + int certIndex; + + if (!cps || !cps->pasCertChain || cps->csCertChain != ExpectedNumCertificates) { + return VCCRErrorCertCount; + } + + for (certIndex = 0; certIndex < ExpectedNumCertificates; ++certIndex) { + CRYPT_PROVIDER_CERT* pCertData = &cps->pasCertChain[certIndex]; + wchar_t subjectStr[400] = {0}; + wchar_t issuerStr[400] = {0}; + + if ((pCertData->fSelfSigned && !pCertData->fTrustedRoot) || pCertData->fTestCert) { + return VCCRErrorTrust; + } + + m_PtrCertGetNameStringW( + pCertData->pCert, + CERT_NAME_ATTR_TYPE, + 0, + szOID_COMMON_NAME, + subjectStr, + ARRAYSIZE(subjectStr)); + + m_PtrCertGetNameStringW( + pCertData->pCert, + CERT_NAME_ATTR_TYPE, + CERT_NAME_ISSUER_FLAG, + 0, + issuerStr, + ARRAYSIZE(issuerStr)); + + if (wcscmp(subjectStr, chain[certIndex].Subject) != 0 || + wcscmp(issuerStr, chain[certIndex].Issuer) != 0) { + return VCCRErrorValidation; + } + } + + return VCCRSuccess; +} + +#define OVR_SIGNING_CONVERT_PTR(ftype, fptr, procaddr) \ + { \ + union { \ + ftype p1; \ + ModuleFunctionType p2; \ + } u; \ + u.p2 = procaddr; \ + fptr = u.p1; \ + } + +static BOOL OVR_Win32_SignCheck(FilePathCharType* fullPath, HANDLE hFile) { + WINTRUST_FILE_INFO fileData; + WINTRUST_DATA wintrustData; + GUID actionGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2; + LONG resultStatus; + BOOL verified = FALSE; + HMODULE libWinTrust = LoadLibraryW(L"wintrust"); + HMODULE libCrypt32 = LoadLibraryW(L"crypt32"); + if (libWinTrust == NULL || libCrypt32 == NULL) { + return FALSE; + } + + OVR_SIGNING_CONVERT_PTR( + PtrCertGetNameStringW, + m_PtrCertGetNameStringW, + GetProcAddress(libCrypt32, "CertGetNameStringW")); + OVR_SIGNING_CONVERT_PTR( + PtrWinVerifyTrust, m_PtrWinVerifyTrust, GetProcAddress(libWinTrust, "WinVerifyTrust")); + OVR_SIGNING_CONVERT_PTR( + PtrWTHelperProvDataFromStateData, + m_PtrWTHelperProvDataFromStateData, + GetProcAddress(libWinTrust, "WTHelperProvDataFromStateData")); + OVR_SIGNING_CONVERT_PTR( + PtrWTHelperGetProvSignerFromChain, + m_PtrWTHelperGetProvSignerFromChain, + GetProcAddress(libWinTrust, "WTHelperGetProvSignerFromChain")); + + if (m_PtrCertGetNameStringW == NULL || m_PtrWinVerifyTrust == NULL || + m_PtrWTHelperProvDataFromStateData == NULL || m_PtrWTHelperGetProvSignerFromChain == NULL) { + return FALSE; + } + + if (hFile == INVALID_HANDLE_VALUE || fullPath == NULL) { + return FALSE; + } + + ZeroMemory(&fileData, sizeof(fileData)); + fileData.cbStruct = sizeof(fileData); + fileData.pcwszFilePath = fullPath; + fileData.hFile = hFile; + + ZeroMemory(&wintrustData, sizeof(wintrustData)); + wintrustData.cbStruct = sizeof(wintrustData); + wintrustData.pFile = &fileData; + wintrustData.dwUnionChoice = WTD_CHOICE_FILE; // Specify WINTRUST_FILE_INFO. + wintrustData.dwUIChoice = WTD_UI_NONE; // Do not display any UI. + wintrustData.dwUIContext = WTD_UICONTEXT_EXECUTE; // Hint that this is about app execution. + wintrustData.fdwRevocationChecks = WTD_REVOKE_NONE; + wintrustData.dwProvFlags = WTD_REVOCATION_CHECK_NONE; + wintrustData.dwStateAction = WTD_STATEACTION_VERIFY; + wintrustData.hWVTStateData = 0; + + resultStatus = m_PtrWinVerifyTrust( + (HWND)INVALID_HANDLE_VALUE, // Do not display any UI. + &actionGUID, // V2 verification + &wintrustData); + + if (resultStatus == ERROR_SUCCESS && wintrustData.hWVTStateData != 0 && + wintrustData.hWVTStateData != INVALID_HANDLE_VALUE) { + CRYPT_PROVIDER_DATA* cpd = m_PtrWTHelperProvDataFromStateData(wintrustData.hWVTStateData); + if (cpd && cpd->csSigners == 1) { + CRYPT_PROVIDER_SGNR* cps = m_PtrWTHelperGetProvSignerFromChain(cpd, 0, FALSE, 0); + int chainIndex; + for (chainIndex = 0; chainIndex < CertificateChainCount; ++chainIndex) { + CertificateEntry* chain = AllowedCertificateChains[chainIndex]; + if (VCCRSuccess == ValidateCertificateContents(chain, cps)) { + verified = TRUE; + break; + } + } + } + } + + wintrustData.dwStateAction = WTD_STATEACTION_CLOSE; + + m_PtrWinVerifyTrust( + (HWND)INVALID_HANDLE_VALUE, // Do not display any UI. + &actionGUID, // V2 verification + &wintrustData); + + return verified; +} + +#endif // #if defined(_WIN32) + +static ModuleHandleType OVR_OpenLibrary(const FilePathCharType* libraryPath, ovrResult* result) { +#if defined(_WIN32) + DWORD fullPathNameLen = 0; + FilePathCharType fullPath[MAX_PATH] = {0}; + HANDLE hFilePinned = INVALID_HANDLE_VALUE; + ModuleHandleType hModule = 0; + + *result = ovrSuccess; + + fullPathNameLen = GetFullPathNameW(libraryPath, MAX_PATH, fullPath, 0); + if (fullPathNameLen <= 0 || fullPathNameLen >= MAX_PATH) { + *result = ovrError_LibPath; + return NULL; + } + + hFilePinned = CreateFileW( + fullPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 0); + + if (hFilePinned == INVALID_HANDLE_VALUE) { + *result = ovrError_LibPath; + return NULL; + } + + if (!OVR_Win32_SignCheck(fullPath, hFilePinned)) { + *result = ovrError_LibSignCheck; + CloseHandle(hFilePinned); + return NULL; + } + + hModule = LoadLibraryW(fullPath); + + CloseHandle(hFilePinned); + + if (hModule == NULL) { + *result = ovrError_LibLoad; + } + + return hModule; +#else + *result = ovrSuccess; + + // Don't bother trying to dlopen() a file that is not even there. + if (access(libraryPath, X_OK | R_OK) != 0) { + *result = ovrError_LibPath; + return NULL; + } + + dlerror(); // Clear any previous dlopen() errors + + // Use RTLD_NOW because we don't want unexpected stalls at runtime, and the library isn't very + // large. + // Use RTLD_LOCAL to avoid unilaterally exporting resolved symbols to the rest of this process. + void* lib = dlopen(libraryPath, RTLD_NOW | RTLD_LOCAL); + + if (!lib) { + fprintf(stderr, "ERROR: Can't load '%s':\n%s\n", libraryPath, dlerror()); + } + + return lib; +#endif +} + +static void OVR_CloseLibrary(ModuleHandleType hLibrary) { + if (hLibrary) { +#if defined(_WIN32) + // We may need to consider what to do in the case that the library is in an exception state. + // In a Windows C++ DLL, all global objects (including static members of classes) will be + // constructed just + // before the calling of the DllMain with DLL_PROCESS_ATTACH and they will be destroyed just + // after + // the call of the DllMain with DLL_PROCESS_DETACH. We may need to intercept DLL_PROCESS_DETACH + // and + // have special handling for the case that the DLL is broken. + FreeLibrary(hLibrary); +#else + dlclose(hLibrary); +#endif + } +} + +// Returns a valid ModuleHandleType (e.g. Windows HMODULE) or returns ModuleHandleTypeNull (e.g. +// NULL). +// The caller is required to eventually call OVR_CloseLibrary on a valid return handle. +// +static ModuleHandleType OVR_FindLibraryPath( + int requestedProductVersion, + int requestedMajorVersion, + FilePathCharType* libraryPath, + size_t libraryPathCapacity, + ovrResult* result) { + ModuleHandleType moduleHandle; + FilePathCharType developerDir[OVR_MAX_PATH] = {'\0'}; + +#if defined(_MSC_VER) +#if defined(_WIN64) + const char* pBitDepth = "64"; +#else + const char* pBitDepth = "32"; +#endif +#elif defined(__APPLE__) +// For Apple platforms we are using a Universal Binary LibOVRRT dylib which has both 32 and 64 in +// it. +#else // Other Unix. +#if defined(__x86_64__) + const char* pBitDepth = "64"; +#else + const char* pBitDepth = "32"; +#endif +#endif + + (void)requestedProductVersion; + + *result = ovrError_LibLoad; + moduleHandle = ModuleHandleTypeNull; + if (libraryPathCapacity) { + libraryPath[0] = '\0'; + } + +#if (defined(_MSC_VER) || defined(_WIN32)) && !defined(OVR_FILE_PATH_SEPARATOR) +#define OVR_FILE_PATH_SEPARATOR L"\\" +#else +#define OVR_FILE_PATH_SEPARATOR "/" +#endif + + { +#if defined(_WIN32) + size_t length; + _wgetenv_s(&length, developerDir, _countof(developerDir), L"LIBOVR_DLL_DIR"); + if ((length != 0) && (length < _countof(developerDir)) && + developerDir[length - 2] != OVR_FILE_PATH_SEPARATOR[0]) { + assert(developerDir[length - 1] == '\0'); + developerDir[length - 1] = OVR_FILE_PATH_SEPARATOR[0]; + developerDir[length] = '\0'; + } +#else + // Example value: /dev/OculusSDK/Main/LibOVR/Mac/Debug/ + const char* pLibOvrDllDir = getenv("LIBOVR_DLL_DIR"); + + if (pLibOvrDllDir) { + char developerDir8[OVR_MAX_PATH]; + size_t length = OVR_strlcpy(developerDir8, pLibOvrDllDir, sizeof(developerDir8)); + + // If missing a trailing path separator then append one. + if ((length > 0) && (length < sizeof(developerDir8)) && + (developerDir8[length - 1] != OVR_FILE_PATH_SEPARATOR[0])) { + length = OVR_strlcat(developerDir8, OVR_FILE_PATH_SEPARATOR, sizeof(developerDir8)); + } + + if (length < sizeof(developerDir8)) { + OVR_strlcpy(developerDir, developerDir8, sizeof(developerDir)); + } + } +#endif + } + + { + size_t i; + +#if !defined(_WIN32) + FilePathCharType cwDir[OVR_MAX_PATH]; // Will be filled in below. + FilePathCharType appDir[OVR_MAX_PATH]; + OVR_GetCurrentWorkingDirectory(cwDir, sizeof(cwDir) / sizeof(cwDir[0])); + OVR_GetCurrentApplicationDirectory(appDir, sizeof(appDir) / sizeof(appDir[0]), ovrTrue, NULL); +#endif + +#if defined(_WIN32) + // On Windows, only search the developer directory and the usual path + const FilePathCharType* directoryArray[2]; + directoryArray[0] = developerDir; // Developer directory. + directoryArray[1] = L""; // No directory, which causes Windows to use the standard search + // strategy to find the DLL. + +#elif defined(__APPLE__) + // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/dyld.1.html + + FilePathCharType homeDir[OVR_MAX_PATH]; + FilePathCharType homeFrameworkDir[OVR_MAX_PATH]; + const FilePathCharType* directoryArray[5]; + size_t homeDirLength = 0; + + const char* pHome = getenv("HOME"); // Try getting the HOME environment variable. + + if (pHome) { + homeDirLength = OVR_strlcpy(homeDir, pHome, sizeof(homeDir)); + } else { + // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/getpwuid_r.3.html + const long pwBufferSize = sysconf(_SC_GETPW_R_SIZE_MAX); + + if (pwBufferSize != -1) { + char pwBuffer[pwBufferSize]; + struct passwd pw; + struct passwd* pwResult = NULL; + + if ((getpwuid_r(getuid(), &pw, pwBuffer, pwBufferSize, &pwResult) == 0) && pwResult) + homeDirLength = OVR_strlcpy(homeDir, pw.pw_dir, sizeof(homeDir)); + } + } + + if (homeDirLength) { + if (homeDir[homeDirLength - 1] == '/') + homeDir[homeDirLength - 1] = '\0'; + OVR_strlcpy(homeFrameworkDir, homeDir, sizeof(homeFrameworkDir)); + OVR_strlcat(homeFrameworkDir, "/Library/Frameworks/", sizeof(homeFrameworkDir)); + } else { + homeFrameworkDir[0] = '\0'; + } + + directoryArray[0] = cwDir; + directoryArray[1] = appDir; + directoryArray[2] = homeFrameworkDir; // ~/Library/Frameworks/ + directoryArray[3] = "/Library/Frameworks/"; // DYLD_FALLBACK_FRAMEWORK_PATH + directoryArray[4] = developerDir; // Developer directory. + +#else +#define STR1(x) #x +#define STR(x) STR1(x) +#ifdef LIBDIR +#define TEST_LIB_DIR STR(LIBDIR) "/" +#else +#define TEST_LIB_DIR appDir +#endif + + const FilePathCharType* directoryArray[5]; + directoryArray[0] = cwDir; + directoryArray[1] = TEST_LIB_DIR; // Directory specified by LIBDIR if defined. + directoryArray[2] = developerDir; // Developer directory. + directoryArray[3] = "/usr/local/lib/"; + directoryArray[4] = "/usr/lib/"; +#endif + + // Versioned file expectations. + // Windows: LibOVRRT__.dll + // // Example: LibOVRRT64_1_1.dll -- LibOVRRT 64 bit, product 1, major version 1, + // minor/patch/build numbers unspecified in the name. + // Mac: + // LibOVRRT_.framework/Versions//LibOVRRT_ + // // We are not presently using the .framework bundle's Current directory to hold the + // version number. This may change. + // Linux: libOVRRT_.so. + // // The file on disk may contain a minor version number, but a symlink is used to map this + // major-only version to it. + + // Since we are manually loading the LibOVR dynamic library, we need to look in various + // locations for a file + // that matches our requirements. The functionality required is somewhat similar to the + // operating system's + // dynamic loader functionality. Each OS has some differences in how this is handled. + // Future versions of this may iterate over all libOVRRT.so.* files in the directory and use the + // one that matches our requirements. + // + // We need to look for a library that matches the product version and major version of the + // caller's request, + // and that library needs to support a minor version that is >= the requested minor version. + // Currently we + // don't test the minor version here, as the library is named based only on the product and + // major version. + // Currently the minor version test is handled via the initialization of the library and the + // initialization + // fails if minor version cannot be supported by the library. The reason this is done during + // initialization + // is that the library can at runtime support multiple minor versions based on the user's + // request. To the + // external user, all that matters it that they call ovr_Initialize with a requested version and + // it succeeds + // or fails. + // + // The product version is something that is at a higher level than the major version, and is not + // something that's + // always seen in libraries (an example is the well-known LibXml2 library, in which the 2 is + // essentially the product version). + + for (i = 0; i < sizeof(directoryArray) / sizeof(directoryArray[0]); ++i) { +#if defined(_WIN32) + int printfResult = swprintf( + libraryPath, + libraryPathCapacity, + L"%lsLibOVRRT%hs_%d.dll", + directoryArray[i], + pBitDepth, + requestedMajorVersion); + + if (*directoryArray[i] == 0) { + int k; + FilePathCharType foundPath[MAX_PATH] = {0}; + DWORD searchResult = SearchPathW(NULL, libraryPath, NULL, MAX_PATH, foundPath, NULL); + if (searchResult <= 0 || searchResult >= libraryPathCapacity) { + continue; + } + foundPath[MAX_PATH - 1] = 0; + for (k = 0; k < MAX_PATH; ++k) { + libraryPath[k] = foundPath[k]; + } + } + +#elif defined(__APPLE__) + (void)requestedMajorVersion; + // https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/VersionInformation.html + // Macintosh application bundles have the option of embedding dependent frameworks within the + // application + // bundle itself. A problem with that is that it doesn't support vendor-supplied updates to + // the framework. + int printfResult = + snprintf(libraryPath, libraryPathCapacity, "%sLibOVRRT.dylib", directoryArray[i]); + +#else // Unix + // Applications that depend on the OS (e.g. ld-linux / ldd) can rely on the library being in a + // common location + // such as /usr/lib or can rely on the -rpath linker option to embed a path for the OS to + // check for the library, + // or can rely on the LD_LIBRARY_PATH environment variable being set. It's generally not + // recommended that applications + // depend on LD_LIBRARY_PATH be globally modified, partly due to potentialy security issues. + // Currently we check the current application directory, current working directory, and then + // /usr/lib and possibly others. + int printfResult = snprintf( + libraryPath, + libraryPathCapacity, + "%slibOVRRT%s.so.%d", + directoryArray[i], + pBitDepth, + requestedMajorVersion); +#endif + + if ((printfResult >= 0) && (printfResult < (int)libraryPathCapacity)) { + moduleHandle = OVR_OpenLibrary(libraryPath, result); + if (moduleHandle != ModuleHandleTypeNull) + return moduleHandle; + } + } + } + + return moduleHandle; +} + +//----------------------------------------------------------------------------------- +// ***** hLibOVR +// +// global handle to the LivOVR shared library. +// +static ModuleHandleType hLibOVR = NULL; + +// This function is currently unsupported. +ModuleHandleType ovr_GetLibOVRRTHandle() { + return hLibOVR; +} + +//----------------------------------------------------------------------------------- +// ***** Function declarations +// + +//----------------------------------------------------------------------------------- +// ***** OVR_DECLARE_IMPORT +// +// Creates a pointer and loader value union for each entry in OVR_LIST_APIS() +// + +#define OVR_DECLARE_IMPORT(ReturnValue, FunctionName, OptionalVersion, Arguments) \ + union { \ + ReturnValue(OVR_CDECL* Ptr) Arguments; \ + ModuleFunctionType Symbol; \ + } FunctionName; + +#define OVR_IGNORE_IMPORT(ReturnValue, FunctionName, OptionalVersion, Arguments) + +//----------------------------------------------------------------------------------- +// ***** API - a structure with each API entrypoint as a FunctionName.Ptr and FunctionName.Symbol +// union +// + +static struct { OVR_LIST_APIS(OVR_DECLARE_IMPORT, OVR_IGNORE_IMPORT) } API = {{NULL}}; + +static void OVR_UnloadSharedLibrary() { + memset(&API, 0, sizeof(API)); + if (hLibOVR) + OVR_CloseLibrary(hLibOVR); + hLibOVR = NULL; +} + +// Don't put this on the heap +static ovrErrorInfo LastInitializeErrorInfo = {ovrError_NotInitialized, + "ovr_Initialize never called"}; + +static ovrResult OVR_LoadSharedLibrary(int requestedProductVersion, int requestedMajorVersion) { + FilePathCharType filePath[OVR_MAX_PATH]; + const char* SymbolName = NULL; + ovrResult result = ovrSuccess; + + if (hLibOVR) + return result; + + hLibOVR = OVR_FindLibraryPath( + requestedProductVersion, + requestedMajorVersion, + filePath, + sizeof(filePath) / sizeof(filePath[0]), + &result); + + if (!hLibOVR) { + LastInitializeErrorInfo.Result = result; + OVR_strlcpy( + LastInitializeErrorInfo.ErrorString, + "Unable to load LibOVRRT DLL", + sizeof(LastInitializeErrorInfo.ErrorString)); + return result; + } + + ovrBool AllowSymbolLoadFailure = ovrFalse; + + // Zero the API table just to be paranoid + memset(&API, 0, sizeof(API)); + +// Load the current API entrypoint using the catenated FunctionName and OptionalVersion +#define OVR_GETFUNCTION(ReturnValue, FunctionName, OptionalVersion, Arguments) \ + SymbolName = #FunctionName #OptionalVersion; \ + API.FunctionName.Symbol = OVR_DLSYM(hLibOVR, SymbolName); \ + if (!API.FunctionName.Symbol && !AllowSymbolLoadFailure) { \ + LastInitializeErrorInfo.Result = result = ovrError_LibSymbols; \ + OVR_strlcpy( \ + LastInitializeErrorInfo.ErrorString, \ + "Unable to locate LibOVRRT symbol: ", \ + sizeof(LastInitializeErrorInfo.ErrorString)); \ + OVR_strlcat( \ + LastInitializeErrorInfo.ErrorString, \ + SymbolName, \ + sizeof(LastInitializeErrorInfo.ErrorString)); \ + goto FailedToLoadSymbol; \ + } + + OVR_LIST_APIS(OVR_GETFUNCTION, OVR_IGNORE_IMPORT) + +#undef OVR_GETFUNCTION + + return result; + +FailedToLoadSymbol: + // Check SymbolName for the name of the API which failed to load + OVR_UnloadSharedLibrary(); + return result; +} + +// These defaults are also in CAPI.cpp +static const ovrInitParams DefaultParams = { + ovrInit_RequestVersion, // Flags + OVR_MINOR_VERSION, // RequestedMinorVersion + 0, // LogCallback + 0, // UserData + 0, // ConnectionTimeoutSeconds + OVR_ON64("") // pad0 +}; + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_Initialize(const ovrInitParams* inputParams) { + ovrResult result; + ovrInitParams params; + + typedef void(OVR_CDECL * ovr_ReportClientInfoType)( + unsigned int compilerVersion, + int productVersion, + int majorVersion, + int minorVersion, + int patchVersion, + int buildNumber); + ovr_ReportClientInfoType reportClientInfo; + + // Do something with our version signature hash to prevent + // it from being optimized out. In this case, compute + // a cheap CRC. + uint8_t crc = 0; + size_t i; + + for (i = 0; i < (sizeof(OculusSDKUniqueIdentifier) - 3); + ++i) // Minus 3 because we have trailing OVR_MAJOR_VERSION, OVR_MINOR_VERSION, + // OVR_PATCH_VERSION which vary per version. + { + crc ^= OculusSDKUniqueIdentifier[i]; + } + + assert(crc == OculusSDKUniqueIdentifierXORResult); + if (crc != OculusSDKUniqueIdentifierXORResult) { + return ovrError_Initialize; + } + + if (!inputParams) { + params = DefaultParams; + } else { + params = *inputParams; + + // If not requesting a particular minor version, + if (!(params.Flags & ovrInit_RequestVersion)) { + // Enable requesting the default minor version. + params.Flags |= ovrInit_RequestVersion; + params.RequestedMinorVersion = OVR_MINOR_VERSION; + } + } + + // Clear non-writable bits provided by client code. + params.Flags &= ovrinit_WritableBits; + + + // Error out if the requested minor version is less than our lowest deemed compatible version + // denoted by OVR_MIN_REQUESTABLE_MINOR_VERSION. + // Note: This code has to be in the shim as we want to enforce usage of the new API versions for + // applications being recompiled while maintaining backwards compatibility with older apps + if (params.RequestedMinorVersion < OVR_MIN_REQUESTABLE_MINOR_VERSION) { + // Requested LibOVRRT version too low + result = ovrError_LibVersion; + return result; + } + + // By design we ignore the build version in the library search. + result = OVR_LoadSharedLibrary(OVR_PRODUCT_VERSION, OVR_MAJOR_VERSION); + if (result != ovrSuccess) + return result; + + result = API.ovr_Initialize.Ptr(¶ms); + + if (result != ovrSuccess) { + // Stash the last initialization error for the shim to return if + // ovr_GetLastErrorInfo is called after we unload the dll below + if (API.ovr_GetLastErrorInfo.Ptr) { + API.ovr_GetLastErrorInfo.Ptr(&LastInitializeErrorInfo); + } + OVR_UnloadSharedLibrary(); + } + + reportClientInfo = + (ovr_ReportClientInfoType)(uintptr_t)OVR_DLSYM(hLibOVR, "ovr_ReportClientInfo"); + + if (reportClientInfo) { + unsigned int mscFullVer = 0; +#if defined(_MSC_FULL_VER) + mscFullVer = _MSC_FULL_VER; +#endif // _MSC_FULL_VER + + reportClientInfo( + mscFullVer, + OVR_PRODUCT_VERSION, + OVR_MAJOR_VERSION, + OVR_MINOR_VERSION, + OVR_PATCH_VERSION, + 0); + } + + return result; +} + +OVR_PUBLIC_FUNCTION(void) ovr_Shutdown() { + if (!API.ovr_Shutdown.Ptr) + return; + API.ovr_Shutdown.Ptr(); + OVR_UnloadSharedLibrary(); +} + +OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString() { + // We don't directly return the value of the DLL API.ovr_GetVersionString.Ptr call, + // because that call returns a pointer to memory within the DLL. If the DLL goes + // away then that pointer becomes invalid while the process may still be holding + // onto it. So we save a local copy of it which is always valid. + static char dllVersionStringLocal[32]; + const char* dllVersionString; + + if (!API.ovr_GetVersionString.Ptr) + return "(Unable to load LibOVR)"; + + dllVersionString = API.ovr_GetVersionString.Ptr(); // Guaranteed to always be valid. + assert(dllVersionString != NULL); + OVR_strlcpy(dllVersionStringLocal, dllVersionString, sizeof(dllVersionStringLocal)); + + return dllVersionStringLocal; +} + +OVR_PUBLIC_FUNCTION(void) ovr_GetLastErrorInfo(ovrErrorInfo* errorInfo) { + if (!API.ovr_GetLastErrorInfo.Ptr) { + *errorInfo = LastInitializeErrorInfo; + } else + API.ovr_GetLastErrorInfo.Ptr(errorInfo); +} + +OVR_PUBLIC_FUNCTION(ovrHmdDesc) ovr_GetHmdDesc(ovrSession session) { + if (!API.ovr_GetHmdDesc.Ptr) { + ovrHmdDesc hmdDesc; + memset(&hmdDesc, 0, sizeof(hmdDesc)); + hmdDesc.Type = ovrHmd_None; + return hmdDesc; + } + + return API.ovr_GetHmdDesc.Ptr(session); +} + +OVR_PUBLIC_FUNCTION(ovrHmdColorDesc) ovr_GetHmdColorDesc(ovrSession session) { + if (!API.ovr_GetHmdColorDesc.Ptr) { + ovrHmdColorDesc hmdColorDesc; + memset(&hmdColorDesc, 0, sizeof(hmdColorDesc)); + return hmdColorDesc; + } + + return API.ovr_GetHmdColorDesc.Ptr(session); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SetClientColorDesc(ovrSession session, const ovrHmdColorDesc* hmdColorDesc) { + if (!API.ovr_SetClientColorDesc.Ptr) { + return ovrError_NotInitialized; + } + + return API.ovr_SetClientColorDesc.Ptr(session, hmdColorDesc); +} + +OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetTrackerCount(ovrSession session) { + if (!API.ovr_GetTrackerCount.Ptr) { + return 0; + } + + return API.ovr_GetTrackerCount.Ptr(session); +} + +OVR_PUBLIC_FUNCTION(ovrTrackerDesc) +ovr_GetTrackerDesc(ovrSession session, unsigned int trackerDescIndex) { + if (!API.ovr_GetTrackerDesc.Ptr) { + ovrTrackerDesc trackerDesc; + memset(&trackerDesc, 0, sizeof(trackerDesc)); + return trackerDesc; + } + + return API.ovr_GetTrackerDesc.Ptr(session, trackerDescIndex); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_Create(ovrSession* pSession, ovrGraphicsLuid* pLuid) { + if (!API.ovr_Create.Ptr) + return ovrError_NotInitialized; + return API.ovr_Create.Ptr(pSession, pLuid); +} + +OVR_PUBLIC_FUNCTION(void) ovr_Destroy(ovrSession session) { + if (!API.ovr_Destroy.Ptr) + return; + API.ovr_Destroy.Ptr(session); +} + + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetSessionStatus(ovrSession session, ovrSessionStatus* sessionStatus) { + if (!API.ovr_GetSessionStatus.Ptr) { + if (sessionStatus) { + sessionStatus->IsVisible = ovrFalse; + sessionStatus->HmdPresent = ovrFalse; + sessionStatus->HmdMounted = ovrFalse; + sessionStatus->ShouldQuit = ovrFalse; + sessionStatus->DisplayLost = ovrFalse; + sessionStatus->ShouldRecenter = ovrFalse; + sessionStatus->HasInputFocus = ovrFalse; + sessionStatus->OverlayPresent = ovrFalse; + sessionStatus->DepthRequested = ovrFalse; + } + + return ovrError_NotInitialized; + } + + return API.ovr_GetSessionStatus.Ptr(session, sessionStatus); +} + + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_IsExtensionSupported(ovrSession session, ovrExtensions extension, ovrBool* extensionSupported) { + if (!API.ovr_IsExtensionSupported.Ptr) + return ovrError_NotInitialized; + return API.ovr_IsExtensionSupported.Ptr(session, extension, extensionSupported); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_EnableExtension(ovrSession session, ovrExtensions extension) { + if (!API.ovr_EnableExtension.Ptr) + return ovrError_NotInitialized; + return API.ovr_EnableExtension.Ptr(session, extension); +} + + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SetTrackingOriginType(ovrSession session, ovrTrackingOrigin origin) { + if (!API.ovr_SetTrackingOriginType.Ptr) + return ovrError_NotInitialized; + return API.ovr_SetTrackingOriginType.Ptr(session, origin); +} + +OVR_PUBLIC_FUNCTION(ovrTrackingOrigin) ovr_GetTrackingOriginType(ovrSession session) { + if (!API.ovr_GetTrackingOriginType.Ptr) + return ovrTrackingOrigin_EyeLevel; + return API.ovr_GetTrackingOriginType.Ptr(session); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_RecenterTrackingOrigin(ovrSession session) { + if (!API.ovr_RecenterTrackingOrigin.Ptr) + return ovrError_NotInitialized; + return API.ovr_RecenterTrackingOrigin.Ptr(session); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_SpecifyTrackingOrigin(ovrSession session, ovrPosef originPose) { + if (!API.ovr_SpecifyTrackingOrigin.Ptr) + return ovrError_NotInitialized; + return API.ovr_SpecifyTrackingOrigin.Ptr(session, originPose); +} + +OVR_PUBLIC_FUNCTION(void) ovr_ClearShouldRecenterFlag(ovrSession session) { + if (!API.ovr_ClearShouldRecenterFlag.Ptr) + return; + API.ovr_ClearShouldRecenterFlag.Ptr(session); +} + +OVR_PUBLIC_FUNCTION(ovrTrackingState) +ovr_GetTrackingState(ovrSession session, double absTime, ovrBool latencyMarker) { + if (!API.ovr_GetTrackingState.Ptr) { + ovrTrackingState nullTrackingState; + memset(&nullTrackingState, 0, sizeof(nullTrackingState)); + return nullTrackingState; + } + + return API.ovr_GetTrackingState.Ptr(session, absTime, latencyMarker); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetDevicePoses( + ovrSession session, + ovrTrackedDeviceType* deviceTypes, + int deviceCount, + double absTime, + ovrPoseStatef* outDevicePoses) { + if (!API.ovr_GetDevicePoses.Ptr) + return ovrError_NotInitialized; + return API.ovr_GetDevicePoses.Ptr(session, deviceTypes, deviceCount, absTime, outDevicePoses); +} + + +OVR_PUBLIC_FUNCTION(ovrTrackerPose) +ovr_GetTrackerPose(ovrSession session, unsigned int trackerPoseIndex) { + if (!API.ovr_GetTrackerPose.Ptr) { + ovrTrackerPose nullTrackerPose; + memset(&nullTrackerPose, 0, sizeof(nullTrackerPose)); + return nullTrackerPose; + } + + return API.ovr_GetTrackerPose.Ptr(session, trackerPoseIndex); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetInputState(ovrSession session, ovrControllerType controllerType, ovrInputState* inputState) { + if (!API.ovr_GetInputState.Ptr) { + if (inputState) + memset(inputState, 0, sizeof(ovrInputState)); + return ovrError_NotInitialized; + } + return API.ovr_GetInputState.Ptr(session, controllerType, inputState); +} + + +OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetConnectedControllerTypes(ovrSession session) { + if (!API.ovr_GetConnectedControllerTypes.Ptr) { + return 0; + } + return API.ovr_GetConnectedControllerTypes.Ptr(session); +} + +OVR_PUBLIC_FUNCTION(ovrTouchHapticsDesc) +ovr_GetTouchHapticsDesc(ovrSession session, ovrControllerType controllerType) { + if (!API.ovr_GetTouchHapticsDesc.Ptr) { + ovrTouchHapticsDesc nullDesc; + memset(&nullDesc, 0, sizeof(nullDesc)); + return nullDesc; + } + + return API.ovr_GetTouchHapticsDesc.Ptr(session, controllerType); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SetControllerVibration( + ovrSession session, + ovrControllerType controllerType, + float frequency, + float amplitude) { + if (!API.ovr_SetControllerVibration.Ptr) + return ovrError_NotInitialized; + + return API.ovr_SetControllerVibration.Ptr(session, controllerType, frequency, amplitude); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SubmitControllerVibration( + ovrSession session, + ovrControllerType controllerType, + const ovrHapticsBuffer* buffer) { + if (!API.ovr_SubmitControllerVibration.Ptr) + return ovrError_NotInitialized; + + return API.ovr_SubmitControllerVibration.Ptr(session, controllerType, buffer); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetControllerVibrationState( + ovrSession session, + ovrControllerType controllerType, + ovrHapticsPlaybackState* outState) { + if (!API.ovr_GetControllerVibrationState.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetControllerVibrationState.Ptr(session, controllerType, outState); +} + + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_TestBoundary( + ovrSession session, + ovrTrackedDeviceType deviceBitmask, + ovrBoundaryType singleBoundaryType, + ovrBoundaryTestResult* outTestResult) { + if (!API.ovr_TestBoundary.Ptr) + return ovrError_NotInitialized; + + return API.ovr_TestBoundary.Ptr(session, deviceBitmask, singleBoundaryType, outTestResult); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_TestBoundaryPoint( + ovrSession session, + const ovrVector3f* point, + ovrBoundaryType singleBoundaryType, + ovrBoundaryTestResult* outTestResult) { + if (!API.ovr_TestBoundaryPoint.Ptr) + return ovrError_NotInitialized; + + return API.ovr_TestBoundaryPoint.Ptr(session, point, singleBoundaryType, outTestResult); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SetBoundaryLookAndFeel(ovrSession session, const ovrBoundaryLookAndFeel* lookAndFeel) { + if (!API.ovr_SetBoundaryLookAndFeel.Ptr) + return ovrError_NotInitialized; + + return API.ovr_SetBoundaryLookAndFeel.Ptr(session, lookAndFeel); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_ResetBoundaryLookAndFeel(ovrSession session) { + if (!API.ovr_ResetBoundaryLookAndFeel.Ptr) + return ovrError_NotInitialized; + + return API.ovr_ResetBoundaryLookAndFeel.Ptr(session); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetBoundaryGeometry( + ovrSession session, + ovrBoundaryType singleBoundaryType, + ovrVector3f* outFloorPoints, + int* outFloorPointsCount) { + if (!API.ovr_GetBoundaryGeometry.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetBoundaryGeometry.Ptr( + session, singleBoundaryType, outFloorPoints, outFloorPointsCount); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetBoundaryDimensions( + ovrSession session, + ovrBoundaryType singleBoundaryType, + ovrVector3f* outDimensions) { + if (!API.ovr_GetBoundaryDimensions.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetBoundaryDimensions.Ptr(session, singleBoundaryType, outDimensions); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetBoundaryVisible(ovrSession session, ovrBool* outIsVisible) { + if (!API.ovr_GetBoundaryVisible.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetBoundaryVisible.Ptr(session, outIsVisible); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_RequestBoundaryVisible(ovrSession session, ovrBool visible) { + if (!API.ovr_RequestBoundaryVisible.Ptr) + return ovrError_NotInitialized; + + return API.ovr_RequestBoundaryVisible.Ptr(session, visible); +} + +OVR_PUBLIC_FUNCTION(ovrSizei) +ovr_GetFovTextureSize( + ovrSession session, + ovrEyeType eye, + ovrFovPort fov, + float pixelsPerDisplayPixel) { + if (!API.ovr_GetFovTextureSize.Ptr) { + ovrSizei nullSize; + memset(&nullSize, 0, sizeof(nullSize)); + return nullSize; + } + + return API.ovr_GetFovTextureSize.Ptr(session, eye, fov, pixelsPerDisplayPixel); +} + +#if defined(_WIN32) +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateTextureSwapChainDX( + ovrSession session, + IUnknown* d3dPtr, + const ovrTextureSwapChainDesc* desc, + ovrTextureSwapChain* outTextureSet) { + if (!API.ovr_CreateTextureSwapChainDX.Ptr) + return ovrError_NotInitialized; + + return API.ovr_CreateTextureSwapChainDX.Ptr(session, d3dPtr, desc, outTextureSet); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateMirrorTextureDX( + ovrSession session, + IUnknown* d3dPtr, + const ovrMirrorTextureDesc* desc, + ovrMirrorTexture* outMirrorTexture) { + if (!API.ovr_CreateMirrorTextureDX.Ptr) + return ovrError_NotInitialized; + + return API.ovr_CreateMirrorTextureDX.Ptr(session, d3dPtr, desc, outMirrorTexture); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateMirrorTextureWithOptionsDX( + ovrSession session, + IUnknown* d3dPtr, + const ovrMirrorTextureDesc* desc, + ovrMirrorTexture* outMirrorTexture) { + if (!API.ovr_CreateMirrorTextureWithOptionsDX.Ptr) + return ovrError_NotInitialized; + + return API.ovr_CreateMirrorTextureWithOptionsDX.Ptr(session, d3dPtr, desc, outMirrorTexture); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainBufferDX( + ovrSession session, + ovrTextureSwapChain chain, + int index, + IID iid, + void** ppObject) { + if (!API.ovr_GetTextureSwapChainBufferDX.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetTextureSwapChainBufferDX.Ptr(session, chain, index, iid, ppObject); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetMirrorTextureBufferDX( + ovrSession session, + ovrMirrorTexture mirror, + IID iid, + void** ppObject) { + if (!API.ovr_GetMirrorTextureBufferDX.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetMirrorTextureBufferDX.Ptr(session, mirror, iid, ppObject); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutWaveId(unsigned int* deviceOutId) { + if (!API.ovr_GetAudioDeviceOutWaveId.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetAudioDeviceOutWaveId.Ptr(deviceOutId); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInWaveId(unsigned int* deviceInId) { + if (!API.ovr_GetAudioDeviceInWaveId.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetAudioDeviceInWaveId.Ptr(deviceInId); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuidStr(WCHAR* deviceOutStrBuffer) { + if (!API.ovr_GetAudioDeviceOutGuidStr.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetAudioDeviceOutGuidStr.Ptr(deviceOutStrBuffer); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuid(GUID* deviceOutGuid) { + if (!API.ovr_GetAudioDeviceOutGuid.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetAudioDeviceOutGuid.Ptr(deviceOutGuid); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuidStr(WCHAR* deviceInStrBuffer) { + if (!API.ovr_GetAudioDeviceInGuidStr.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetAudioDeviceInGuidStr.Ptr(deviceInStrBuffer); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuid(GUID* deviceInGuid) { + if (!API.ovr_GetAudioDeviceInGuid.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetAudioDeviceInGuid.Ptr(deviceInGuid); +} + +#endif // _WIN32 + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateTextureSwapChainGL( + ovrSession session, + const ovrTextureSwapChainDesc* desc, + ovrTextureSwapChain* outTextureSet) { + if (!API.ovr_CreateTextureSwapChainGL.Ptr) + return ovrError_NotInitialized; + + return API.ovr_CreateTextureSwapChainGL.Ptr(session, desc, outTextureSet); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateMirrorTextureGL( + ovrSession session, + const ovrMirrorTextureDesc* desc, + ovrMirrorTexture* outMirrorTexture) { + if (!API.ovr_CreateMirrorTextureGL.Ptr) + return ovrError_NotInitialized; + + return API.ovr_CreateMirrorTextureGL.Ptr(session, desc, outMirrorTexture); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateMirrorTextureWithOptionsGL( + ovrSession session, + const ovrMirrorTextureDesc* desc, + ovrMirrorTexture* outMirrorTexture) { + if (!API.ovr_CreateMirrorTextureWithOptionsGL.Ptr) + return ovrError_NotInitialized; + + return API.ovr_CreateMirrorTextureWithOptionsGL.Ptr(session, desc, outMirrorTexture); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainBufferGL( + ovrSession session, + ovrTextureSwapChain chain, + int index, + unsigned int* texId) { + if (!API.ovr_GetTextureSwapChainBufferGL.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetTextureSwapChainBufferGL.Ptr(session, chain, index, texId); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetMirrorTextureBufferGL(ovrSession session, ovrMirrorTexture mirror, unsigned int* texId) { + if (!API.ovr_GetMirrorTextureBufferGL.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetMirrorTextureBufferGL.Ptr(session, mirror, texId); +} + +#if defined(_WIN32) +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetInstanceExtensionsVk( + ovrGraphicsLuid luid, + char* extensionNames, + uint32_t* inoutExtensionNamesSize) { + if (!API.ovr_GetInstanceExtensionsVk.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetInstanceExtensionsVk.Ptr(luid, extensionNames, inoutExtensionNamesSize); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetDeviceExtensionsVk( + ovrGraphicsLuid luid, + char* extensionNames, + uint32_t* inoutExtensionNamesSize) { + if (!API.ovr_GetDeviceExtensionsVk.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetDeviceExtensionsVk.Ptr(luid, extensionNames, inoutExtensionNamesSize); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetSessionPhysicalDeviceVk( + ovrSession session, + ovrGraphicsLuid luid, + VkInstance instance, + VkPhysicalDevice* out_physicalDevice) { + if (!API.ovr_GetSessionPhysicalDeviceVk.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetSessionPhysicalDeviceVk.Ptr(session, luid, instance, out_physicalDevice); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetSynchronizationQueueVk(ovrSession session, VkQueue queue) { + if (!API.ovr_SetSynchronizationQueueVk.Ptr) + return ovrError_NotInitialized; + + return API.ovr_SetSynchronizationQueueVk.Ptr(session, queue); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateTextureSwapChainVk( + ovrSession session, + VkDevice device, + const ovrTextureSwapChainDesc* desc, + ovrTextureSwapChain* out_TextureSwapChain) { + if (!API.ovr_CreateTextureSwapChainVk.Ptr) + return ovrError_NotInitialized; + + return API.ovr_CreateTextureSwapChainVk.Ptr(session, device, desc, out_TextureSwapChain); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainBufferVk( + ovrSession session, + ovrTextureSwapChain chain, + int index, + VkImage* out_Image) { + if (!API.ovr_GetTextureSwapChainBufferVk.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetTextureSwapChainBufferVk.Ptr(session, chain, index, out_Image); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CreateMirrorTextureWithOptionsVk( + ovrSession session, + VkDevice device, + const ovrMirrorTextureDesc* desc, + ovrMirrorTexture* out_MirrorTexture) { + if (!API.ovr_CreateMirrorTextureWithOptionsVk.Ptr) + return ovrError_NotInitialized; + + return API.ovr_CreateMirrorTextureWithOptionsVk.Ptr(session, device, desc, out_MirrorTexture); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetMirrorTextureBufferVk( + ovrSession session, + ovrMirrorTexture mirrorTexture, + VkImage* out_Image) { + if (!API.ovr_GetMirrorTextureBufferVk.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetMirrorTextureBufferVk.Ptr(session, mirrorTexture, out_Image); +} +#endif // defined (_WIN32) + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainLength(ovrSession session, ovrTextureSwapChain chain, int* length) { + if (!API.ovr_GetTextureSwapChainLength.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetTextureSwapChainLength.Ptr(session, chain, length); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainCurrentIndex( + ovrSession session, + ovrTextureSwapChain chain, + int* currentIndex) { + if (!API.ovr_GetTextureSwapChainCurrentIndex.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetTextureSwapChainCurrentIndex.Ptr(session, chain, currentIndex); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetTextureSwapChainDesc( + ovrSession session, + ovrTextureSwapChain chain, + ovrTextureSwapChainDesc* desc) { + if (!API.ovr_GetTextureSwapChainDesc.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetTextureSwapChainDesc.Ptr(session, chain, desc); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_CommitTextureSwapChain(ovrSession session, ovrTextureSwapChain chain) { + if (!API.ovr_CommitTextureSwapChain.Ptr) + return ovrError_NotInitialized; + + return API.ovr_CommitTextureSwapChain.Ptr(session, chain); +} + +OVR_PUBLIC_FUNCTION(void) +ovr_DestroyTextureSwapChain(ovrSession session, ovrTextureSwapChain chain) { + if (!API.ovr_DestroyTextureSwapChain.Ptr) + return; + + API.ovr_DestroyTextureSwapChain.Ptr(session, chain); +} + +OVR_PUBLIC_FUNCTION(void) +ovr_DestroyMirrorTexture(ovrSession session, ovrMirrorTexture mirrorTexture) { + if (!API.ovr_DestroyMirrorTexture.Ptr) + return; + + API.ovr_DestroyMirrorTexture.Ptr(session, mirrorTexture); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetFovStencil( + ovrSession session, + const ovrFovStencilDesc* fovStencilDesc, + ovrFovStencilMeshBuffer* meshBuffer) { + if (!API.ovr_GetFovStencil.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetFovStencil.Ptr(session, fovStencilDesc, meshBuffer); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_WaitToBeginFrame(ovrSession session, long long frameIndex) { + if (!API.ovr_WaitToBeginFrame.Ptr) + return ovrError_NotInitialized; + + return API.ovr_WaitToBeginFrame.Ptr(session, frameIndex); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_BeginFrame(ovrSession session, long long frameIndex) { + if (!API.ovr_BeginFrame.Ptr) + return ovrError_NotInitialized; + + return API.ovr_BeginFrame.Ptr(session, frameIndex); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_EndFrame( + ovrSession session, + long long frameIndex, + const ovrViewScaleDesc* viewScaleDesc, + ovrLayerHeader const* const* layerPtrList, + unsigned int layerCount) { + if (!API.ovr_EndFrame.Ptr) + return ovrError_NotInitialized; + + return API.ovr_EndFrame.Ptr(session, frameIndex, viewScaleDesc, layerPtrList, layerCount); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SubmitFrame( + ovrSession session, + long long frameIndex, + const ovrViewScaleDesc* viewScaleDesc, + ovrLayerHeader const* const* layerPtrList, + unsigned int layerCount) { + if (!API.ovr_SubmitFrame.Ptr) + return ovrError_NotInitialized; + + return API.ovr_SubmitFrame.Ptr(session, frameIndex, viewScaleDesc, layerPtrList, layerCount); +} + + +OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) +ovr_GetRenderDesc(ovrSession session, ovrEyeType eyeType, ovrFovPort fov) { + if (!API.ovr_GetRenderDesc.Ptr) { + ovrEyeRenderDesc nullEyeRenderDesc; + memset(&nullEyeRenderDesc, 0, sizeof(nullEyeRenderDesc)); + return nullEyeRenderDesc; + } + return API.ovr_GetRenderDesc.Ptr(session, eyeType, fov); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetPerfStats(ovrSession session, ovrPerfStats* outPerfStats) { + if (!API.ovr_GetPerfStats.Ptr) + return ovrError_NotInitialized; + + return API.ovr_GetPerfStats.Ptr(session, outPerfStats); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_ResetPerfStats(ovrSession session) { + if (!API.ovr_ResetPerfStats.Ptr) + return ovrError_NotInitialized; + + return API.ovr_ResetPerfStats.Ptr(session); +} + +OVR_PUBLIC_FUNCTION(double) ovr_GetPredictedDisplayTime(ovrSession session, long long frameIndex) { + if (!API.ovr_GetPredictedDisplayTime.Ptr) + return 0.0; + + return API.ovr_GetPredictedDisplayTime.Ptr(session, frameIndex); +} + +OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds() { + if (!API.ovr_GetTimeInSeconds.Ptr) + return 0.; + return API.ovr_GetTimeInSeconds.Ptr(); +} + +OVR_PUBLIC_FUNCTION(ovrBool) +ovr_GetBool(ovrSession session, const char* propertyName, ovrBool defaultVal) { + if (!API.ovr_GetBool.Ptr) + return ovrFalse; + return API.ovr_GetBool.Ptr(session, propertyName, defaultVal); +} + +OVR_PUBLIC_FUNCTION(ovrBool) +ovr_SetBool(ovrSession session, const char* propertyName, ovrBool value) { + if (!API.ovr_SetBool.Ptr) + return ovrFalse; + return API.ovr_SetBool.Ptr(session, propertyName, value); +} + +OVR_PUBLIC_FUNCTION(int) ovr_GetInt(ovrSession session, const char* propertyName, int defaultVal) { + if (!API.ovr_GetInt.Ptr) + return 0; + return API.ovr_GetInt.Ptr(session, propertyName, defaultVal); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetInt(ovrSession session, const char* propertyName, int value) { + if (!API.ovr_SetInt.Ptr) + return ovrFalse; + return API.ovr_SetInt.Ptr(session, propertyName, value); +} + +OVR_PUBLIC_FUNCTION(float) +ovr_GetFloat(ovrSession session, const char* propertyName, float defaultVal) { + if (!API.ovr_GetFloat.Ptr) + return 0.f; + return API.ovr_GetFloat.Ptr(session, propertyName, defaultVal); +} + +OVR_PUBLIC_FUNCTION(ovrBool) +ovr_SetFloat(ovrSession session, const char* propertyName, float value) { + if (!API.ovr_SetFloat.Ptr) + return ovrFalse; + return API.ovr_SetFloat.Ptr(session, propertyName, value); +} + +OVR_PUBLIC_FUNCTION(unsigned int) +ovr_GetFloatArray( + ovrSession session, + const char* propertyName, + float values[], + unsigned int arraySize) { + if (!API.ovr_GetFloatArray.Ptr) + return 0; + return API.ovr_GetFloatArray.Ptr(session, propertyName, values, arraySize); +} + +OVR_PUBLIC_FUNCTION(ovrBool) +ovr_SetFloatArray( + ovrSession session, + const char* propertyName, + const float values[], + unsigned int arraySize) { + if (!API.ovr_SetFloatArray.Ptr) + return ovrFalse; + return API.ovr_SetFloatArray.Ptr(session, propertyName, values, arraySize); +} + +OVR_PUBLIC_FUNCTION(const char*) +ovr_GetString(ovrSession session, const char* propertyName, const char* defaultVal) { + if (!API.ovr_GetString.Ptr) + return "(Unable to load LibOVR)"; + return API.ovr_GetString.Ptr(session, propertyName, defaultVal); +} + +OVR_PUBLIC_FUNCTION(ovrBool) +ovr_SetString(ovrSession session, const char* propertyName, const char* value) { + if (!API.ovr_SetString.Ptr) + return ovrFalse; + return API.ovr_SetString.Ptr(session, propertyName, value); +} + +OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message) { + if (!API.ovr_TraceMessage.Ptr) + return -1; + + return API.ovr_TraceMessage.Ptr(level, message); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_IdentifyClient(const char* identity) { + if (!API.ovr_IdentifyClient.Ptr) + return ovrError_NotInitialized; + + return API.ovr_IdentifyClient.Ptr(identity); +} + +OVR_PUBLIC_FUNCTION(ovrResult) ovr_Lookup(const char* name, void** data) { + if (!API.ovr_Lookup.Ptr) + return ovrError_NotInitialized; + return API.ovr_Lookup.Ptr(name, data); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GetExternalCameras( + ovrSession session, + ovrExternalCamera* outCameras, + unsigned int* outCameraCount) { + if (!API.ovr_GetExternalCameras.Ptr) + return ovrError_NotInitialized; + if (!outCameras || !outCameraCount) + return ovrError_InvalidParameter; + + return API.ovr_GetExternalCameras.Ptr(session, outCameras, outCameraCount); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_SetExternalCameraProperties( + ovrSession session, + const char* name, + const ovrCameraIntrinsics* const intrinsics, + const ovrCameraExtrinsics* const extrinsics) { + if (!API.ovr_SetExternalCameraProperties.Ptr) + return ovrError_NotInitialized; + if (!name || (!intrinsics && !extrinsics)) + return ovrError_InvalidParameter; + + return API.ovr_SetExternalCameraProperties.Ptr(session, name, intrinsics, extrinsics); +} +#if defined(_MSC_VER) +#pragma warning(pop) +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPI_Prototypes.h b/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPI_Prototypes.h new file mode 100644 index 0000000..fda10d2 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPI_Prototypes.h @@ -0,0 +1,171 @@ +/********************************************************************************/ /** + \file OVR_CAPI_Prototypes.h + \brief Internal CAPI prototype listing macros + \copyright Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + ************************************************************************************/ + +#ifndef OVR_CAPI_Prototypes_h +#define OVR_CAPI_Prototypes_h + +#include "OVR_CAPI.h" + + +// +// OVR_LIST_*_APIS - apply passed in macros to a list of API entrypoints +// +// The _ macro argument is applied for all current API versions +// The X macro argument is applied for back-compat API versions +// +// The tuple passed to either macro is (ReturnType, FunctionName, OptionalVersion, ParameterList) +// + + +struct ovrViewportStencilDesc_; +typedef struct ovrViewportStencilDesc_ ovrViewportStencilDesc; + +// clang-format off + +#define OVR_LIST_PUBLIC_APIS(_,X) \ +X(ovrBool, ovr_InitializeRenderingShimVersion, , (int requestedMinorVersion)) \ +_(ovrResult, ovr_Initialize, , (const ovrInitParams* params)) \ +_(void, ovr_Shutdown, , (void)) \ +_(const char*, ovr_GetVersionString, , (void)) \ +_(void, ovr_GetLastErrorInfo, , (ovrErrorInfo* errorInfo)) \ +_(ovrHmdDesc, ovr_GetHmdDesc, , (ovrSession session)) \ +_(unsigned int, ovr_GetTrackerCount, , (ovrSession session)) \ +_(ovrTrackerDesc, ovr_GetTrackerDesc, , (ovrSession session, unsigned int trackerDescIndex)) \ +_(ovrResult, ovr_Create, , (ovrSession* pSession, ovrGraphicsLuid* pLuid)) \ +_(void, ovr_Destroy, , (ovrSession session)) \ +_(ovrResult, ovr_GetSessionStatus, , (ovrSession session, ovrSessionStatus* sessionStatus)) \ +_(ovrResult, ovr_IsExtensionSupported, , (ovrSession session, ovrExtensions extension, ovrBool* outExtensionSupported)) \ +_(ovrResult, ovr_EnableExtension, , (ovrSession session, ovrExtensions extension)) \ +_(ovrResult, ovr_SetTrackingOriginType, , (ovrSession session, ovrTrackingOrigin origin)) \ +_(ovrTrackingOrigin, ovr_GetTrackingOriginType, , (ovrSession session)) \ +_(ovrResult, ovr_RecenterTrackingOrigin, , (ovrSession session)) \ +_(ovrResult, ovr_SpecifyTrackingOrigin, , (ovrSession session, ovrPosef originPose)) \ +_(void, ovr_ClearShouldRecenterFlag, , (ovrSession session)) \ +_(ovrTrackingState, ovr_GetTrackingState, , (ovrSession session, double absTime, ovrBool latencyMarker)) \ +_(ovrResult, ovr_GetDevicePoses, , (ovrSession session, ovrTrackedDeviceType* deviceTypes, int deviceCount, double absTime, ovrPoseStatef* outDevicePoses)) \ +_(ovrTrackerPose, ovr_GetTrackerPose, , (ovrSession session, unsigned int index)) \ +_(ovrResult, ovr_GetInputState, , (ovrSession session, ovrControllerType controllerType, ovrInputState*)) \ +_(unsigned int, ovr_GetConnectedControllerTypes, , (ovrSession session)) \ +_(ovrSizei, ovr_GetFovTextureSize, , (ovrSession session, ovrEyeType eye, ovrFovPort fov, float pixelsPerDisplayPixel)) \ +X(ovrResult, ovr_GetViewportStencil, , (ovrSession session, const ovrViewportStencilDesc* viewportStencilDesc, ovrFovStencilMeshBuffer* meshBuffer)) \ +_(ovrResult, ovr_GetFovStencil, , (ovrSession session, const ovrFovStencilDesc* fovStencilDesc, ovrFovStencilMeshBuffer* meshBuffer)) \ +_(ovrResult, ovr_WaitToBeginFrame, , (ovrSession session, long long frameIndex)) \ +_(ovrResult, ovr_BeginFrame, , (ovrSession session, long long frameIndex)) \ +_(ovrResult, ovr_EndFrame, , (ovrSession session, long long frameIndex, const ovrViewScaleDesc* viewScaleDesc, ovrLayerHeader const * const * layerPtrList, unsigned int layerCount)) \ +X(ovrResult, ovr_SubmitFrame, , (ovrSession session, long long frameIndex, const ovrViewScaleDescPre117* viewScaleDesc, ovrLayerHeader const * const * layerPtrList, unsigned int layerCount)) \ +_(ovrResult, ovr_SubmitFrame, 2, (ovrSession session, long long frameIndex, const ovrViewScaleDesc* viewScaleDesc, ovrLayerHeader const * const * layerPtrList, unsigned int layerCount)) \ +X(ovrEyeRenderDescPre117, ovr_GetRenderDesc, , (ovrSession session, ovrEyeType eyeType, ovrFovPort fov)) \ +_(ovrEyeRenderDesc, ovr_GetRenderDesc, 2, (ovrSession session, ovrEyeType eyeType, ovrFovPort fov)) \ +_(double, ovr_GetPredictedDisplayTime, , (ovrSession session, long long frameIndex)) \ +_(double, ovr_GetTimeInSeconds, , (void)) \ +_(ovrBool, ovr_GetBool, , (ovrSession session, const char* propertyName, ovrBool defaultVal)) \ +_(ovrBool, ovr_SetBool, , (ovrSession session, const char* propertyName, ovrBool value)) \ +_(int, ovr_GetInt, , (ovrSession session, const char* propertyName, int defaultVal)) \ +_(ovrBool, ovr_SetInt, , (ovrSession session, const char* propertyName, int value)) \ +_(float, ovr_GetFloat, , (ovrSession session, const char* propertyName, float defaultVal)) \ +_(ovrBool, ovr_SetFloat, , (ovrSession session, const char* propertyName, float value)) \ +_(unsigned int, ovr_GetFloatArray, , (ovrSession session, const char* propertyName, float values[], unsigned int arraySize)) \ +_(ovrBool, ovr_SetFloatArray, , (ovrSession session, const char* propertyName, const float values[], unsigned int arraySize)) \ +_(const char*, ovr_GetString, , (ovrSession session, const char* propertyName, const char* defaultVal)) \ +_(ovrBool, ovr_SetString, , (ovrSession session, const char* propertyName, const char* value)) \ +_(int, ovr_TraceMessage, , (int level, const char* message)) \ +_(ovrResult, ovr_IdentifyClient, , (const char* identity)) \ +_(ovrResult, ovr_CreateTextureSwapChainGL, , (ovrSession session, const ovrTextureSwapChainDesc* desc, ovrTextureSwapChain* outTextureChain)) \ +_(ovrResult, ovr_CreateMirrorTextureGL, , (ovrSession session, const ovrMirrorTextureDesc* desc, ovrMirrorTexture* outMirrorTexture)) \ +_(ovrResult, ovr_CreateMirrorTextureWithOptionsGL, , (ovrSession session, const ovrMirrorTextureDesc* desc, ovrMirrorTexture* outMirrorTexture)) \ +_(ovrResult, ovr_GetTextureSwapChainBufferGL, , (ovrSession session, ovrTextureSwapChain chain, int index, unsigned int* texId)) \ +_(ovrResult, ovr_GetMirrorTextureBufferGL, , (ovrSession session, ovrMirrorTexture mirror, unsigned int* texId)) \ +_(ovrResult, ovr_GetTextureSwapChainLength, , (ovrSession session, ovrTextureSwapChain chain, int* length)) \ +_(ovrResult, ovr_GetTextureSwapChainCurrentIndex, , (ovrSession session, ovrTextureSwapChain chain, int* currentIndex)) \ +_(ovrResult, ovr_GetTextureSwapChainDesc, , (ovrSession session, ovrTextureSwapChain chain, ovrTextureSwapChainDesc* desc)) \ +_(ovrResult, ovr_CommitTextureSwapChain, , (ovrSession session, ovrTextureSwapChain chain)) \ +_(void, ovr_DestroyTextureSwapChain, , (ovrSession session, ovrTextureSwapChain chain)) \ +_(void, ovr_DestroyMirrorTexture, , (ovrSession session, ovrMirrorTexture texture)) \ +X(ovrResult, ovr_SetQueueAheadFraction, , (ovrSession session, float queueAheadFraction)) \ +_(ovrResult, ovr_Lookup, , (const char* name, void** data)) \ +_(ovrTouchHapticsDesc, ovr_GetTouchHapticsDesc, , (ovrSession session, ovrControllerType controllerType)) \ +_(ovrResult, ovr_SetControllerVibration, , (ovrSession session, ovrControllerType controllerType, float frequency, float amplitude)) \ +_(ovrResult, ovr_SubmitControllerVibration, , (ovrSession session, ovrControllerType controllerType, const ovrHapticsBuffer* buffer)) \ +_(ovrResult, ovr_GetControllerVibrationState, , (ovrSession session, ovrControllerType controllerType, ovrHapticsPlaybackState* outState)) \ +_(ovrResult, ovr_TestBoundary, , (ovrSession session, ovrTrackedDeviceType deviceBitmask, ovrBoundaryType singleBoundaryType, ovrBoundaryTestResult* outTestResult)) \ +_(ovrResult, ovr_TestBoundaryPoint, , (ovrSession session, const ovrVector3f* point, ovrBoundaryType singleBoundaryType, ovrBoundaryTestResult* outTestResult)) \ +_(ovrResult, ovr_SetBoundaryLookAndFeel, , (ovrSession session, const ovrBoundaryLookAndFeel* lookAndFeel)) \ +_(ovrResult, ovr_ResetBoundaryLookAndFeel, , (ovrSession session)) \ +_(ovrResult, ovr_GetBoundaryGeometry, , (ovrSession session, ovrBoundaryType singleBoundaryType, ovrVector3f* outFloorPoints, int* outFloorPointsCount)) \ +_(ovrResult, ovr_GetBoundaryDimensions, , (ovrSession session, ovrBoundaryType singleBoundaryType, ovrVector3f* outDimension)) \ +_(ovrResult, ovr_GetBoundaryVisible, , (ovrSession session, ovrBool* outIsVisible)) \ +_(ovrResult, ovr_RequestBoundaryVisible, , (ovrSession session, ovrBool visible)) \ +_(ovrResult, ovr_GetPerfStats, , (ovrSession session, ovrPerfStats* outPerfStats)) \ +_(ovrResult, ovr_ResetPerfStats, , (ovrSession session))\ +_(ovrResult, ovr_GetExternalCameras, , (ovrSession session, ovrExternalCamera* outCameras, unsigned int* outCameraCount))\ +_(ovrResult, ovr_SetExternalCameraProperties, , (ovrSession session, const char* name, const ovrCameraIntrinsics* const intrinsics, const ovrCameraExtrinsics* const extrinsics )) \ +_(ovrHmdColorDesc, ovr_GetHmdColorDesc, , (ovrSession session)) \ +_(ovrResult, ovr_SetClientColorDesc, , (ovrSession session, const ovrHmdColorDesc* hmdColorDesc)) + +#if defined (_WIN32) +#define OVR_LIST_WIN32_APIS(_,X) \ + _(ovrResult, ovr_CreateTextureSwapChainDX, , (ovrSession session, IUnknown* d3dPtr, const ovrTextureSwapChainDesc* desc, ovrTextureSwapChain* outTextureChain)) \ + _(ovrResult, ovr_CreateMirrorTextureDX, , (ovrSession session, IUnknown* d3dPtr, const ovrMirrorTextureDesc* desc, ovrMirrorTexture* outMirrorTexture)) \ + _(ovrResult, ovr_CreateMirrorTextureWithOptionsDX, , (ovrSession session, IUnknown* d3dPtr, const ovrMirrorTextureDesc* desc, ovrMirrorTexture* outMirrorTexture)) \ + _(ovrResult, ovr_GetTextureSwapChainBufferDX, , (ovrSession session, ovrTextureSwapChain chain, int index, IID iid, void** ppObject)) \ + _(ovrResult, ovr_GetMirrorTextureBufferDX, , (ovrSession session, ovrMirrorTexture mirror, IID iid, void** ppObject)) \ + _(ovrResult, ovr_GetAudioDeviceOutWaveId, , (UINT* deviceOutId)) \ + _(ovrResult, ovr_GetAudioDeviceInWaveId, , (UINT* deviceInId)) \ + _(ovrResult, ovr_GetAudioDeviceOutGuidStr, , (WCHAR* deviceOutStrBuffer)) \ + _(ovrResult, ovr_GetAudioDeviceOutGuid, , (GUID* deviceOutGuid)) \ + _(ovrResult, ovr_GetAudioDeviceInGuidStr, , (WCHAR* deviceInStrBuffer)) \ + _(ovrResult, ovr_GetAudioDeviceInGuid, , (GUID* deviceInGuid)) \ + _(ovrResult, ovr_GetInstanceExtensionsVk, , (ovrGraphicsLuid luid, char* extensionNames, uint32_t* inoutExtensionNamesSize)) \ + _(ovrResult, ovr_GetDeviceExtensionsVk, , (ovrGraphicsLuid luid, char* extensionNames, uint32_t* inoutExtensionNamesSize)) \ + _(ovrResult, ovr_GetSessionPhysicalDeviceVk, , (ovrSession session, ovrGraphicsLuid luid, VkInstance instance, VkPhysicalDevice* out_physicalDevice)) \ + X(ovrResult, ovr_SetSynchonizationQueueVk, , (ovrSession session, VkQueue queue)) \ + _(ovrResult, ovr_SetSynchronizationQueueVk, , (ovrSession session, VkQueue queue)) \ + _(ovrResult, ovr_CreateTextureSwapChainVk, , (ovrSession session, VkDevice device, const ovrTextureSwapChainDesc* desc, ovrTextureSwapChain* out_TextureSwapChain)) \ + _(ovrResult, ovr_GetTextureSwapChainBufferVk, , (ovrSession session, ovrTextureSwapChain chain, int index, VkImage* out_Image)) \ + _(ovrResult, ovr_CreateMirrorTextureWithOptionsVk, , (ovrSession session, VkDevice device, const ovrMirrorTextureDesc* desc, ovrMirrorTexture* out_MirrorTexture)) \ + _(ovrResult, ovr_GetMirrorTextureBufferVk, , (ovrSession session, ovrMirrorTexture mirrorTexture, VkImage* out_Image)) +#else +#define OVR_LIST_WIN32_APIS(_,X) +#endif + +#define OVR_LIST_INTERNAL_APIS(_,X) + +// We need to forward declare the ovrSensorData type here, as it won't be in a public OVR_CAPI.h header. +struct ovrSensorData_; +typedef struct ovrSensorData_ ovrSensorData; + +// Hybrid Apps API forward declaration which won't be in a public OVR_CAPI.h header for now. +// -------------------------------------------------------------------------- +struct ovrDesktopWindowDesc_; +typedef struct ovrDesktopWindowDesc_ ovrDesktopWindowDesc; + +struct ovrKeyboardDesc_; +typedef struct ovrKeyboardDesc_ ovrKeyboardDesc; + +enum ovrHybridInputFocusType_ ; +typedef enum ovrHybridInputFocusType_ ovrHybridInputFocusType; + +struct ovrHybridInputFocusState_; +typedef struct ovrHybridInputFocusState_ ovrHybridInputFocusState; + +typedef uint32_t ovrDesktopWindowHandle; +// -------------------------------------------------------------------------- + +#define OVR_LIST_PRIVATE_APIS(_,X) + +// clang-format on + +// +// OVR_LIST_APIS - master list of all API entrypoints +// + +#define OVR_LIST_APIS(_, X) \ + OVR_LIST_PUBLIC_APIS(_, X) \ + OVR_LIST_WIN32_APIS(_, X) \ + OVR_LIST_INTERNAL_APIS(_, X) \ + OVR_LIST_PRIVATE_APIS(_, X) + +#endif // OVR_CAPI_Prototypes_h diff --git a/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPI_Util.cpp b/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPI_Util.cpp new file mode 100644 index 0000000..f53aa66 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPI_Util.cpp @@ -0,0 +1,430 @@ +/************************************************************************************ + +PublicHeader: OVR_CAPI_Util.c +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include +#include + +#include + +#if !defined(_WIN32) +#include +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1800 // MSVC < 2013 +#define round(dbl) \ + (dbl) >= 0.0 ? (int)((dbl) + 0.5) \ + : (((dbl) - (double)(int)(dbl)) <= -0.5 ? (int)(dbl) : (int)((dbl)-0.5)) +#endif + + +#if defined(_MSC_VER) +#include +#pragma intrinsic(_mm_pause) +#endif + +#if defined(_WIN32) +#include +#endif + +template +T ovrMax(T a, T b) { + return a > b ? a : b; +} +template +T ovrMin(T a, T b) { + return a < b ? a : b; +} + +// Used to generate projection from ovrEyeDesc::Fov +OVR_PUBLIC_FUNCTION(ovrMatrix4f) +ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, unsigned int projectionModFlags) { + bool leftHanded = (projectionModFlags & ovrProjection_LeftHanded) > 0; + bool flipZ = (projectionModFlags & ovrProjection_FarLessThanNear) > 0; + bool farAtInfinity = (projectionModFlags & ovrProjection_FarClipAtInfinity) > 0; + bool isOpenGL = (projectionModFlags & ovrProjection_ClipRangeOpenGL) > 0; + + // TODO: Pass in correct eye to CreateProjection if we want to support canted displays from CAPI + return OVR::CreateProjection( + leftHanded, isOpenGL, fov, OVR::StereoEye_Center, znear, zfar, flipZ, farAtInfinity); +} + +OVR_PUBLIC_FUNCTION(ovrTimewarpProjectionDesc) +ovrTimewarpProjectionDesc_FromProjection(ovrMatrix4f Projection, unsigned int projectionModFlags) { + ovrTimewarpProjectionDesc res; + res.Projection22 = Projection.M[2][2]; + res.Projection23 = Projection.M[2][3]; + res.Projection32 = Projection.M[3][2]; + + if ((res.Projection32 != 1.0f) && (res.Projection32 != -1.0f)) { + // This is a very strange projection matrix, and probably won't work. + // If you need it to work, please contact Oculus and let us know your usage scenario. + } + + if ((projectionModFlags & ovrProjection_ClipRangeOpenGL) != 0) { + // Internally we use the D3D range of [0,+w] not the OGL one of [-w,+w], so we need to convert + // one to the other. + // Note that the values in the depth buffer, and the actual linear depth we want is the same for + // both APIs, + // the difference is purely in the values inside the projection matrix. + + // D3D does this: + // depthBuffer = ( ProjD3D.M[2][2] * linearDepth + ProjD3D.M[2][3] ) / ( linearDepth + // * ProjD3D.M[3][2] ); + // OGL does this: + // depthBuffer = 0.5 + 0.5 * ( ProjOGL.M[2][2] * linearDepth + ProjOGL.M[2][3] ) / ( linearDepth + // * ProjOGL.M[3][2] ); + + // Therefore: + // ProjD3D.M[2][2] = 0.5 * ( ProjOGL.M[2][2] + ProjOGL.M[3][2] ); + // ProjD3D.M[2][3] = 0.5 * ProjOGL.M[2][3]; + // ProjD3D.M[3][2] = ProjOGL.M[3][2]; + + res.Projection22 = 0.5f * (Projection.M[2][2] + Projection.M[3][2]); + res.Projection23 = 0.5f * Projection.M[2][3]; + res.Projection32 = Projection.M[3][2]; + } + return res; +} + +OVR_PUBLIC_FUNCTION(ovrMatrix4f) +ovrMatrix4f_OrthoSubProjection( + ovrMatrix4f projection, + ovrVector2f orthoScale, + float orthoDistance, + float hmdToEyeOffsetX) { + ovrMatrix4f ortho; + // Negative sign is correct! + // If the eye is offset to the left, then the ortho view needs to be offset to the right relative + // to the camera. + float orthoHorizontalOffset = -hmdToEyeOffsetX / orthoDistance; + + // Current projection maps real-world vector (x,y,1) to the RT. + // We want to find the projection that maps the range [-FovPixels/2,FovPixels/2] to + // the physical [-orthoHalfFov,orthoHalfFov] + // Note moving the offset from M[0][2]+M[1][2] to M[0][3]+M[1][3] - this means + // we don't have to feed in Z=1 all the time. + // The horizontal offset math is a little hinky because the destination is + // actually [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset] + // So we need to first map [-FovPixels/2,FovPixels/2] to + // [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset]: + // x1 = x0 * orthoHalfFov/(FovPixels/2) + orthoHorizontalOffset; + // = x0 * 2*orthoHalfFov/FovPixels + orthoHorizontalOffset; + // But then we need the same mapping as the existing projection matrix, i.e. + // x2 = x1 * Projection.M[0][0] + Projection.M[0][2]; + // = x0 * (2*orthoHalfFov/FovPixels + orthoHorizontalOffset) * Projection.M[0][0] + + // Projection.M[0][2]; = x0 * Projection.M[0][0]*2*orthoHalfFov/FovPixels + + // orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]; + // So in the new projection matrix we need to scale by Projection.M[0][0]*2*orthoHalfFov/FovPixels + // and offset by orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]. + + ortho.M[0][0] = projection.M[0][0] * orthoScale.x; + ortho.M[0][1] = 0.0f; + ortho.M[0][2] = 0.0f; + ortho.M[0][3] = -projection.M[0][2] + (orthoHorizontalOffset * projection.M[0][0]); + + ortho.M[1][0] = 0.0f; + ortho.M[1][1] = + -projection.M[1][1] * orthoScale.y; /* Note sign flip (text rendering uses Y=down). */ + ortho.M[1][2] = 0.0f; + ortho.M[1][3] = -projection.M[1][2]; + + ortho.M[2][0] = 0.0f; + ortho.M[2][1] = 0.0f; + ortho.M[2][2] = 0.0f; + ortho.M[2][3] = 0.0f; + + /* No perspective correction for ortho. */ + ortho.M[3][0] = 0.0f; + ortho.M[3][1] = 0.0f; + ortho.M[3][2] = 0.0f; + ortho.M[3][3] = 1.0f; + + return ortho; +} + +#undef ovr_CalcEyePoses +OVR_PUBLIC_FUNCTION(void) +ovr_CalcEyePoses(ovrPosef headPose, const ovrVector3f hmdToEyeOffset[2], ovrPosef outEyePoses[2]) { + if (!hmdToEyeOffset || !outEyePoses) { + return; + } + + using OVR::Posef; + using OVR::Vector3f; + + // Currently hmdToEyeOffset is only a 3D vector + outEyePoses[0] = + Posef(headPose.Orientation, ((Posef)headPose).Apply((Vector3f)hmdToEyeOffset[0])); + outEyePoses[1] = + Posef(headPose.Orientation, ((Posef)headPose).Apply((Vector3f)hmdToEyeOffset[1])); +} + +OVR_PRIVATE_FUNCTION(void) +ovr_CalcEyePoses2(ovrPosef headPose, const ovrPosef hmdToEyePose[2], ovrPosef outEyePoses[2]) { + if (!hmdToEyePose || !outEyePoses) { + return; + } + + using OVR::Posef; + using OVR::Vector3f; + + outEyePoses[0] = (Posef)headPose * (Posef)hmdToEyePose[0]; + outEyePoses[1] = (Posef)headPose * (Posef)hmdToEyePose[1]; +} + +#undef ovr_GetEyePoses +OVR_PUBLIC_FUNCTION(void) +ovr_GetEyePoses( + ovrSession session, + long long frameIndex, + ovrBool latencyMarker, + const ovrVector3f hmdToEyeOffset[2], + ovrPosef outEyePoses[2], + double* outSensorSampleTime) { + double frameTime = ovr_GetPredictedDisplayTime(session, frameIndex); + ovrTrackingState trackingState = ovr_GetTrackingState(session, frameTime, latencyMarker); + ovr_CalcEyePoses(trackingState.HeadPose.ThePose, hmdToEyeOffset, outEyePoses); + + if (outSensorSampleTime != nullptr) { + *outSensorSampleTime = ovr_GetTimeInSeconds(); + } +} + +OVR_PRIVATE_FUNCTION(void) +ovr_GetEyePoses2( + ovrSession session, + long long frameIndex, + ovrBool latencyMarker, + const ovrPosef hmdToEyePose[2], + ovrPosef outEyePoses[2], + double* outSensorSampleTime) { + double frameTime = ovr_GetPredictedDisplayTime(session, frameIndex); + ovrTrackingState trackingState = ovr_GetTrackingState(session, frameTime, latencyMarker); + ovr_CalcEyePoses2(trackingState.HeadPose.ThePose, hmdToEyePose, outEyePoses); + + if (outSensorSampleTime != nullptr) { + *outSensorSampleTime = ovr_GetTimeInSeconds(); + } +} + +OVR_PUBLIC_FUNCTION(ovrDetectResult) ovr_Detect(int timeoutMilliseconds) { + // Initially we assume everything is not running. + ovrDetectResult result; + result.IsOculusHMDConnected = ovrFalse; + result.IsOculusServiceRunning = ovrFalse; + +#if defined(_WIN32) + // Attempt to open the named event. + HANDLE hServiceEvent = ::OpenEventW(SYNCHRONIZE, FALSE, OVR_HMD_CONNECTED_EVENT_NAME); + + // If event exists, + if (hServiceEvent != nullptr) { + // This indicates that the Oculus Runtime is installed and running. + result.IsOculusServiceRunning = ovrTrue; + + // Poll for event state. + DWORD objectResult = ::WaitForSingleObject(hServiceEvent, timeoutMilliseconds); + + // If the event is signaled, + if (objectResult == WAIT_OBJECT_0) { + // This indicates that the Oculus HMD is connected. + result.IsOculusHMDConnected = ovrTrue; + } + + ::CloseHandle(hServiceEvent); + } +#else + (void)timeoutMilliseconds; + fprintf(stderr, __FILE__ "::[%s] Not implemented. Assuming single-process.\n", __func__); + result.IsOculusServiceRunning = ovrTrue; + result.IsOculusHMDConnected = ovrTrue; +#endif // OSX_UNIMPLEMENTED + + return result; +} + +OVR_PUBLIC_FUNCTION(void) ovrPosef_FlipHandedness(const ovrPosef* inPose, ovrPosef* outPose) { + outPose->Orientation.x = -inPose->Orientation.x; + outPose->Orientation.y = inPose->Orientation.y; + outPose->Orientation.z = inPose->Orientation.z; + outPose->Orientation.w = -inPose->Orientation.w; + + outPose->Position.x = -inPose->Position.x; + outPose->Position.y = inPose->Position.y; + outPose->Position.z = inPose->Position.z; +} + +static float wavPcmBytesToFloat(const void* data, int32_t sizeInBits, bool swapBytes) { + // TODO Support big endian + (void)swapBytes; + + // There's not a strong standard to convert 8/16/32b PCM to float. + // For 16b: MSDN says range is [-32760, 32760], Pyton Scipy uses [-32767, 32767] and Audacity + // outputs the full range [-32768, 32767]. + // We use the same range on both sides and clamp to [-1, 1]. + + float result = 0.0f; + if (sizeInBits == 8) + // uint8_t is a special case, unsigned where 128 is zero + result = (*((uint8_t*)data) / (float)UCHAR_MAX) * 2.0f - 1.0f; + else if (sizeInBits == 16) + result = *((int16_t*)data) / (float)SHRT_MAX; + // else if (sizeInBits == 24) { + // int value = data[0] | data[1] << 8 | data[2] << 16; // Need consider 2's complement + // return value / 8388607.0f; + //} + else if (sizeInBits == 32) + result = *((int32_t*)data) / (float)INT_MAX; + + return ovrMax(-1.0f, result); +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_GenHapticsFromAudioData( + ovrHapticsClip* outHapticsClip, + const ovrAudioChannelData* audioChannel, + ovrHapticsGenMode genMode) { + if (!outHapticsClip || !audioChannel || genMode != ovrHapticsGenMode_PointSample) + return ovrError_InvalidParameter; + // Validate audio channel + if (audioChannel->Frequency <= 0 || audioChannel->SamplesCount <= 0 || + audioChannel->Samples == nullptr) + return ovrError_InvalidParameter; + + const int32_t kHapticsFrequency = 320; + const int32_t kHapticsMaxAmplitude = 255; + float samplesPerStep = audioChannel->Frequency / (float)kHapticsFrequency; + int32_t hapticsSampleCount = (int32_t)ceil(audioChannel->SamplesCount / samplesPerStep); + + uint8_t* hapticsSamples = new uint8_t[hapticsSampleCount]; + for (int32_t i = 0; i < hapticsSampleCount; ++i) { + float sample = audioChannel->Samples[(int32_t)(i * samplesPerStep)]; + uint8_t hapticSample = + (uint8_t)ovrMin(UCHAR_MAX, (int)round(fabs(sample) * kHapticsMaxAmplitude)); + hapticsSamples[i] = hapticSample; + } + + outHapticsClip->Samples = hapticsSamples; + outHapticsClip->SamplesCount = hapticsSampleCount; + + return ovrSuccess; +} + +OVR_PUBLIC_FUNCTION(ovrResult) +ovr_ReadWavFromBuffer( + ovrAudioChannelData* outAudioChannel, + const void* inputData, + int dataSizeInBytes, + int stereoChannelToUse) { + // We don't support any format other than PCM and IEEE Float + enum WavFormats { + kWavFormatUnknown = 0x0000, + kWavFormatLPCM = 0x0001, + kWavFormatFloatIEEE = 0x0003, + kWavFormatExtensible = 0xFFFE + }; + + struct WavHeader { + char RiffId[4]; // "RIFF" = little-endian, "RIFX" = big-endian + int32_t Size; // 4 + (8 + FmtChunkSize) + (8 + DataChunkSize) + char WavId[4]; // Must be "WAVE" + + char FmtChunckId[4]; // Must be "fmt " + uint32_t FmtChunkSize; // Remaining size of this chunk (16B) + uint16_t Format; // WavFormats: PCM or Float supported + uint16_t Channels; // 1 = Mono, 2 = Stereo + uint32_t SampleRate; // e.g. 44100 + uint32_t BytesPerSec; // SampleRate * BytesPerBlock + uint16_t BytesPerBlock; // (NumChannels * BitsPerSample/8) + uint16_t BitsPerSample; // 8, 16, 32 + + char DataChunckId[4]; // Must be "data" + uint32_t DataChunkSize; // Remaining size of this chunk + }; + + const int32_t kMinWavFileSize = sizeof(WavHeader) + 1; + if (!outAudioChannel || !inputData || dataSizeInBytes < kMinWavFileSize) + return ovrError_InvalidParameter; + + WavHeader* header = (WavHeader*)inputData; + uint8_t* data = (uint8_t*)inputData + sizeof(WavHeader); + + // Validate + const char* wavId = header->RiffId; + // TODO We need to support RIFX when supporting big endian formats + // bool isValidWav = (wavId[0] == 'R' && wavId[1] == 'I' && wavId[2] == 'F' && (wavId[3] == 'F' || + // wavId[3] == 'X')) && + bool isValidWav = (wavId[0] == 'R' && wavId[1] == 'I' && wavId[2] == 'F' && wavId[3] == 'F') && + memcmp(header->WavId, "WAVE", 4) == 0; + bool hasValidChunks = + memcmp(header->FmtChunckId, "fmt ", 4) == 0 && memcmp(header->DataChunckId, "data ", 4) == 0; + if (!isValidWav || !hasValidChunks) { + return ovrError_InvalidOperation; + } + + // We only support PCM + bool isSupported = (header->Format == kWavFormatLPCM || header->Format == kWavFormatFloatIEEE) && + (header->Channels == 1 || header->Channels == 2) && + (header->BitsPerSample == 8 || header->BitsPerSample == 16 || header->BitsPerSample == 32); + if (!isSupported) { + return ovrError_Unsupported; + } + + // Channel selection + bool useSecondChannel = (header->Channels == 2 && stereoChannelToUse == 1); + int32_t channelOffset = (useSecondChannel) ? header->BytesPerBlock / 2 : 0; + + // TODO Support big-endian + int32_t blockCount = header->DataChunkSize / header->BytesPerBlock; + float* samples = new float[blockCount]; + + for (int32_t i = 0; i < blockCount; i++) { + int32_t dataIndex = i * header->BytesPerBlock; + uint8_t* dataPtr = &data[dataIndex + channelOffset]; + float sample = (header->Format == kWavFormatLPCM) + ? wavPcmBytesToFloat(dataPtr, header->BitsPerSample, false) + : *(float*)dataPtr; + + samples[i] = sample; + } + + // Output + outAudioChannel->Samples = samples; + outAudioChannel->SamplesCount = blockCount; + outAudioChannel->Frequency = header->SampleRate; + + return ovrSuccess; +} + +OVR_PUBLIC_FUNCTION(void) ovr_ReleaseAudioChannelData(ovrAudioChannelData* audioChannel) { + if (audioChannel != nullptr && audioChannel->Samples != nullptr) { + delete[] audioChannel->Samples; + memset(audioChannel, 0, sizeof(ovrAudioChannelData)); + } +} + +OVR_PUBLIC_FUNCTION(void) ovr_ReleaseHapticsClip(ovrHapticsClip* hapticsClip) { + if (hapticsClip != nullptr && hapticsClip->Samples != nullptr) { + delete[](uint8_t*) hapticsClip->Samples; + memset(hapticsClip, 0, sizeof(ovrHapticsClip)); + } +} diff --git a/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_StereoProjection.cpp b/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_StereoProjection.cpp new file mode 100644 index 0000000..53afe3e --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_StereoProjection.cpp @@ -0,0 +1,202 @@ +/************************************************************************************ + +Filename : OVR_StereoProjection.cpp +Content : Stereo rendering functions +Created : November 30, 2013 +Authors : Tom Fosyth + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include + +namespace OVR { + +Matrix4f CreateProjection( + bool leftHanded, + bool isOpenGL, + FovPort tanHalfFov, + StereoEye /*eye*/, + float zNear /*= 0.01f*/, + float zFar /*= 10000.0f*/, + bool flipZ /*= false*/, + bool farAtInfinity /*= false*/) { + if (!flipZ && farAtInfinity) { + // OVR_ASSERT_M(false, "Cannot push Far Clip to Infinity when Z-order is not flipped"); + // Assertion disabled because this code no longer has access to LibOVRKernel assertion + // functionality. + farAtInfinity = false; + } + + // A projection matrix is very like a scaling from NDC, so we can start with that. + ScaleAndOffset2D scaleAndOffset = FovPort::CreateNDCScaleAndOffsetFromFov(tanHalfFov); + + float handednessScale = leftHanded ? 1.0f : -1.0f; + + Matrix4f projection; + // Produces X result, mapping clip edges to [-w,+w] + projection.M[0][0] = scaleAndOffset.Scale.x; + projection.M[0][1] = 0.0f; + projection.M[0][2] = handednessScale * scaleAndOffset.Offset.x; + projection.M[0][3] = 0.0f; + + // Produces Y result, mapping clip edges to [-w,+w] + // Hey - why is that YOffset negated? + // It's because a projection matrix transforms from world coords with Y=up, + // whereas this is derived from an NDC scaling, which is Y=down. + projection.M[1][0] = 0.0f; + projection.M[1][1] = scaleAndOffset.Scale.y; + projection.M[1][2] = handednessScale * -scaleAndOffset.Offset.y; + projection.M[1][3] = 0.0f; + + // Produces Z-buffer result - app needs to fill this in with whatever Z range it wants. + // We'll just use some defaults for now. + projection.M[2][0] = 0.0f; + projection.M[2][1] = 0.0f; + + if (farAtInfinity) { + if (isOpenGL) { + // It's not clear this makes sense for OpenGL - you don't get the same precision benefits you + // do in D3D. + projection.M[2][2] = -handednessScale; + projection.M[2][3] = 2.0f * zNear; + } else { + projection.M[2][2] = 0.0f; + projection.M[2][3] = zNear; + } + } else { + if (isOpenGL) { + // Clip range is [-w,+w], so 0 is at the middle of the range. + projection.M[2][2] = + -handednessScale * (flipZ ? -1.0f : 1.0f) * (zNear + zFar) / (zNear - zFar); + projection.M[2][3] = 2.0f * ((flipZ ? -zFar : zFar) * zNear) / (zNear - zFar); + } else { + // Clip range is [0,+w], so 0 is at the start of the range. + projection.M[2][2] = -handednessScale * (flipZ ? -zNear : zFar) / (zNear - zFar); + projection.M[2][3] = ((flipZ ? -zFar : zFar) * zNear) / (zNear - zFar); + } + } + + // Produces W result (= Z in) + projection.M[3][0] = 0.0f; + projection.M[3][1] = 0.0f; + projection.M[3][2] = handednessScale; + projection.M[3][3] = 0.0f; + + return projection; +} + +Matrix4f CreateOrthoSubProjection( + bool /*rightHanded*/, + StereoEye eyeType, + float tanHalfFovX, + float tanHalfFovY, + float unitsX, + float unitsY, + float distanceFromCamera, + float interpupillaryDistance, + Matrix4f const& projection, + float zNear /*= 0.0f*/, + float zFar /*= 0.0f*/, + bool flipZ /*= false*/, + bool farAtInfinity /*= false*/) { + if (!flipZ && farAtInfinity) { + // OVR_ASSERT_M(false, "Cannot push Far Clip to Infinity when Z-order is not flipped"); + // Assertion disabled because this code no longer has access to LibOVRKernel assertion + // functionality. + farAtInfinity = false; + } + + float orthoHorizontalOffset = interpupillaryDistance * 0.5f / distanceFromCamera; + switch (eyeType) { + case StereoEye_Left: + break; + case StereoEye_Right: + orthoHorizontalOffset = -orthoHorizontalOffset; + break; + case StereoEye_Center: + orthoHorizontalOffset = 0.0f; + break; + default: + break; + } + + // Current projection maps real-world vector (x,y,1) to the RT. + // We want to find the projection that maps the range [-FovPixels/2,FovPixels/2] to + // the physical [-orthoHalfFov,orthoHalfFov] + // Note moving the offset from M[0][2]+M[1][2] to M[0][3]+M[1][3] - this means + // we don't have to feed in Z=1 all the time. + // The horizontal offset math is a little hinky because the destination is + // actually [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset] + // So we need to first map [-FovPixels/2,FovPixels/2] to + // [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset]: + // x1 = x0 * orthoHalfFov/(FovPixels/2) + orthoHorizontalOffset; + // = x0 * 2*orthoHalfFov/FovPixels + orthoHorizontalOffset; + // But then we need the sam mapping as the existing projection matrix, i.e. + // x2 = x1 * Projection.M[0][0] + Projection.M[0][2]; + // = x0 * (2*orthoHalfFov/FovPixels + orthoHorizontalOffset) * Projection.M[0][0] + + // Projection.M[0][2]; + // = x0 * Projection.M[0][0]*2*orthoHalfFov/FovPixels + + // orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]; + // So in the new projection matrix we need to scale by Projection.M[0][0]*2*orthoHalfFov/FovPixels + // and + // offset by orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]. + + float orthoScaleX = 2.0f * tanHalfFovX / unitsX; + float orthoScaleY = 2.0f * tanHalfFovY / unitsY; + Matrix4f ortho; + ortho.M[0][0] = projection.M[0][0] * orthoScaleX; + ortho.M[0][1] = 0.0f; + ortho.M[0][2] = 0.0f; + ortho.M[0][3] = -projection.M[0][2] + (orthoHorizontalOffset * projection.M[0][0]); + + ortho.M[1][0] = 0.0f; + ortho.M[1][1] = -projection.M[1][1] * orthoScaleY; // Note sign flip (text rendering uses Y=down). + ortho.M[1][2] = 0.0f; + ortho.M[1][3] = -projection.M[1][2]; + + const float zDiff = zNear - zFar; + if (fabsf(zDiff) < 0.001f) { + ortho.M[2][0] = 0.0f; + ortho.M[2][1] = 0.0f; + ortho.M[2][2] = 0.0f; + ortho.M[2][3] = flipZ ? zNear : zFar; + } else { + ortho.M[2][0] = 0.0f; + ortho.M[2][1] = 0.0f; + + if (farAtInfinity) { + ortho.M[2][2] = 0.0f; + ortho.M[2][3] = zNear; + } else if (zDiff != 0.0f) { + ortho.M[2][2] = (flipZ ? zNear : zFar) / zDiff; + ortho.M[2][3] = ((flipZ ? -zFar : zFar) * zNear) / zDiff; + } + } + + // No perspective correction for ortho. + ortho.M[3][0] = 0.0f; + ortho.M[3][1] = 0.0f; + ortho.M[3][2] = 0.0f; + ortho.M[3][3] = 1.0f; + + return ortho; +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2015/LibOVRKernel.vcxproj b/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2015/LibOVRKernel.vcxproj new file mode 100644 index 0000000..cbdbbe3 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2015/LibOVRKernel.vcxproj @@ -0,0 +1,1386 @@ + + + + + Debug (DLL CRT) + Win32 + + + Debug (DLL CRT) + x64 + + + DebugSingleProcess + Win32 + + + DebugSingleProcess + x64 + + + DebugStatic + Win32 + + + DebugStatic + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release (DLL CRT) + Win32 + + + Release (DLL CRT) + x64 + + + ReleaseSingleProcess + Win32 + + + ReleaseSingleProcess + x64 + + + ReleaseStatic + Win32 + + + ReleaseStatic + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + %(Filename) + %(RelativeDir)%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + + + + + %(Filename) + %(Filename) + %(Filename) + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + + + + + %(Filename) + %(RelativeDir)%(Filename).h + + + %(Filename) + %(RelativeDir)%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + + + + + %(Filename) + %(Filename) + %(Filename) + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + + + + + %(Filename) + %(RelativeDir)%(Filename).h + + + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + + + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + + + %(Filename) + %(RelativeDir)%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + + + + + %(Filename) + %(Filename) + %(Filename) + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + + + + + %(Filename) + %(RelativeDir)%(Filename).h + + + %(Filename) + %(RelativeDir)%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + + + + + %(Filename) + %(Filename) + %(Filename) + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + + + + + %(Filename) + %(RelativeDir)%(Filename).h + + + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + + + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(RelativeDir)%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + + + + + + + + + + + + + + + + + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + + + + {29FA0962-DDC6-4F72-9D12-E150DF29E279} + Win32Proj + LibOVR + LibOVRKernel + + + + StaticLibrary + true + MultiByte + v140 + + + StaticLibrary + true + MultiByte + v140 + + + StaticLibrary + true + MultiByte + v140 + + + StaticLibrary + true + MultiByte + v140 + + + StaticLibrary + true + MultiByte + v140 + + + StaticLibrary + true + MultiByte + v140 + + + StaticLibrary + true + MultiByte + v140 + + + StaticLibrary + true + MultiByte + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + StaticLibrary + false + true + Unicode + v140 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + LibOVRKernel + + + LibOVRKernel + + + LibOVRKernel + + + LibOVRKernel + + + LibOVRKernel + AllRules.ruleset + false + + + LibOVRKernel + AllRules.ruleset + false + + + LibOVRKernel + AllRules.ruleset + false + + + LibOVRKernel + AllRules.ruleset + false + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Lib/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + $(ProjectDir)../../../Obj/$(ProjectName)/Windows/$(Platform)/$(Configuration)/VS2015/ + + + LibOVRKernel + + + LibOVRKernel + + + LibOVRKernel + + + LibOVRKernel + + + LibOVRKernel + + + LibOVRKernel + + + LibOVRKernel + + + LibOVRKernel + + + + + + Level4 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions); + OldStyle + true + false + true + MultiThreadedDebug + true + SyncCThrow + true + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + + + Windows + true + + + + %(AdditionalDependencies) + + + + + + + Level4 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions); + OldStyle + true + false + true + MultiThreadedDebug + true + SyncCThrow + true + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + + + Windows + true + + + + %(AdditionalDependencies) + + + + + + + Level4 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions); + OldStyle + true + false + true + MultiThreadedDebugDLL + true + SyncCThrow + true + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + + + Windows + true + + + + %(AdditionalDependencies) + + + + + + + Level4 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions); + OldStyle + true + false + true + MultiThreadedDebug + true + SyncCThrow + true + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + + + Windows + true + + + + %(AdditionalDependencies) + + + + + + + Level4 + Disabled + _WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions); + OldStyle + true + false + true + MultiThreadedDebug + false + false + true + SyncCThrow + true + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + + + Windows + true + + + + %(AdditionalDependencies) + + + + + + + Level4 + Disabled + _WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions); + OldStyle + true + false + true + MultiThreadedDebug + false + false + true + SyncCThrow + true + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + + + Windows + true + + + + %(AdditionalDependencies) + + + + + + + Level4 + Disabled + _WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions); + OldStyle + true + false + true + MultiThreadedDebugDLL + false + false + true + SyncCThrow + true + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + + + Windows + true + + + + %(AdditionalDependencies) + + + + + + + Level4 + Disabled + _WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions); + OldStyle + true + false + true + MultiThreadedDebug + false + false + true + SyncCThrow + true + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + + + Windows + true + + + + %(AdditionalDependencies) + + + + + Level4 + + + Full + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions); + MultiThreaded + true + true + OldStyle + false + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + true + false + SyncCThrow + StreamingSIMDExtensions2 + true + AnySuitable + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + %(AdditionalDependencies) + + + + + Level4 + + + Full + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions); + MultiThreaded + true + true + OldStyle + false + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + true + false + SyncCThrow + StreamingSIMDExtensions2 + true + AnySuitable + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + %(AdditionalDependencies) + + + + + Level4 + + + Full + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions); + MultiThreadedDLL + true + true + OldStyle + false + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + true + false + SyncCThrow + StreamingSIMDExtensions2 + true + AnySuitable + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + %(AdditionalDependencies) + + + + + Level4 + + + Full + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions); + MultiThreaded + true + true + OldStyle + false + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + true + false + SyncCThrow + StreamingSIMDExtensions2 + true + AnySuitable + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + %(AdditionalDependencies) + + + + + Level4 + + + Full + true + true + _WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions); + MultiThreaded + true + true + OldStyle + false + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + true + false + SyncCThrow + NotSet + true + AnySuitable + false + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + %(AdditionalDependencies) + + + + + Level4 + + + Full + true + true + _WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions); + MultiThreaded + true + true + OldStyle + false + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + true + false + SyncCThrow + NotSet + true + AnySuitable + false + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + %(AdditionalDependencies) + + + + + Level4 + + + Full + true + true + _WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions); + MultiThreadedDLL + true + true + OldStyle + false + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + true + false + SyncCThrow + NotSet + true + AnySuitable + false + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + %(AdditionalDependencies) + + + + + Level4 + + + Full + true + true + _WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions); + MultiThreaded + true + true + OldStyle + false + /d2Zi+ /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + true + false + SyncCThrow + NotSet + true + AnySuitable + false + false + $(OVRSDKROOT)LibOVRKernel/Src/;$(OVRSDKROOT)Logging/;$(OVRSDKROOT)LibOVR/Include/;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + %(AdditionalDependencies) + + + + + + diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2015/LibOVRKernel.vcxproj.filters b/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2015/LibOVRKernel.vcxproj.filters new file mode 100644 index 0000000..101ff30 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2015/LibOVRKernel.vcxproj.filters @@ -0,0 +1,292 @@ + + + + + {cbd5aacf-597b-4418-bb2d-5cc31c56d320} + + + {9c8f8b78-8c98-4daa-a0be-885ce14ec526} + + + {adfe2ad5-b3f5-4afd-98da-b3ca76652ced} + + + {af8a116e-e692-4597-ba74-77fd10a5276c} + + + {fc456049-35b9-44d7-b53d-a761c67053e8} + + + {bc903fcf-621a-4443-a5a9-31c194309543} + + + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + GL + + + GL + + + Util + + + Util + + + Util + + + Util + + + Util + + + Util + + + Kernel + + + Kernel + + + Kernel + + + Tracing + + + Tracing + + + Util + + + Util + + + Kernel + + + + + + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + GL + + + Util + + + Util + + + Util + + + Util + + + Util + + + Util + + + Kernel + + + Util + + + Util + + + Logging + + + Logging + + + Logging + + + Kernel + + + + + Tracing + + + Tracing + + + Kernel + + + + + Util\Shaders + + + Util\Shaders + + + Util\Shaders + + + Util\Shaders + + + diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel.vcxproj b/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel.vcxproj new file mode 100644 index 0000000..6fb59bf --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel.vcxproj @@ -0,0 +1,784 @@ + + + + + Debug (DLL CRT) + Win32 + + + Debug (DLL CRT) + x64 + + + DebugSingleProcess + Win32 + + + DebugSingleProcess + x64 + + + DebugStatic + Win32 + + + DebugStatic + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release (DLL CRT) + Win32 + + + Release (DLL CRT) + x64 + + + ReleaseSingleProcess + Win32 + + + ReleaseSingleProcess + x64 + + + ReleaseStatic + Win32 + + + ReleaseStatic + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + %(Filename) + $(GenDir)Shaders/%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + + + + + + + %(Filename) + %(Filename) + %(Filename) + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + + + + + + + %(Filename) + $(GenDir)Shaders/%(Filename).h + + + %(Filename) + $(GenDir)Shaders/%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + + + + + + + %(Filename) + %(Filename) + %(Filename) + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + + + + + + + %(Filename) + $(GenDir)Shaders/%(Filename).h + + + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + + + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + $(GenDir)Shaders/%(Filename).h + + + $(GenDir)Shaders/%(Filename).h + + + $(GenDir)Shaders/%(Filename).h + + + $(GenDir)Shaders/%(Filename).h + + + $(GenDir)Shaders/%(Filename).h + + + $(GenDir)Shaders/%(Filename).h + + + $(GenDir)Shaders/%(Filename).h + + + $(GenDir)Shaders/%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + 5.0 + + + %(Filename) + $(GenDir)Shaders/%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + + + + + + + %(Filename) + %(Filename) + %(Filename) + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + + + + + + + %(Filename) + $(GenDir)Shaders/%(Filename).h + + + %(Filename) + $(GenDir)Shaders/%(Filename).h + + + %(Filename) + %(Filename) + %(Filename) + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + + + + + + + %(Filename) + %(Filename) + %(Filename) + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + + + + + + + %(Filename) + $(GenDir)Shaders/%(Filename).h + + + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + + + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + 4.0 + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + %(Filename) + + + %(Filename) + + + %(Filename) + + + %(Filename) + + + %(Filename) + + + %(Filename) + + + %(Filename) + + + %(Filename) + + + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + $(GenDir)Shaders/%(Filename).h + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + %(Filename) + + + + + + + + + + + + + + + + + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + + + + {29FA0962-DDC6-4F72-9D12-E150DF29E279} + Win32Proj + LibOVR + LibOVRKernel + 8.1 + + + + StaticLibrary + true + MultiByte + v141 + + + StaticLibrary + true + MultiByte + v141 + + + StaticLibrary + true + MultiByte + v141 + + + StaticLibrary + true + MultiByte + v141 + + + StaticLibrary + true + MultiByte + v141 + + + StaticLibrary + true + MultiByte + v141 + + + StaticLibrary + true + MultiByte + v141 + + + StaticLibrary + true + MultiByte + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + StaticLibrary + false + true + Unicode + v141 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MultiThreadedDebug + + + + + MultiThreadedDebug + + + + + MultiThreadedDebugDLL + + + + + MultiThreadedDebug + + + + + MultiThreadedDebug + + + + + MultiThreadedDebug + + + + + MultiThreadedDebugDLL + + + + + MultiThreadedDebug + + + + + MultiThreaded + + + + + MultiThreaded + + + + + MultiThreadedDLL + + + + + MultiThreaded + + + + + MultiThreaded + + + + + MultiThreaded + + + + + MultiThreadedDLL + + + + + MultiThreaded + + + + + + diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel.vcxproj.filters b/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel.vcxproj.filters new file mode 100644 index 0000000..a6c993b --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel.vcxproj.filters @@ -0,0 +1,279 @@ + + + + + {cbd5aacf-597b-4418-bb2d-5cc31c56d320} + + + {9c8f8b78-8c98-4daa-a0be-885ce14ec526} + + + {adfe2ad5-b3f5-4afd-98da-b3ca76652ced} + + + {af8a116e-e692-4597-ba74-77fd10a5276c} + + + {fc456049-35b9-44d7-b53d-a761c67053e8} + + + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + GL + + + GL + + + Util + + + Util + + + Util + + + Util + + + Util + + + Util + + + Kernel + + + Kernel + + + Kernel + + + Tracing + + + Tracing + + + Util + + + Util + + + Kernel + + + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + Kernel + + + GL + + + Util + + + Util + + + Util + + + Util + + + Util + + + Util + + + Kernel + + + Util + + + Util + + + Kernel + + + + + Tracing + + + Tracing + + + Kernel + + + + + + + Util\Shaders + + + Util\Shaders + + + Util\Shaders + + + Util\Shaders + + + diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel_internal.props b/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel_internal.props new file mode 100644 index 0000000..dc8851f --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Projects/Windows/VS2017/LibOVRKernel_internal.props @@ -0,0 +1,17 @@ + + + + + $(GenDir);$(MSBuildThisFileDirectory)/../../../Src;$(MSBuildThisFileDirectory)/../../../../LibOVR/include;%(AdditionalIncludeDirectories) + /we4263 /we4264 /we4265 /we4266 /we4062 %(AdditionalOptions) + true + _LIB;%(PreprocessorDefinitions) + false + true + Level4 + + + + + + diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE.cpp new file mode 100644 index 0000000..e0445ea --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE.cpp @@ -0,0 +1,8935 @@ +/************************************************************************************ + +Filename : CAPI_GLE.cpp +Content : OpenGL Extensions support. Implements a stripped down glew-like + interface with some additional functionality. +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "CAPI_GLE.h" +#if defined(OVR_OS_WIN32) +#include "Kernel/OVR_Win32_IncludeWindows.h" +#endif // OVR_OS_WIN32 +#include +#include +#include +#include + +#if defined(_WIN32) +#pragma comment(lib, "opengl32.lib") +#elif defined(__APPLE__) +#include +#include +#include +#include +#endif + +#if defined(_MSC_VER) +#pragma warning(disable : 4996) // 'sscanf': This function or variable may be unsafe. +#endif + +// To do: redirect these log statements. +#define OVR_DEBUG_LOG(x) +#define LogText(x) + +// namespace OVR +//{ +// OVRTypeof +// Acts the same as the C++11 decltype expression, though with reduced requirements. +#if !defined(OVRTypeof) +#if defined(_MSC_VER) +#define OVRTypeof(x) decltype(x) // VS2010+ unilaterally supports decltype +#else +#define OVRTypeof(x) \ + __typeof__(x) // Other compilers support decltype, but usually not unless C++11 support is present +// and explicitly enabled. +#endif +#endif + +// GLELoadProc +// Macro which implements dynamically looking up and assigning an OpenGL function. +// +// Example usage: +// GLELoadProc(glCopyTexSubImage3D, glCopyTexSubImage3D); +// Expands to: +// gleCopyTexSubImage3D = (OVRTypeof(gleCopyTexSubImage3D)) +// GLEGetProcAddress("glCopyTexSubImage3D"); + +#define GLELoadProc(var, name) var = (OVRTypeof(var))GLEGetProcAddress(#name) + +// Disable some #defines, as we need to call these functions directly. +#if defined(GLE_HOOKING_ENABLED) +#if defined(_WIN32) +#undef wglGetProcAddress +extern "C" { +GLAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc); +} +#endif + +#undef glGetString +extern "C" { +GLAPI const GLubyte* GLAPIENTRY glGetString(GLenum name); +} +#endif + +// Suppress function pointer to object pointer cast error +// when compiling with clang. +#ifdef __clang__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmicrosoft-cast" +#endif +// Generic OpenGL GetProcAddress function interface. Maps to platform-specific functionality +// internally. On Windows this is equivalent to wglGetProcAddress as opposed to global +// GetProcAddress. +void* OVR::GLEGetProcAddress(const char* name) { +#if defined(_WIN32) + return wglGetProcAddress(name); +#ifdef __clang__ +#pragma GCC diagnostic pop +#endif + +#elif defined(__APPLE__) + // Requires the OS 10.3 SDK or later. + static void* dlImage = NULL; + void* addr = nullptr; + + if (!dlImage) + dlImage = + dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); + + if (dlImage) + addr = dlsym(dlImage, name); + + return addr; + +#elif defined(__ANDROID__) + return eglGetProcAddress(name); + +#else + // This was glXGetProcAddressARB in GLX versions prior to v1.4, but that was ten years ago. + return (void*)glXGetProcAddress((const GLubyte*)name); +#endif +} + +// Current context functionality +static OVR::GLEContext* GLECurrentContext = NULL; + +OVR::GLEContext* OVR::GLEContext::GetCurrentContext() { + return GLECurrentContext; +} + +void OVR::GLEContext::SetCurrentContext(OVR::GLEContext* p) { + GLECurrentContext = p; +} + +OVR::GLEContext::GLEContext() + : MajorVersion(0), + MinorVersion(0), + WholeVersion(0), + IsGLES(false), + IsCoreProfile(false), + EnableHookGetError(true), + PlatformMajorVersion(0), + PlatformMinorVersion(0), + PlatformWholeVersion(0) { + // The following sequence is not thread-safe. Two threads could set the context to this at the + // same time. + if (GetCurrentContext() == NULL) + SetCurrentContext(this); +} + +OVR::GLEContext::~GLEContext() { + if (GetCurrentContext() == this) + SetCurrentContext(NULL); +} + +void OVR::GLEContext::Init() { + PlatformInit(); + + if (!IsInitialized()) { + InitVersion(); + InitExtensionLoad(); + InitExtensionSupport(); + } +} + +bool OVR::GLEContext::IsInitialized() const { + return (MajorVersion != 0); +} + +void OVR::GLEContext::Shutdown() { + // This memset is valid only if this class has no virtual functions (similar to concept of POD). + // We cannot assert this because restrictions prevent us from using C++11 type traits here. + memset(this, 0, sizeof(GLEContext)); +} + +void OVR::GLEContext::PlatformInit() { + if (!IsPlatformInitialized()) { + InitPlatformExtensionLoad(); + InitPlatformExtensionSupport(); + InitPlatformVersion(); + } +} + +bool OVR::GLEContext::IsPlatformInitialized() const { + return (PlatformMajorVersion != 0); +} + +void OVR::GLEContext::InitVersion() { + const char* version = (const char*)glGetString(GL_VERSION); + int fields = 0, major = 0, minor = 0; + bool isGLES = false; + + assert(version); + if (version) { + OVR_DEBUG_LOG(("GL_VERSION: %s", (const char*)version)); + + // Skip all leading non-digits before reading %d. + // Example GL_VERSION strings: + // "1.5 ATI-1.4.18" + // "OpenGL ES-CM 3.2" + fields = sscanf(version, isdigit(*version) ? "%d.%d" : "%*[^0-9]%d.%d", &major, &minor); + isGLES = (strstr(version, "OpenGL ES") != NULL); + } else { + LogText("Warning: GL_VERSION was NULL\n"); + } + + // If two fields were not found, + if (fields != 2) { + static_assert(sizeof(major) == sizeof(GLint), "type mis-match"); + + glGetIntegerv(GL_MAJOR_VERSION, &major); + glGetIntegerv(GL_MINOR_VERSION, &minor); + } + + // Write version data + MajorVersion = major; + MinorVersion = minor; + WholeVersion = (major * 100) + minor; + + GLint profileMask = 0; + if (WholeVersion >= 302) { + // Older NVidia drivers have a bug with this on at least Windows. + // https://www.opengl.org/discussion_boards/showthread.php/171380-NVIDIA-drivers-not-returning-the-right-profile-mas + // A workaround could be to check for the GL_ARB_compatibility extension, which indicates if + // OpenGL is in compatibility mode, and if not then we are in core profile mode. On Apple + // another solution would be to use NSOpeNGLPixelFormat NSOpenGLView::pixelFormat to get the + // core profile attribute. + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profileMask); + } + IsCoreProfile = + (profileMask == + GL_CONTEXT_CORE_PROFILE_BIT); // There's also GL_CONTEXT_COMPATIBILITY_PROFILE_BIT + IsGLES = isGLES; +} + +void OVR::GLEContext::InitExtensionLoad() { + // GL_VERSION_1_1 + // We don't load these but rather link to them directly. + + // GL_VERSION_1_2 + GLELoadProc(glCopyTexSubImage3D_Impl, glCopyTexSubImage3D); // This expands to a get proc address + // call (e.g. wglGetProcAddress on + // Windows). + GLELoadProc(glDrawRangeElements_Impl, glDrawRangeElements); + GLELoadProc(glTexImage3D_Impl, glTexImage3D); + GLELoadProc(glTexSubImage3D_Impl, glTexSubImage3D); + + // GL_VERSION_1_3 + GLELoadProc(glActiveTexture_Impl, glActiveTexture); + GLELoadProc(glClientActiveTexture_Impl, glClientActiveTexture); + GLELoadProc(glCompressedTexImage1D_Impl, glCompressedTexImage1D); + GLELoadProc(glCompressedTexImage2D_Impl, glCompressedTexImage2D); + GLELoadProc(glCompressedTexImage3D_Impl, glCompressedTexImage3D); + GLELoadProc(glCompressedTexSubImage1D_Impl, glCompressedTexSubImage1D); + GLELoadProc(glCompressedTexSubImage2D_Impl, glCompressedTexSubImage2D); + GLELoadProc(glCompressedTexSubImage3D_Impl, glCompressedTexSubImage3D); + GLELoadProc(glGetCompressedTexImage_Impl, glGetCompressedTexImage); + GLELoadProc(glLoadTransposeMatrixd_Impl, glLoadTransposeMatrixd); + GLELoadProc(glLoadTransposeMatrixf_Impl, glLoadTransposeMatrixf); + GLELoadProc(glMultTransposeMatrixd_Impl, glMultTransposeMatrixd); + GLELoadProc(glMultTransposeMatrixf_Impl, glMultTransposeMatrixf); + GLELoadProc(glMultiTexCoord1d_Impl, glMultiTexCoord1d); + GLELoadProc(glMultiTexCoord1dv_Impl, glMultiTexCoord1dv); + GLELoadProc(glMultiTexCoord1f_Impl, glMultiTexCoord1f); + GLELoadProc(glMultiTexCoord1fv_Impl, glMultiTexCoord1fv); + GLELoadProc(glMultiTexCoord1i_Impl, glMultiTexCoord1i); + GLELoadProc(glMultiTexCoord1iv_Impl, glMultiTexCoord1iv); + GLELoadProc(glMultiTexCoord1s_Impl, glMultiTexCoord1s); + GLELoadProc(glMultiTexCoord1sv_Impl, glMultiTexCoord1sv); + GLELoadProc(glMultiTexCoord2d_Impl, glMultiTexCoord2d); + GLELoadProc(glMultiTexCoord2dv_Impl, glMultiTexCoord2dv); + GLELoadProc(glMultiTexCoord2f_Impl, glMultiTexCoord2f); + GLELoadProc(glMultiTexCoord2fv_Impl, glMultiTexCoord2fv); + GLELoadProc(glMultiTexCoord2i_Impl, glMultiTexCoord2i); + GLELoadProc(glMultiTexCoord2iv_Impl, glMultiTexCoord2iv); + GLELoadProc(glMultiTexCoord2s_Impl, glMultiTexCoord2s); + GLELoadProc(glMultiTexCoord2sv_Impl, glMultiTexCoord2sv); + GLELoadProc(glMultiTexCoord3d_Impl, glMultiTexCoord3d); + GLELoadProc(glMultiTexCoord3dv_Impl, glMultiTexCoord3dv); + GLELoadProc(glMultiTexCoord3f_Impl, glMultiTexCoord3f); + GLELoadProc(glMultiTexCoord3fv_Impl, glMultiTexCoord3fv); + GLELoadProc(glMultiTexCoord3i_Impl, glMultiTexCoord3i); + GLELoadProc(glMultiTexCoord3iv_Impl, glMultiTexCoord3iv); + GLELoadProc(glMultiTexCoord3s_Impl, glMultiTexCoord3s); + GLELoadProc(glMultiTexCoord3sv_Impl, glMultiTexCoord3sv); + GLELoadProc(glMultiTexCoord4d_Impl, glMultiTexCoord4d); + GLELoadProc(glMultiTexCoord4dv_Impl, glMultiTexCoord4dv); + GLELoadProc(glMultiTexCoord4f_Impl, glMultiTexCoord4f); + GLELoadProc(glMultiTexCoord4fv_Impl, glMultiTexCoord4fv); + GLELoadProc(glMultiTexCoord4i_Impl, glMultiTexCoord4i); + GLELoadProc(glMultiTexCoord4iv_Impl, glMultiTexCoord4iv); + GLELoadProc(glMultiTexCoord4s_Impl, glMultiTexCoord4s); + GLELoadProc(glMultiTexCoord4sv_Impl, glMultiTexCoord4sv); + GLELoadProc(glSampleCoverage_Impl, glSampleCoverage); + + // GL_VERSION_1_4 + GLELoadProc(glBlendColor_Impl, glBlendColor); + GLELoadProc(glBlendEquation_Impl, glBlendEquation); + GLELoadProc(glBlendFuncSeparate_Impl, glBlendFuncSeparate); + GLELoadProc(glFogCoordPointer_Impl, glFogCoordPointer); + GLELoadProc(glFogCoordd_Impl, glFogCoordd); + GLELoadProc(glFogCoorddv_Impl, glFogCoorddv); + GLELoadProc(glFogCoordf_Impl, glFogCoordf); + GLELoadProc(glFogCoordfv_Impl, glFogCoordfv); + GLELoadProc(glMultiDrawArrays_Impl, glMultiDrawArrays); + GLELoadProc(glMultiDrawElements_Impl, glMultiDrawElements); + GLELoadProc(glPointParameterf_Impl, glPointParameterf); + GLELoadProc(glPointParameterfv_Impl, glPointParameterfv); + GLELoadProc(glPointParameteri_Impl, glPointParameteri); + GLELoadProc(glPointParameteriv_Impl, glPointParameteriv); + GLELoadProc(glSecondaryColor3b_Impl, glSecondaryColor3b); + GLELoadProc(glSecondaryColor3bv_Impl, glSecondaryColor3bv); + GLELoadProc(glSecondaryColor3d_Impl, glSecondaryColor3d); + GLELoadProc(glSecondaryColor3dv_Impl, glSecondaryColor3dv); + GLELoadProc(glSecondaryColor3f_Impl, glSecondaryColor3f); + GLELoadProc(glSecondaryColor3fv_Impl, glSecondaryColor3fv); + GLELoadProc(glSecondaryColor3i_Impl, glSecondaryColor3i); + GLELoadProc(glSecondaryColor3iv_Impl, glSecondaryColor3iv); + GLELoadProc(glSecondaryColor3s_Impl, glSecondaryColor3s); + GLELoadProc(glSecondaryColor3sv_Impl, glSecondaryColor3sv); + GLELoadProc(glSecondaryColor3ub_Impl, glSecondaryColor3ub); + GLELoadProc(glSecondaryColor3ubv_Impl, glSecondaryColor3ubv); + GLELoadProc(glSecondaryColor3ui_Impl, glSecondaryColor3ui); + GLELoadProc(glSecondaryColor3uiv_Impl, glSecondaryColor3uiv); + GLELoadProc(glSecondaryColor3us_Impl, glSecondaryColor3us); + GLELoadProc(glSecondaryColor3usv_Impl, glSecondaryColor3usv); + GLELoadProc(glSecondaryColorPointer_Impl, glSecondaryColorPointer); + GLELoadProc(glWindowPos2d_Impl, glWindowPos2d); + GLELoadProc(glWindowPos2dv_Impl, glWindowPos2dv); + GLELoadProc(glWindowPos2f_Impl, glWindowPos2f); + GLELoadProc(glWindowPos2fv_Impl, glWindowPos2fv); + GLELoadProc(glWindowPos2i_Impl, glWindowPos2i); + GLELoadProc(glWindowPos2iv_Impl, glWindowPos2iv); + GLELoadProc(glWindowPos2s_Impl, glWindowPos2s); + GLELoadProc(glWindowPos2sv_Impl, glWindowPos2sv); + GLELoadProc(glWindowPos3d_Impl, glWindowPos3d); + GLELoadProc(glWindowPos3dv_Impl, glWindowPos3dv); + GLELoadProc(glWindowPos3f_Impl, glWindowPos3f); + GLELoadProc(glWindowPos3fv_Impl, glWindowPos3fv); + GLELoadProc(glWindowPos3i_Impl, glWindowPos3i); + GLELoadProc(glWindowPos3iv_Impl, glWindowPos3iv); + GLELoadProc(glWindowPos3s_Impl, glWindowPos3s); + GLELoadProc(glWindowPos3sv_Impl, glWindowPos3sv); + + // GL_VERSION_1_5 + GLELoadProc(glBeginQuery_Impl, glBeginQuery); + GLELoadProc(glBindBuffer_Impl, glBindBuffer); + GLELoadProc(glBufferData_Impl, glBufferData); + GLELoadProc(glBufferSubData_Impl, glBufferSubData); + GLELoadProc(glDeleteBuffers_Impl, glDeleteBuffers); + GLELoadProc(glDeleteQueries_Impl, glDeleteQueries); + GLELoadProc(glEndQuery_Impl, glEndQuery); + GLELoadProc(glGenBuffers_Impl, glGenBuffers); + GLELoadProc(glGenQueries_Impl, glGenQueries); + GLELoadProc(glGetBufferParameteriv_Impl, glGetBufferParameteriv); + GLELoadProc(glGetBufferPointerv_Impl, glGetBufferPointerv); + GLELoadProc(glGetBufferSubData_Impl, glGetBufferSubData); + GLELoadProc(glGetQueryObjectiv_Impl, glGetQueryObjectiv); + GLELoadProc(glGetQueryObjectuiv_Impl, glGetQueryObjectuiv); + GLELoadProc(glGetQueryiv_Impl, glGetQueryiv); + GLELoadProc(glIsBuffer_Impl, glIsBuffer); + GLELoadProc(glIsQuery_Impl, glIsQuery); + GLELoadProc(glMapBuffer_Impl, glMapBuffer); + GLELoadProc(glUnmapBuffer_Impl, glUnmapBuffer); + + // GL_VERSION_2_0 + GLELoadProc(glAttachShader_Impl, glAttachShader); + GLELoadProc(glBindAttribLocation_Impl, glBindAttribLocation); + GLELoadProc(glBlendEquationSeparate_Impl, glBlendEquationSeparate); + GLELoadProc(glCompileShader_Impl, glCompileShader); + GLELoadProc(glCreateProgram_Impl, glCreateProgram); + GLELoadProc(glCreateShader_Impl, glCreateShader); + GLELoadProc(glDeleteProgram_Impl, glDeleteProgram); + GLELoadProc(glDeleteShader_Impl, glDeleteShader); + GLELoadProc(glDetachShader_Impl, glDetachShader); + GLELoadProc(glDisableVertexAttribArray_Impl, glDisableVertexAttribArray); + GLELoadProc(glDrawBuffers_Impl, glDrawBuffers); + GLELoadProc(glEnableVertexAttribArray_Impl, glEnableVertexAttribArray); + GLELoadProc(glGetActiveAttrib_Impl, glGetActiveAttrib); + GLELoadProc(glGetActiveUniform_Impl, glGetActiveUniform); + GLELoadProc(glGetAttachedShaders_Impl, glGetAttachedShaders); + GLELoadProc(glGetAttribLocation_Impl, glGetAttribLocation); + GLELoadProc(glGetProgramInfoLog_Impl, glGetProgramInfoLog); + GLELoadProc(glGetProgramiv_Impl, glGetProgramiv); + GLELoadProc(glGetShaderInfoLog_Impl, glGetShaderInfoLog); + GLELoadProc(glGetShaderSource_Impl, glGetShaderSource); + GLELoadProc(glGetShaderiv_Impl, glGetShaderiv); + GLELoadProc(glGetUniformLocation_Impl, glGetUniformLocation); + GLELoadProc(glGetUniformfv_Impl, glGetUniformfv); + GLELoadProc(glGetUniformiv_Impl, glGetUniformiv); + GLELoadProc(glGetVertexAttribPointerv_Impl, glGetVertexAttribPointerv); + GLELoadProc(glGetVertexAttribdv_Impl, glGetVertexAttribdv); + GLELoadProc(glGetVertexAttribfv_Impl, glGetVertexAttribfv); + GLELoadProc(glGetVertexAttribiv_Impl, glGetVertexAttribiv); + GLELoadProc(glIsProgram_Impl, glIsProgram); + GLELoadProc(glIsShader_Impl, glIsShader); + GLELoadProc(glLinkProgram_Impl, glLinkProgram); + GLELoadProc(glShaderSource_Impl, glShaderSource); + GLELoadProc(glStencilFuncSeparate_Impl, glStencilFuncSeparate); + GLELoadProc(glStencilMaskSeparate_Impl, glStencilMaskSeparate); + GLELoadProc(glStencilOpSeparate_Impl, glStencilOpSeparate); + GLELoadProc(glUniform1f_Impl, glUniform1f); + GLELoadProc(glUniform1fv_Impl, glUniform1fv); + GLELoadProc(glUniform1i_Impl, glUniform1i); + GLELoadProc(glUniform1iv_Impl, glUniform1iv); + GLELoadProc(glUniform2f_Impl, glUniform2f); + GLELoadProc(glUniform2fv_Impl, glUniform2fv); + GLELoadProc(glUniform2i_Impl, glUniform2i); + GLELoadProc(glUniform2iv_Impl, glUniform2iv); + GLELoadProc(glUniform3f_Impl, glUniform3f); + GLELoadProc(glUniform3fv_Impl, glUniform3fv); + GLELoadProc(glUniform3i_Impl, glUniform3i); + GLELoadProc(glUniform3iv_Impl, glUniform3iv); + GLELoadProc(glUniform4f_Impl, glUniform4f); + GLELoadProc(glUniform4fv_Impl, glUniform4fv); + GLELoadProc(glUniform4i_Impl, glUniform4i); + GLELoadProc(glUniform4iv_Impl, glUniform4iv); + GLELoadProc(glUniformMatrix2fv_Impl, glUniformMatrix2fv); + GLELoadProc(glUniformMatrix3fv_Impl, glUniformMatrix3fv); + GLELoadProc(glUniformMatrix4fv_Impl, glUniformMatrix4fv); + GLELoadProc(glUseProgram_Impl, glUseProgram); + GLELoadProc(glValidateProgram_Impl, glValidateProgram); + GLELoadProc(glVertexAttrib1d_Impl, glVertexAttrib1d); + GLELoadProc(glVertexAttrib1dv_Impl, glVertexAttrib1dv); + GLELoadProc(glVertexAttrib1f_Impl, glVertexAttrib1f); + GLELoadProc(glVertexAttrib1fv_Impl, glVertexAttrib1fv); + GLELoadProc(glVertexAttrib1s_Impl, glVertexAttrib1s); + GLELoadProc(glVertexAttrib1sv_Impl, glVertexAttrib1sv); + GLELoadProc(glVertexAttrib2d_Impl, glVertexAttrib2d); + GLELoadProc(glVertexAttrib2dv_Impl, glVertexAttrib2dv); + GLELoadProc(glVertexAttrib2f_Impl, glVertexAttrib2f); + GLELoadProc(glVertexAttrib2fv_Impl, glVertexAttrib2fv); + GLELoadProc(glVertexAttrib2s_Impl, glVertexAttrib2s); + GLELoadProc(glVertexAttrib2sv_Impl, glVertexAttrib2sv); + GLELoadProc(glVertexAttrib3d_Impl, glVertexAttrib3d); + GLELoadProc(glVertexAttrib3dv_Impl, glVertexAttrib3dv); + GLELoadProc(glVertexAttrib3f_Impl, glVertexAttrib3f); + GLELoadProc(glVertexAttrib3fv_Impl, glVertexAttrib3fv); + GLELoadProc(glVertexAttrib3s_Impl, glVertexAttrib3s); + GLELoadProc(glVertexAttrib3sv_Impl, glVertexAttrib3sv); + GLELoadProc(glVertexAttrib4Nbv_Impl, glVertexAttrib4Nbv); + GLELoadProc(glVertexAttrib4Niv_Impl, glVertexAttrib4Niv); + GLELoadProc(glVertexAttrib4Nsv_Impl, glVertexAttrib4Nsv); + GLELoadProc(glVertexAttrib4Nub_Impl, glVertexAttrib4Nub); + GLELoadProc(glVertexAttrib4Nubv_Impl, glVertexAttrib4Nubv); + GLELoadProc(glVertexAttrib4Nuiv_Impl, glVertexAttrib4Nuiv); + GLELoadProc(glVertexAttrib4Nusv_Impl, glVertexAttrib4Nusv); + GLELoadProc(glVertexAttrib4bv_Impl, glVertexAttrib4bv); + GLELoadProc(glVertexAttrib4d_Impl, glVertexAttrib4d); + GLELoadProc(glVertexAttrib4dv_Impl, glVertexAttrib4dv); + GLELoadProc(glVertexAttrib4f_Impl, glVertexAttrib4f); + GLELoadProc(glVertexAttrib4fv_Impl, glVertexAttrib4fv); + GLELoadProc(glVertexAttrib4iv_Impl, glVertexAttrib4iv); + GLELoadProc(glVertexAttrib4s_Impl, glVertexAttrib4s); + GLELoadProc(glVertexAttrib4sv_Impl, glVertexAttrib4sv); + GLELoadProc(glVertexAttrib4ubv_Impl, glVertexAttrib4ubv); + GLELoadProc(glVertexAttrib4uiv_Impl, glVertexAttrib4uiv); + GLELoadProc(glVertexAttrib4usv_Impl, glVertexAttrib4usv); + GLELoadProc(glVertexAttribPointer_Impl, glVertexAttribPointer); + + // GL_VERSION_2_1 + GLELoadProc(glUniformMatrix2x3fv_Impl, glUniformMatrix2x3fv); + GLELoadProc(glUniformMatrix2x4fv_Impl, glUniformMatrix2x4fv); + GLELoadProc(glUniformMatrix3x2fv_Impl, glUniformMatrix3x2fv); + GLELoadProc(glUniformMatrix3x4fv_Impl, glUniformMatrix3x4fv); + GLELoadProc(glUniformMatrix4x2fv_Impl, glUniformMatrix4x2fv); + GLELoadProc(glUniformMatrix4x3fv_Impl, glUniformMatrix4x3fv); + + // GL_VERSION_3_0 + GLELoadProc(glBeginConditionalRender_Impl, glBeginConditionalRender); + GLELoadProc(glBeginTransformFeedback_Impl, glBeginTransformFeedback); + GLELoadProc(glBindFragDataLocation_Impl, glBindFragDataLocation); + GLELoadProc(glClampColor_Impl, glClampColor); + GLELoadProc(glClearBufferfi_Impl, glClearBufferfi); + GLELoadProc(glClearBufferfv_Impl, glClearBufferfv); + GLELoadProc(glClearBufferiv_Impl, glClearBufferiv); + GLELoadProc(glClearBufferuiv_Impl, glClearBufferuiv); + GLELoadProc(glColorMaski_Impl, glColorMaski); + GLELoadProc(glDisablei_Impl, glDisablei); + GLELoadProc(glEnablei_Impl, glEnablei); + GLELoadProc(glEndConditionalRender_Impl, glEndConditionalRender); + GLELoadProc(glEndTransformFeedback_Impl, glEndTransformFeedback); + GLELoadProc(glBindBufferRange_Impl, glBindBufferRange); + GLELoadProc(glBindBufferBase_Impl, glBindBufferBase); + GLELoadProc(glGetBooleani_v_Impl, glGetBooleani_v); + GLELoadProc(glGetIntegeri_v_Impl, glGetIntegeri_v); + GLELoadProc(glGetFragDataLocation_Impl, glGetFragDataLocation); + GLELoadProc(glGetStringi_Impl, glGetStringi); + GLELoadProc(glGetTexParameterIiv_Impl, glGetTexParameterIiv); + GLELoadProc(glGetTexParameterIuiv_Impl, glGetTexParameterIuiv); + GLELoadProc(glGetTransformFeedbackVarying_Impl, glGetTransformFeedbackVarying); + GLELoadProc(glGetUniformuiv_Impl, glGetUniformuiv); + GLELoadProc(glGetVertexAttribIiv_Impl, glGetVertexAttribIiv); + GLELoadProc(glGetVertexAttribIuiv_Impl, glGetVertexAttribIuiv); + GLELoadProc(glIsEnabledi_Impl, glIsEnabledi); + GLELoadProc(glTexParameterIiv_Impl, glTexParameterIiv); + GLELoadProc(glTexParameterIuiv_Impl, glTexParameterIuiv); + GLELoadProc(glTransformFeedbackVaryings_Impl, glTransformFeedbackVaryings); + GLELoadProc(glUniform1ui_Impl, glUniform1ui); + GLELoadProc(glUniform1uiv_Impl, glUniform1uiv); + GLELoadProc(glUniform2ui_Impl, glUniform2ui); + GLELoadProc(glUniform2uiv_Impl, glUniform2uiv); + GLELoadProc(glUniform3ui_Impl, glUniform3ui); + GLELoadProc(glUniform3uiv_Impl, glUniform3uiv); + GLELoadProc(glUniform4ui_Impl, glUniform4ui); + GLELoadProc(glUniform4uiv_Impl, glUniform4uiv); + GLELoadProc(glVertexAttribI1i_Impl, glVertexAttribI1i); + GLELoadProc(glVertexAttribI1iv_Impl, glVertexAttribI1iv); + GLELoadProc(glVertexAttribI1ui_Impl, glVertexAttribI1ui); + GLELoadProc(glVertexAttribI1uiv_Impl, glVertexAttribI1uiv); + GLELoadProc(glVertexAttribI2i_Impl, glVertexAttribI2i); + GLELoadProc(glVertexAttribI2iv_Impl, glVertexAttribI2iv); + GLELoadProc(glVertexAttribI2ui_Impl, glVertexAttribI2ui); + GLELoadProc(glVertexAttribI2uiv_Impl, glVertexAttribI2uiv); + GLELoadProc(glVertexAttribI3i_Impl, glVertexAttribI3i); + GLELoadProc(glVertexAttribI3iv_Impl, glVertexAttribI3iv); + GLELoadProc(glVertexAttribI3ui_Impl, glVertexAttribI3ui); + GLELoadProc(glVertexAttribI3uiv_Impl, glVertexAttribI3uiv); + GLELoadProc(glVertexAttribI4bv_Impl, glVertexAttribI4bv); + GLELoadProc(glVertexAttribI4i_Impl, glVertexAttribI4i); + GLELoadProc(glVertexAttribI4iv_Impl, glVertexAttribI4iv); + GLELoadProc(glVertexAttribI4sv_Impl, glVertexAttribI4sv); + GLELoadProc(glVertexAttribI4ubv_Impl, glVertexAttribI4ubv); + GLELoadProc(glVertexAttribI4ui_Impl, glVertexAttribI4ui); + GLELoadProc(glVertexAttribI4uiv_Impl, glVertexAttribI4uiv); + GLELoadProc(glVertexAttribI4usv_Impl, glVertexAttribI4usv); + GLELoadProc(glVertexAttribIPointer_Impl, glVertexAttribIPointer); + + // GL_VERSION_3_1 + GLELoadProc(glDrawArraysInstanced_Impl, glDrawArraysInstanced); + GLELoadProc(glDrawElementsInstanced_Impl, glDrawElementsInstanced); + GLELoadProc(glPrimitiveRestartIndex_Impl, glPrimitiveRestartIndex); + GLELoadProc(glTexBuffer_Impl, glTexBuffer); + + // GL_VERSION_3_2 + GLELoadProc(glFramebufferTexture_Impl, glFramebufferTexture); + GLELoadProc(glGetBufferParameteri64v_Impl, glGetBufferParameteri64v); + GLELoadProc(glGetInteger64i_v_Impl, glGetInteger64i_v); + + // GL_VERSION_3_3 + GLELoadProc(glVertexAttribDivisor_Impl, glVertexAttribDivisor); + + // GL_VERSION_4_0 + GLELoadProc(glBlendEquationSeparatei_Impl, glBlendEquationSeparatei); + GLELoadProc(glBlendEquationi_Impl, glBlendEquationi); + GLELoadProc(glBlendFuncSeparatei_Impl, glBlendFuncSeparatei); + GLELoadProc(glBlendFunci_Impl, glBlendFunci); + GLELoadProc(glMinSampleShading_Impl, glMinSampleShading); + + // GL_VERSION_4_2 + GLELoadProc(glMemoryBarrier_Impl, glMemoryBarrier); + + // GL_VERSION_4_3 + GLELoadProc(glDispatchCompute_Impl, glDispatchCompute); + GLELoadProc(glBindImageTexture_Impl, glBindImageTexture); + + // GL_AMD_debug_output + GLELoadProc(glDebugMessageCallbackAMD_Impl, glDebugMessageCallbackAMD); + GLELoadProc(glDebugMessageEnableAMD_Impl, glDebugMessageEnableAMD); + GLELoadProc(glDebugMessageInsertAMD_Impl, glDebugMessageInsertAMD); + GLELoadProc(glGetDebugMessageLogAMD_Impl, glGetDebugMessageLogAMD); + +#if defined(GLE_CGL_ENABLED) + // GL_APPLE_element_array + GLELoadProc(glDrawElementArrayAPPLE_Impl, glDrawElementArrayAPPLE); + GLELoadProc(glDrawRangeElementArrayAPPLE_Impl, glDrawRangeElementArrayAPPLE); + GLELoadProc(glElementPointerAPPLE_Impl, glElementPointerAPPLE); + GLELoadProc(glMultiDrawElementArrayAPPLE_Impl, glMultiDrawElementArrayAPPLE); + GLELoadProc(glMultiDrawRangeElementArrayAPPLE_Impl, glMultiDrawRangeElementArrayAPPLE); + + // GL_APPLE_fence + GLELoadProc(glDeleteFencesAPPLE_Impl, glDeleteFencesAPPLE); + GLELoadProc(glFinishFenceAPPLE_Impl, glFinishFenceAPPLE); + GLELoadProc(glFinishObjectAPPLE_Impl, glFinishObjectAPPLE); + GLELoadProc(glGenFencesAPPLE_Impl, glGenFencesAPPLE); + GLELoadProc(glIsFenceAPPLE_Impl, glIsFenceAPPLE); + GLELoadProc(glSetFenceAPPLE_Impl, glSetFenceAPPLE); + GLELoadProc(glTestFenceAPPLE_Impl, glTestFenceAPPLE); + GLELoadProc(glTestObjectAPPLE_Impl, glTestObjectAPPLE); + + // GL_APPLE_flush_buffer_range + GLELoadProc(glBufferParameteriAPPLE_Impl, glMultiDrawRangeElementArrayAPPLE); + GLELoadProc(glFlushMappedBufferRangeAPPLE_Impl, glFlushMappedBufferRangeAPPLE); + + // GL_APPLE_object_purgeable + GLELoadProc(glGetObjectParameterivAPPLE_Impl, glGetObjectParameterivAPPLE); + GLELoadProc(glObjectPurgeableAPPLE_Impl, glObjectPurgeableAPPLE); + GLELoadProc(glObjectUnpurgeableAPPLE_Impl, glObjectUnpurgeableAPPLE); + + // GL_APPLE_texture_range + GLELoadProc(glGetTexParameterPointervAPPLE_Impl, glGetTexParameterPointervAPPLE); + GLELoadProc(glTextureRangeAPPLE_Impl, glTextureRangeAPPLE); + + // GL_APPLE_vertex_array_object + GLELoadProc(glBindVertexArrayAPPLE_Impl, glBindVertexArrayAPPLE); + GLELoadProc(glDeleteVertexArraysAPPLE_Impl, glDeleteVertexArraysAPPLE); + GLELoadProc(glGenVertexArraysAPPLE_Impl, glGenVertexArraysAPPLE); + GLELoadProc(glIsVertexArrayAPPLE_Impl, glIsVertexArrayAPPLE); + + // GL_APPLE_vertex_array_range + GLELoadProc(glFlushVertexArrayRangeAPPLE_Impl, glFlushVertexArrayRangeAPPLE); + GLELoadProc(glVertexArrayParameteriAPPLE_Impl, glVertexArrayParameteriAPPLE); + GLELoadProc(glVertexArrayRangeAPPLE_Impl, glVertexArrayRangeAPPLE); + + // GL_APPLE_vertex_program_evaluators + GLELoadProc(glDisableVertexAttribAPPLE_Impl, glDisableVertexAttribAPPLE); + GLELoadProc(glEnableVertexAttribAPPLE_Impl, glEnableVertexAttribAPPLE); + GLELoadProc(glIsVertexAttribEnabledAPPLE_Impl, glIsVertexAttribEnabledAPPLE); + GLELoadProc(glMapVertexAttrib1dAPPLE_Impl, glMapVertexAttrib1dAPPLE); + GLELoadProc(glMapVertexAttrib1fAPPLE_Impl, glMapVertexAttrib1fAPPLE); + GLELoadProc(glMapVertexAttrib2dAPPLE_Impl, glMapVertexAttrib2dAPPLE); + GLELoadProc(glMapVertexAttrib2fAPPLE_Impl, glMapVertexAttrib2fAPPLE); + +#endif // GLE_CGL_ENABLED + + // GL_ARB_copy_buffer + GLELoadProc(glCopyBufferSubData_Impl, glCopyBufferSubData); + + // GL_ARB_debug_output + GLELoadProc(glDebugMessageCallbackARB_Impl, glDebugMessageCallbackARB); + GLELoadProc(glDebugMessageControlARB_Impl, glDebugMessageControlARB); + GLELoadProc(glDebugMessageInsertARB_Impl, glDebugMessageInsertARB); + GLELoadProc(glGetDebugMessageLogARB_Impl, glGetDebugMessageLogARB); + + // GL_ARB_ES2_compatibility + GLELoadProc(glClearDepthf_Impl, glClearDepthf); + GLELoadProc(glDepthRangef_Impl, glDepthRangef); + GLELoadProc(glGetShaderPrecisionFormat_Impl, glGetShaderPrecisionFormat); + GLELoadProc(glReleaseShaderCompiler_Impl, glReleaseShaderCompiler); + GLELoadProc(glShaderBinary_Impl, glShaderBinary); + + // GL_ARB_framebuffer_object + GLELoadProc(glBindFramebuffer_Impl, glBindFramebuffer); + GLELoadProc(glBindRenderbuffer_Impl, glBindRenderbuffer); + GLELoadProc(glBlitFramebuffer_Impl, glBlitFramebuffer); + GLELoadProc(glCheckFramebufferStatus_Impl, glCheckFramebufferStatus); + GLELoadProc(glDeleteFramebuffers_Impl, glDeleteFramebuffers); + GLELoadProc(glDeleteRenderbuffers_Impl, glDeleteRenderbuffers); + GLELoadProc(glFramebufferRenderbuffer_Impl, glFramebufferRenderbuffer); + GLELoadProc(glFramebufferTexture1D_Impl, glFramebufferTexture1D); + GLELoadProc(glFramebufferTexture2D_Impl, glFramebufferTexture2D); + GLELoadProc(glFramebufferTexture3D_Impl, glFramebufferTexture3D); + GLELoadProc(glFramebufferTextureLayer_Impl, glFramebufferTextureLayer); + GLELoadProc(glGenFramebuffers_Impl, glGenFramebuffers); + GLELoadProc(glGenRenderbuffers_Impl, glGenRenderbuffers); + GLELoadProc(glGenerateMipmap_Impl, glGenerateMipmap); + GLELoadProc(glGetFramebufferAttachmentParameteriv_Impl, glGetFramebufferAttachmentParameteriv); + GLELoadProc(glGetRenderbufferParameteriv_Impl, glGetRenderbufferParameteriv); + GLELoadProc(glIsFramebuffer_Impl, glIsFramebuffer); + GLELoadProc(glIsRenderbuffer_Impl, glIsRenderbuffer); + GLELoadProc(glRenderbufferStorage_Impl, glRenderbufferStorage); + GLELoadProc(glRenderbufferStorageMultisample_Impl, glRenderbufferStorageMultisample); + + if (!glBindFramebuffer_Impl) // This will rarely if ever be the case in practice with modern + // computers and drivers. + { + // See if we can map GL_EXT_framebuffer_object to GL_ARB_framebuffer_object. The former is + // basically a subset of the latter, but we use only that subset. + GLELoadProc(glBindFramebuffer_Impl, glBindFramebufferEXT); + GLELoadProc(glBindRenderbuffer_Impl, glBindRenderbufferEXT); + // GLELoadProc(glBlitFramebuffer_Impl, glBlitFramebufferEXT (nonexistent)); + GLELoadProc(glCheckFramebufferStatus_Impl, glCheckFramebufferStatusEXT); + GLELoadProc(glDeleteFramebuffers_Impl, glDeleteFramebuffersEXT); + GLELoadProc(glDeleteRenderbuffers_Impl, glDeleteRenderbuffersEXT); + GLELoadProc(glFramebufferRenderbuffer_Impl, glFramebufferRenderbufferEXT); + GLELoadProc(glFramebufferTexture1D_Impl, glFramebufferTexture1DEXT); + GLELoadProc(glFramebufferTexture2D_Impl, glFramebufferTexture2DEXT); + GLELoadProc(glFramebufferTexture3D_Impl, glFramebufferTexture3DEXT); + // GLELoadProc(glFramebufferTextureLayer_Impl, glFramebufferTextureLayerEXT (nonexistent)); + GLELoadProc(glGenFramebuffers_Impl, glGenFramebuffersEXT); + GLELoadProc(glGenRenderbuffers_Impl, glGenRenderbuffersEXT); + GLELoadProc(glGenerateMipmap_Impl, glGenerateMipmapEXT); + GLELoadProc( + glGetFramebufferAttachmentParameteriv_Impl, glGetFramebufferAttachmentParameterivEXT); + GLELoadProc(glGetRenderbufferParameteriv_Impl, glGetRenderbufferParameterivEXT); + GLELoadProc(glIsFramebuffer_Impl, glIsFramebufferEXT); + GLELoadProc(glIsRenderbuffer_Impl, glIsRenderbufferEXT); + GLELoadProc(glRenderbufferStorage_Impl, glRenderbufferStorageEXT); + // GLELoadProc(glRenderbufferStorageMultisample_Impl, glRenderbufferStorageMultisampleEXT + // (nonexistent)); + } + + // GL_ARB_texture_multisample + GLELoadProc(glGetMultisamplefv_Impl, glGetMultisamplefv); + GLELoadProc(glSampleMaski_Impl, glSampleMaski); + GLELoadProc(glTexImage2DMultisample_Impl, glTexImage2DMultisample); + GLELoadProc(glTexImage3DMultisample_Impl, glTexImage3DMultisample); + + // GL_ARB_texture_storage + GLELoadProc(glTexStorage1D_Impl, glTexStorage1D); + GLELoadProc(glTexStorage2D_Impl, glTexStorage2D); + GLELoadProc(glTexStorage3D_Impl, glTexStorage3D); + GLELoadProc(glTextureStorage1DEXT_Impl, glTextureStorage1DEXT); + GLELoadProc(glTextureStorage2DEXT_Impl, glTextureStorage2DEXT); + GLELoadProc(glTextureStorage3DEXT_Impl, glTextureStorage3DEXT); + + // GL_ARB_texture_storage_multisample + GLELoadProc(glTexStorage2DMultisample_Impl, glTexStorage2DMultisample); + GLELoadProc(glTexStorage3DMultisample_Impl, glTexStorage3DMultisample); + GLELoadProc(glTextureStorage2DMultisampleEXT_Impl, glTextureStorage2DMultisampleEXT); + GLELoadProc(glTextureStorage3DMultisampleEXT_Impl, glTextureStorage3DMultisampleEXT); + + // GL_ARB_timer_query + GLELoadProc(glGetQueryObjecti64v_Impl, glGetQueryObjecti64v); + GLELoadProc(glGetQueryObjectui64v_Impl, glGetQueryObjectui64v); + GLELoadProc(glQueryCounter_Impl, glQueryCounter); + + // GL_ARB_vertex_array_object + GLELoadProc(glBindVertexArray_Impl, glBindVertexArray); + GLELoadProc(glDeleteVertexArrays_Impl, glDeleteVertexArrays); + GLELoadProc(glGenVertexArrays_Impl, glGenVertexArrays); + GLELoadProc(glIsVertexArray_Impl, glIsVertexArray); + +#if defined(GLE_CGL_ENABLED) // Apple OpenGL... + if (WholeVersion < 302) // It turns out that Apple OpenGL versions prior to 3.2 have + // glBindVertexArray, etc. but they silently fail by default. So always + // use the APPLE version. + { + glBindVertexArray_Impl = glBindVertexArrayAPPLE_Impl; + glDeleteVertexArrays_Impl = glDeleteVertexArraysAPPLE_Impl; + glGenVertexArrays_Impl = + (OVRTypeof(glGenVertexArrays_Impl))glGenVertexArraysAPPLE_Impl; // There is a const cast of + // the arrays argument here + // due to a slight + // difference in the Apple + // behavior. For our + // purposes it should be OK. + glIsVertexArray_Impl = glIsVertexArrayAPPLE_Impl; + + if (glBindVertexArray_Impl) + gle_ARB_vertex_array_object = true; // We are routing the APPLE version through our version, + // with the assumption that we use the ARB version the + // same as we would use the APPLE version. + } +#endif + + // GL_EXT_draw_buffers2 + GLELoadProc(glColorMaskIndexedEXT_Impl, glColorMaskIndexedEXT); + GLELoadProc(glDisableIndexedEXT_Impl, glDisableIndexedEXT); + GLELoadProc(glEnableIndexedEXT_Impl, glEnableIndexedEXT); + GLELoadProc(glGetBooleanIndexedvEXT_Impl, glGetBooleanIndexedvEXT); + GLELoadProc(glGetIntegerIndexedvEXT_Impl, glGetIntegerIndexedvEXT); + GLELoadProc(glIsEnabledIndexedEXT_Impl, glIsEnabledIndexedEXT); + + // GL_KHR_debug + GLELoadProc(glDebugMessageCallback_Impl, glDebugMessageCallback); + GLELoadProc(glDebugMessageControl_Impl, glDebugMessageControl); + GLELoadProc(glDebugMessageInsert_Impl, glDebugMessageInsert); + GLELoadProc(glGetDebugMessageLog_Impl, glGetDebugMessageLog); + GLELoadProc(glGetObjectLabel_Impl, glGetObjectLabel); + GLELoadProc(glGetObjectPtrLabel_Impl, glGetObjectPtrLabel); + GLELoadProc(glObjectLabel_Impl, glObjectLabel); + GLELoadProc(glObjectPtrLabel_Impl, glObjectPtrLabel); + GLELoadProc(glPopDebugGroup_Impl, glPopDebugGroup); + GLELoadProc(glPushDebugGroup_Impl, glPushDebugGroup); + + // GL_WIN_swap_hint + GLELoadProc(glAddSwapHintRectWIN_Impl, glAddSwapHintRectWIN); +} + +OVR_DISABLE_MSVC_WARNING(4510 4512 4610) // default constructor could not be generated, +struct ValueStringPair { + bool& IsPresent; + const char* ExtensionName; +}; + +// Helper function for InitExtensionSupport. +static void +CheckExtensions(ValueStringPair* pValueStringPairArray, size_t arrayCount, const char* extensions) { + // We search the extesion list string for each of the individual extensions we are interested in. + // We do this by walking over the string and comparing each entry in turn to our array of entries + // of interest. Example string (with patholigical extra spaces): " ext1 ext2 ext3 " + + char extension[64]; + const char* p = extensions; // p points to the beginning of the current word + const char* pEnd; // pEnd points to one-past the last character of the current word. It is where + // the trailing '\0' of the string would be. + + while (*p) { + while (*p == ' ') // Find the next word begin. + ++p; + + pEnd = p; + + while ((*pEnd != '\0') && (*pEnd != ' ')) // Find the next word end. + ++pEnd; + + if (((pEnd - p) > 0) && ((size_t)(pEnd - p) < OVR_ARRAY_COUNT(extension))) { + memcpy(extension, p, pEnd - p); // To consider: Revise this code to directly read from p/pEnd + // instead of doing a memcpy. + extension[pEnd - p] = '\0'; + + for (size_t i = 0; i < arrayCount; i++) // For each extension we are interested in... + { + ValueStringPair& vsp = pValueStringPairArray[i]; + + if (strcmp(extension, vsp.ExtensionName) == 0) // case-sensitive compare + pValueStringPairArray[i].IsPresent = true; + } + } + + p = pEnd; + } +} + +void OVR::GLEContext::InitExtensionSupport() { + // It may be better in the long run to use a member STL map. + // It would make this loading code cleaner, though it would make lookups slower. + + ValueStringPair vspArray[] = { + {gle_AMD_debug_output, "GL_AMD_debug_output"}, +#if defined(GLE_CGL_ENABLED) + {gle_APPLE_aux_depth_stencil, "GL_APPLE_aux_depth_stencil"}, + {gle_APPLE_client_storage, "GL_APPLE_client_storage"}, + {gle_APPLE_element_array, "GL_APPLE_element_array"}, + {gle_APPLE_fence, "GL_APPLE_fence"}, + {gle_APPLE_float_pixels, "GL_APPLE_float_pixels"}, + {gle_APPLE_flush_buffer_range, "GL_APPLE_flush_buffer_range"}, + {gle_APPLE_object_purgeable, "GL_APPLE_object_purgeable"}, + {gle_APPLE_pixel_buffer, "GL_APPLE_pixel_buffer"}, + {gle_APPLE_rgb_422, "GL_APPLE_rgb_422"}, + {gle_APPLE_row_bytes, "GL_APPLE_row_bytes"}, + {gle_APPLE_specular_vector, "GL_APPLE_specular_vector"}, + {gle_APPLE_texture_range, "GL_APPLE_texture_range"}, + {gle_APPLE_transform_hint, "GL_APPLE_transform_hint"}, + {gle_APPLE_vertex_array_object, "GL_APPLE_vertex_array_object"}, + {gle_APPLE_vertex_array_range, "GL_APPLE_vertex_array_range"}, + {gle_APPLE_vertex_program_evaluators, "GL_APPLE_vertex_program_evaluators"}, + {gle_APPLE_ycbcr_422, "GL_APPLE_ycbcr_422"}, +#endif + {gle_ARB_copy_buffer, "GL_ARB_copy_buffer"}, + {gle_ARB_debug_output, "GL_ARB_debug_output"}, + {gle_ARB_depth_buffer_float, "GL_ARB_depth_buffer_float"}, + {gle_ARB_ES2_compatibility, "GL_ARB_ES2_compatibility"}, + {gle_ARB_framebuffer_object, "GL_ARB_framebuffer_object"}, + {gle_ARB_framebuffer_object, "GL_EXT_framebuffer_object"}, // We map glBindFramebuffer, etc. to + // glBindFramebufferEXT, etc. if + // necessary + {gle_ARB_framebuffer_sRGB, "GL_ARB_framebuffer_sRGB"}, + {gle_ARB_texture_multisample, "GL_ARB_texture_multisample"}, + {gle_ARB_texture_non_power_of_two, "GL_ARB_texture_non_power_of_two"}, + {gle_ARB_texture_rectangle, "GL_ARB_texture_rectangle"}, + {gle_ARB_texture_rectangle, "GL_EXT_texture_rectangle"}, // We also check for + // GL_EXT_texture_rectangle and + // GL_NV_texture_rectangle. + {gle_ARB_texture_rectangle, "GL_NV_texture_rectangle"}, + {gle_ARB_texture_storage, "GL_ARB_texture_storage"}, + {gle_ARB_texture_storage_multisample, "GL_ARB_texture_storage_multisample"}, + {gle_ARB_timer_query, "GL_ARB_timer_query"}, + {gle_ARB_vertex_array_object, "GL_ARB_vertex_array_object"}, + {gle_EXT_draw_buffers2, "GL_EXT_draw_buffers2"}, + {gle_EXT_texture_compression_s3tc, "GL_EXT_texture_compression_s3tc"}, + {gle_EXT_texture_filter_anisotropic, "GL_EXT_texture_filter_anisotropic"}, + {gle_EXT_texture_sRGB, "GL_EXT_texture_sRGB"}, + {gle_KHR_debug, "GL_KHR_debug"}, + {gle_WIN_swap_hint, "GL_WIN_swap_hint"} + // Windows WGL, Unix GLX, and Apple CGL extensions are handled below, as they require different + // calls from glGetString(GL_EXTENSIONS). + }; + + // We cannot use glGetString(GL_EXTENSIONS) when an OpenGL core profile is active, + // as it's deprecated in favor of using OpenGL 3+ glGetStringi. + const char* extensions = (MajorVersion < 3) ? (const char*)glGetString(GL_EXTENSIONS) : ""; + + if (extensions && *extensions) // If we have a space-delimited extension string to search for + // individual extensions... + { + OVR_DEBUG_LOG(("GL_EXTENSIONS: %s", (const char*)extensions)); + CheckExtensions( + vspArray, + OVR_ARRAY_COUNT(vspArray), + extensions); // Call our shared helper function for this. + } else { + if (MajorVersion >= 3) // If glGetIntegerv(GL_NUM_EXTENSIONS, ...) is supported... + { + // In this case we need to match an array of individual extensions against an array of + // externsions provided by glGetStringi. This is an O(n^2) operation, but at least we + // are doing this only once on startup. There are a few tricks we can employ to speed + // up the logic below, but they may not be worth much. + + GLint extensionCount = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); + GLenum err = glGetError(); + + if (err == 0) { + std::string sExtensions; + + for (GLint e = 0; e != extensionCount; ++e) // For each extension supported... + { + const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, (GLuint)e); + + if (extension) // glGetStringi returns NULL upon error. + { + sExtensions += " "; + sExtensions += extension; + + for (size_t i = 0; i < OVR_ARRAY_COUNT(vspArray); + i++) // For each extension we are interested in... + { + ValueStringPair& vsp = vspArray[i]; + + if (strcmp(extension, vsp.ExtensionName) == 0) // case-sensitive compare + vspArray[i].IsPresent = true; + } + } else + break; + } + + OVR_DEBUG_LOG(("GL_EXTENSIONS: %s", sExtensions.c_str())); + } + } + // Else we have a problem: no means to read the extensions was successful. + } + +#if defined(GLE_CGL_ENABLED) + // The following are built into Apple OpenGL 3.2+ (declared in ) and not identified + // as extensions. On other platforms (e.g. Windows) these are identified as extensions and are + // detected above. + if (WholeVersion >= 302) { + gle_ARB_copy_buffer = true; + gle_ARB_depth_buffer_float = true; + gle_ARB_framebuffer_object = true; + gle_ARB_framebuffer_sRGB = true; + gle_ARB_texture_multisample = true; + gle_ARB_texture_non_power_of_two = true; + gle_ARB_texture_rectangle = true; + gle_ARB_vertex_array_object = true; + } +#endif + +} // GLEContext::InitExtensionSupport() + +void OVR::GLEContext::InitPlatformVersion() { +#if defined(GLE_GLX_ENABLED) + const char* pGLXVersion = glXGetClientString( + glXGetCurrentDisplay(), + GLX_VERSION); // To do: Use a better mechanism to get the desired display. + sscanf(pGLXVersion, "%d.%d", &PlatformMajorVersion, &PlatformMinorVersion); + +#elif defined(GLE_EGL_ENABLED) + const char* pEGLVersion = eglQueryString(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_VERSION); + sscanf(pEGLVersion, "%d.%d", &PlatformMajorVersion, &PlatformMinorVersion); + +#else + PlatformMajorVersion = 1; + PlatformMinorVersion = 0; + PlatformWholeVersion = 100; +#endif +} + +void OVR::GLEContext::InitPlatformExtensionLoad() { +#if defined(GLE_WGL_ENABLED) + // WGL + // We don't load these as function pointers but rather statically link to them. + // These need to be loaded via LoadLibrary instead of wglLoadLibrary. + +#if 0 + HINSTANCE hOpenGL = LoadLibraryW(L"Opengl32.dll"); + if(hOpenGL) + { + wglCopyContext_Impl = (OVRTypeof(wglCopyContext_Impl)) GetProcAddress(hOpenGL, "wglCopyContext"); + wglCreateContext_Impl = (OVRTypeof(wglCreateContext_Impl)) GetProcAddress(hOpenGL, "wglCreateContext"); + wglCreateLayerContext_Impl = (OVRTypeof(wglCreateLayerContext_Impl)) GetProcAddress(hOpenGL, "wglCreateLayerContext"); + wglDeleteContext_Impl = (OVRTypeof(wglDeleteContext_Impl)) GetProcAddress(hOpenGL, "wglDeleteContext"); + wglGetCurrentContext_Impl = (OVRTypeof(wglGetCurrentContext_Impl)) GetProcAddress(hOpenGL, "wglGetCurrentContext"); + wglGetCurrentDC_Impl = (OVRTypeof(wglGetCurrentDC_Impl)) GetProcAddress(hOpenGL, "wglGetCurrentDC"); + wglGetProcAddress_Impl = (OVRTypeof(wglGetProcAddress_Impl)) GetProcAddress(hOpenGL, "wglGetProcAddress"); + wglMakeCurrent_Impl = (OVRTypeof(wglMakeCurrent_Impl)) GetProcAddress(hOpenGL, "wglMakeCurrent"); + wglShareLists_Impl = (OVRTypeof(wglShareLists_Impl)) GetProcAddress(hOpenGL, "wglShareLists"); + wglUseFontBitmapsA_Impl = (OVRTypeof(wglUseFontBitmapsA_Impl)) GetProcAddress(hOpenGL, "wglUseFontBitmapsA"); + wglUseFontBitmapsW_Impl = (OVRTypeof(wglUseFontBitmapsW_Impl)) GetProcAddress(hOpenGL, "wglUseFontBitmapsW"); + wglUseFontOutlinesA_Impl = (OVRTypeof(wglUseFontOutlinesA_Impl)) GetProcAddress(hOpenGL, "wglUseFontOutlinesA"); + wglUseFontOutlinesW_Impl = (OVRTypeof(wglUseFontOutlinesW_Impl)) GetProcAddress(hOpenGL, "wglUseFontOutlinesW"); + wglDescribeLayerPlane_Impl = (OVRTypeof(wglDescribeLayerPlane_Impl)) GetProcAddress(hOpenGL, "wglDescribeLayerPlane"); + wglSetLayerPaletteEntries_Impl = (OVRTypeof(wglSetLayerPaletteEntries_Impl)) GetProcAddress(hOpenGL, "wglSetLayerPaletteEntries"); + wglGetLayerPaletteEntries_Impl = (OVRTypeof(wglGetLayerPaletteEntries_Impl)) GetProcAddress(hOpenGL, "wglGetLayerPaletteEntries"); + wglRealizeLayerPalette_Impl = (OVRTypeof(wglRealizeLayerPalette_Impl)) GetProcAddress(hOpenGL, "wglRealizeLayerPalette"); + wglSwapLayerBuffers_Impl = (OVRTypeof(wglSwapLayerBuffers_Impl)) GetProcAddress(hOpenGL, "wglSwapLayerBuffers"); + wglSwapMultipleBuffers_Impl = (OVRTypeof(wglSwapMultipleBuffers_Impl)) GetProcAddress(hOpenGL, "wglSwapMultipleBuffers"); + FreeLibrary(hOpenGL); + } +#endif + + // WGL_ARB_buffer_region + GLELoadProc(wglCreateBufferRegionARB_Impl, wglCreateBufferRegionARB); + GLELoadProc(wglDeleteBufferRegionARB_Impl, wglDeleteBufferRegionARB); + GLELoadProc(wglSaveBufferRegionARB_Impl, wglSaveBufferRegionARB); + GLELoadProc(wglRestoreBufferRegionARB_Impl, wglRestoreBufferRegionARB); + + // WGL_ARB_extensions_string + GLELoadProc(wglGetExtensionsStringARB_Impl, wglGetExtensionsStringARB); + + // WGL_ARB_pixel_format + GLELoadProc(wglGetPixelFormatAttribivARB_Impl, wglGetPixelFormatAttribivARB); + GLELoadProc(wglGetPixelFormatAttribfvARB_Impl, wglGetPixelFormatAttribfvARB); + GLELoadProc(wglChoosePixelFormatARB_Impl, wglChoosePixelFormatARB); + + // WGL_ARB_make_current_read + GLELoadProc(wglMakeContextCurrentARB_Impl, wglMakeContextCurrentARB); + GLELoadProc(wglGetCurrentReadDCARB_Impl, wglGetCurrentReadDCARB); + + // WGL_ARB_pbuffer + GLELoadProc(wglCreatePbufferARB_Impl, wglCreatePbufferARB); + GLELoadProc(wglGetPbufferDCARB_Impl, wglGetPbufferDCARB); + GLELoadProc(wglReleasePbufferDCARB_Impl, wglReleasePbufferDCARB); + GLELoadProc(wglDestroyPbufferARB_Impl, wglDestroyPbufferARB); + GLELoadProc(wglQueryPbufferARB_Impl, wglQueryPbufferARB); + + // WGL_ARB_render_texture + GLELoadProc(wglBindTexImageARB_Impl, wglBindTexImageARB); + GLELoadProc(wglReleaseTexImageARB_Impl, wglReleaseTexImageARB); + GLELoadProc(wglSetPbufferAttribARB_Impl, wglSetPbufferAttribARB); + + // WGL_NV_present_video + GLELoadProc(wglEnumerateVideoDevicesNV_Impl, wglEnumerateVideoDevicesNV); + GLELoadProc(wglBindVideoDeviceNV_Impl, wglBindVideoDeviceNV); + GLELoadProc(wglQueryCurrentContextNV_Impl, wglQueryCurrentContextNV); + + // WGL_ARB_create_context + GLELoadProc(wglCreateContextAttribsARB_Impl, wglCreateContextAttribsARB); + + // WGL_EXT_extensions_string + GLELoadProc(wglGetExtensionsStringEXT_Impl, wglGetExtensionsStringEXT); + + // WGL_EXT_swap_control + GLELoadProc(wglGetSwapIntervalEXT_Impl, wglGetSwapIntervalEXT); + GLELoadProc(wglSwapIntervalEXT_Impl, wglSwapIntervalEXT); + + // WGL_OML_sync_control + GLELoadProc(wglGetSyncValuesOML_Impl, wglGetSyncValuesOML); + GLELoadProc(wglGetMscRateOML_Impl, wglGetMscRateOML); + GLELoadProc(wglSwapBuffersMscOML_Impl, wglSwapBuffersMscOML); + GLELoadProc(wglSwapLayerBuffersMscOML_Impl, wglSwapLayerBuffersMscOML); + GLELoadProc(wglWaitForMscOML_Impl, wglWaitForMscOML); + GLELoadProc(wglWaitForSbcOML_Impl, wglWaitForSbcOML); + + // WGL_NV_video_output + GLELoadProc(wglGetVideoDeviceNV_Impl, wglGetVideoDeviceNV); + GLELoadProc(wglReleaseVideoDeviceNV_Impl, wglReleaseVideoDeviceNV); + GLELoadProc(wglBindVideoImageNV_Impl, wglBindVideoImageNV); + GLELoadProc(wglReleaseVideoImageNV_Impl, wglReleaseVideoImageNV); + GLELoadProc(wglSendPbufferToVideoNV_Impl, wglSendPbufferToVideoNV); + GLELoadProc(wglGetVideoInfoNV_Impl, wglGetVideoInfoNV); + + // WGL_NV_swap_group + GLELoadProc(wglJoinSwapGroupNV_Impl, wglJoinSwapGroupNV); + GLELoadProc(wglBindSwapBarrierNV_Impl, wglBindSwapBarrierNV); + GLELoadProc(wglQuerySwapGroupNV_Impl, wglQuerySwapGroupNV); + GLELoadProc(wglQueryMaxSwapGroupsNV_Impl, wglQueryMaxSwapGroupsNV); + GLELoadProc(wglQueryFrameCountNV_Impl, wglQueryFrameCountNV); + GLELoadProc(wglResetFrameCountNV_Impl, wglResetFrameCountNV); + + // WGL_NV_video_capture + GLELoadProc(wglBindVideoCaptureDeviceNV_Impl, wglBindVideoCaptureDeviceNV); + GLELoadProc(wglEnumerateVideoCaptureDevicesNV_Impl, wglEnumerateVideoCaptureDevicesNV); + GLELoadProc(wglLockVideoCaptureDeviceNV_Impl, wglLockVideoCaptureDeviceNV); + GLELoadProc(wglQueryVideoCaptureDeviceNV_Impl, wglQueryVideoCaptureDeviceNV); + GLELoadProc(wglReleaseVideoCaptureDeviceNV_Impl, wglReleaseVideoCaptureDeviceNV); + + // WGL_NV_copy_image + GLELoadProc(wglCopyImageSubDataNV_Impl, wglCopyImageSubDataNV); + + // WGL_NV_DX_interop + GLELoadProc(wglDXCloseDeviceNV_Impl, wglDXCloseDeviceNV); + GLELoadProc(wglDXLockObjectsNV_Impl, wglDXLockObjectsNV); + GLELoadProc(wglDXObjectAccessNV_Impl, wglDXObjectAccessNV); + GLELoadProc(wglDXOpenDeviceNV_Impl, wglDXOpenDeviceNV); + GLELoadProc(wglDXRegisterObjectNV_Impl, wglDXRegisterObjectNV); + GLELoadProc(wglDXSetResourceShareHandleNV_Impl, wglDXSetResourceShareHandleNV); + GLELoadProc(wglDXUnlockObjectsNV_Impl, wglDXUnlockObjectsNV); + GLELoadProc(wglDXUnregisterObjectNV_Impl, wglDXUnregisterObjectNV); + +#elif defined(GLE_GLX_ENABLED) + // GLX_VERSION_1_1 + // We don't create any pointers_Impl, because we assume these functions are always present. + + // GLX_VERSION_1_2 + GLELoadProc(glXGetCurrentDisplay_Impl, glXGetCurrentDisplay); + + // GLX_VERSION_1_3 + GLELoadProc(glXChooseFBConfig_Impl, glXChooseFBConfig); + GLELoadProc(glXCreateNewContext_Impl, glXCreateNewContext); + GLELoadProc(glXCreatePbuffer_Impl, glXCreatePbuffer); + GLELoadProc(glXCreatePixmap_Impl, glXCreatePixmap); + GLELoadProc(glXCreateWindow_Impl, glXCreateWindow); + GLELoadProc(glXDestroyPbuffer_Impl, glXDestroyPbuffer); + GLELoadProc(glXDestroyPixmap_Impl, glXDestroyPixmap); + GLELoadProc(glXDestroyWindow_Impl, glXDestroyWindow); + GLELoadProc(glXGetCurrentReadDrawable_Impl, glXGetCurrentReadDrawable); + GLELoadProc(glXGetFBConfigAttrib_Impl, glXGetFBConfigAttrib); + GLELoadProc(glXGetFBConfigs_Impl, glXGetFBConfigs); + GLELoadProc(glXGetSelectedEvent_Impl, glXGetSelectedEvent); + GLELoadProc(glXGetVisualFromFBConfig_Impl, glXGetVisualFromFBConfig); + GLELoadProc(glXMakeContextCurrent_Impl, glXMakeContextCurrent); + GLELoadProc(glXQueryContext_Impl, glXQueryContext); + GLELoadProc(glXQueryDrawable_Impl, glXQueryDrawable); + GLELoadProc(glXSelectEvent_Impl, glXSelectEvent); + + // GLX_VERSION_1_4 + // Nothing to declare + + // GLX_ARB_create_context + GLELoadProc(glXCreateContextAttribsARB_Impl, glXCreateContextAttribsARB); + + // GLX_EXT_swap_control + GLELoadProc(glXSwapIntervalEXT_Impl, glXSwapIntervalEXT); + + // GLX_OML_sync_control + GLELoadProc(glXGetMscRateOML_Impl, glXGetMscRateOML); + GLELoadProc(glXGetSyncValuesOML_Impl, glXGetSyncValuesOML); + GLELoadProc(glXGetSyncValuesOML_Impl, glXSwapBuffersMscOML); + GLELoadProc(glXSwapBuffersMscOML_Impl, glXSwapBuffersMscOML); + GLELoadProc(glXWaitForSbcOML_Impl, glXWaitForSbcOML); + + // GLX_MESA_swap_control + GLELoadProc(glXGetSwapIntervalMESA_Impl, glXGetSwapIntervalMESA); + GLELoadProc(glXSwapIntervalMESA_Impl, glXSwapIntervalMESA); +#endif +} + +void OVR::GLEContext::InitPlatformExtensionSupport() { +#if defined(GLE_WGL_ENABLED) + // We need to use wglGetExtensionsStringARB or wglGetExtensionsStringEXT as opposed to above with + // glGetString(GL_EXTENSIONS). + ValueStringPair vspWGLArray[] = { + {gle_WGL_ARB_buffer_region, "WGL_ARB_buffer_region"}, + {gle_WGL_ARB_create_context, "WGL_ARB_create_context"}, + {gle_WGL_ARB_create_context_profile, "WGL_ARB_create_context_profile"}, + {gle_WGL_ARB_create_context_robustness, "WGL_ARB_create_context_robustness"}, + {gle_WGL_ARB_extensions_string, "WGL_ARB_extensions_string"}, + {gle_WGL_ARB_framebuffer_sRGB, "WGL_ARB_framebuffer_sRGB"}, + {gle_WGL_ARB_framebuffer_sRGB, "WGL_EXT_framebuffer_sRGB"} // We map the EXT to the ARB. + , + {gle_WGL_ARB_make_current_read, "WGL_ARB_make_current_read"}, + {gle_WGL_ARB_pbuffer, "WGL_ARB_pbuffer"}, + {gle_WGL_ARB_pixel_format, "WGL_ARB_pixel_format"}, + {gle_WGL_ARB_pixel_format_float, "WGL_ARB_pixel_format_float"}, + {gle_WGL_ARB_render_texture, "WGL_ARB_render_texture"}, + {gle_WGL_ATI_render_texture_rectangle, "WGL_ATI_render_texture_rectangle"}, + {gle_WGL_EXT_extensions_string, "WGL_EXT_extensions_string"}, + {gle_WGL_EXT_swap_control, "WGL_EXT_swap_control"}, + {gle_WGL_NV_copy_image, "WGL_NV_copy_image"}, + {gle_WGL_NV_DX_interop, "WGL_NV_DX_interop"}, + {gle_WGL_NV_DX_interop2, "WGL_NV_DX_interop2"}, + {gle_WGL_NV_present_video, "WGL_NV_present_video"}, + {gle_WGL_NV_render_texture_rectangle, "WGL_NV_render_texture_rectangle"}, + {gle_WGL_NV_swap_group, "WGL_NV_swap_group"}, + {gle_WGL_NV_video_capture, "WGL_NV_video_capture"}, + {gle_WGL_NV_video_output, "WGL_NV_video_output"}, + {gle_WGL_OML_sync_control, "WGL_OML_sync_control"}}; + + const char* extensions = NULL; + + if (wglGetExtensionsStringARB_Impl) + extensions = wglGetExtensionsStringARB_Impl( + wglGetCurrentDC()); // To do: Use a better mechanism to get the desired HDC. + else if (wglGetExtensionsStringEXT_Impl) + extensions = wglGetExtensionsStringEXT_Impl(); + + if (extensions && *extensions) { + OVR_DEBUG_LOG(("WGL_EXTENSIONS: %s", (const char*)extensions)); + CheckExtensions(vspWGLArray, OVR_ARRAY_COUNT(vspWGLArray), extensions); + } + +#elif defined(GLE_GLX_ENABLED) + ValueStringPair vspGLXArray[] = { + {gle_GLX_ARB_create_context, "GLX_ARB_create_context"}, + {gle_GLX_ARB_create_context_profile, "GLX_ARB_create_context_profile"}, + {gle_GLX_ARB_create_context_robustness, "GLX_ARB_create_context_robustness"}, + {gle_GLX_EXT_swap_control, "GLX_EXT_swap_control"}, + {gle_GLX_OML_sync_control, "GLX_OML_sync_control"}, + {gle_MESA_swap_control, "GLX_MESA_swap_control"}}; + + const char* extensions = glXGetClientString( + glXGetCurrentDisplay(), + GLX_EXTENSIONS); // To do: Use a better mechanism to get the desired display. + + if (extensions && *extensions) { + OVR_DEBUG_LOG(("GLX_EXTENSIONS: %s", (const char*)extensions)); + CheckExtensions(vspGLXArray, OVR_ARRAY_COUNT(vspGLXArray), extensions); + } +#endif +} + +#if defined(GLE_HOOKING_ENABLED) + +#undef glGetError +extern "C" { +GLAPI GLenum GLAPIENTRY glGetError(); +} + +// Disabled until such time as it might be useful to enable for debug purposes. +// void OVR::GLEContext::PreHook(const char* functionName) +//{ +// if(EnableHookGetError) +// { +// int err = glGetError(); +// +// for(int i = 0; (i < 6) && (err != GL_NO_ERROR); i++) // 6 is an arbitrary cap to prevent +// infinite looping which would occur if the current GL context is invalid. +// { +// OVR_DEBUG_LOG(("GL Error prior to hook: %d (%#x) from %s", err, err, functionName ? +// functionName : "OpenGL")); OVR_UNUSED(functionName); err = glGetError(); +// } +// } +//} + +void OVR::GLEContext::PostHook(const char* functionName) { + if (EnableHookGetError) { + // OpenGL Standard regarding error state: To allow for distributed implementations, there may be + // several error flags. If any single error flag has recorded an error, the value of that flag + // is returned and that flag is reset to GL_NO_ERROR when glGetError is called. If more than one + // flag has recorded an error, glGetError returns and clears an arbitrary error flag value. + // Thus, glGetError should always be called in a loop, until it returns GL_NO_ERROR, if all + // error flags are to be reset. + int err = glGetError(); + + for (int i = 0; (i < 6) && (err != GL_NO_ERROR); i++) // 6 is an arbitrary cap to prevent + // infinite looping which would occur if + // the current GL context is invalid. + { + OVR_DEBUG_LOG( + ("GL Error: %d (%#x) from %s", err, err, functionName ? functionName : "OpenGL")); + OVR_UNUSED(functionName); + err = glGetError(); + } + } +} + +// OpenGL 1.1 link-based functions +#undef glAccum // Undefine the macro from our header so that we can directly call the real version +// of this function. +extern "C" { +GLAPI void GLAPIENTRY glAccum(GLenum op, GLfloat value); +} +void OVR::GLEContext::glAccum_Hook(GLenum op, GLfloat value) { + glAccum(op, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glAlphaFunc +extern "C" { +GLAPI void GLAPIENTRY glAlphaFunc(GLenum func, GLclampf ref); +} +void OVR::GLEContext::glAlphaFunc_Hook(GLenum func, GLclampf ref) { + glAlphaFunc(func, ref); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glAreTexturesResident +extern "C" { +GLAPI GLboolean GLAPIENTRY +glAreTexturesResident(GLsizei n, const GLuint* textures, GLboolean* residences); +} +GLboolean OVR::GLEContext::glAreTexturesResident_Hook( + GLsizei n, + const GLuint* textures, + GLboolean* residences) { + GLboolean b = glAreTexturesResident(n, textures, residences); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef glArrayElement +extern "C" { +GLAPI void GLAPIENTRY glArrayElement(GLint i); +} +void OVR::GLEContext::glArrayElement_Hook(GLint i) { + glArrayElement(i); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glBegin +extern "C" { +GLAPI void GLAPIENTRY glBegin(GLenum mode); +} +void OVR::GLEContext::glBegin_Hook(GLenum mode) { + glBegin(mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glBindTexture +extern "C" { +GLAPI void GLAPIENTRY glBindTexture(GLenum target, GLuint texture); +} +void OVR::GLEContext::glBindTexture_Hook(GLenum target, GLuint texture) { + glBindTexture(target, texture); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glBitmap +extern "C" { +GLAPI void GLAPIENTRY glBitmap( + GLsizei width, + GLsizei height, + GLfloat xorig, + GLfloat yorig, + GLfloat xmove, + GLfloat ymove, + const GLubyte* bitmap); +} +void OVR::GLEContext::glBitmap_Hook( + GLsizei width, + GLsizei height, + GLfloat xorig, + GLfloat yorig, + GLfloat xmove, + GLfloat ymove, + const GLubyte* bitmap) { + glBitmap(width, height, xorig, yorig, xmove, ymove, bitmap); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glBlendFunc +extern "C" { +GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor); +} +void OVR::GLEContext::glBlendFunc_Hook(GLenum sfactor, GLenum dfactor) { + glBlendFunc(sfactor, dfactor); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glCallList +extern "C" { +GLAPI void GLAPIENTRY glCallList(GLuint list); +} +void OVR::GLEContext::glCallList_Hook(GLuint list) { + glCallList(list); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glCallLists +extern "C" { +GLAPI void GLAPIENTRY glCallLists(GLsizei n, GLenum type, const void* lists); +} +void OVR::GLEContext::glCallLists_Hook(GLsizei n, GLenum type, const void* lists) { + glCallLists(n, type, lists); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glClear +extern "C" { +GLAPI void GLAPIENTRY glClear(GLbitfield mask); +} +void OVR::GLEContext::glClear_Hook(GLbitfield mask) { + glClear(mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glClearAccum +extern "C" { +GLAPI void GLAPIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +} +void OVR::GLEContext::glClearAccum_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + glClearAccum(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glClearColor +extern "C" { +GLAPI void GLAPIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +} +void OVR::GLEContext::glClearColor_Hook( + GLclampf red, + GLclampf green, + GLclampf blue, + GLclampf alpha) { + glClearColor(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glClearDepth +extern "C" { +GLAPI void GLAPIENTRY glClearDepth(GLclampd depth); +} +void OVR::GLEContext::glClearDepth_Hook(GLclampd depth) { + glClearDepth(depth); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glClearIndex +extern "C" { +GLAPI void GLAPIENTRY glClearIndex(GLfloat c); +} +void OVR::GLEContext::glClearIndex_Hook(GLfloat c) { + glClearIndex(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glClearStencil +extern "C" { +GLAPI void GLAPIENTRY glClearStencil(GLint s); +} +void OVR::GLEContext::glClearStencil_Hook(GLint s) { + glClearStencil(s); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glClipPlane +extern "C" { +GLAPI void GLAPIENTRY glClipPlane(GLenum plane, const GLdouble* equation); +} +void OVR::GLEContext::glClipPlane_Hook(GLenum plane, const GLdouble* equation) { + glClipPlane(plane, equation); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3b +extern "C" { +GLAPI void GLAPIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue); +} +void OVR::GLEContext::glColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue) { + glColor3b(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3bv +extern "C" { +GLAPI void GLAPIENTRY glColor3bv(const GLbyte* v); +} +void OVR::GLEContext::glColor3bv_Hook(const GLbyte* v) { + glColor3bv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3d +extern "C" { +GLAPI void GLAPIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue); +} +void OVR::GLEContext::glColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue) { + glColor3d(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3dv +extern "C" { +GLAPI void GLAPIENTRY glColor3dv(const GLdouble* v); +} +void OVR::GLEContext::glColor3dv_Hook(const GLdouble* v) { + glColor3dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3f +extern "C" { +GLAPI void GLAPIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue); +} +void OVR::GLEContext::glColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue) { + glColor3f(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3fv +extern "C" { +GLAPI void GLAPIENTRY glColor3fv(const GLfloat* v); +} +void OVR::GLEContext::glColor3fv_Hook(const GLfloat* v) { + glColor3fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3i +extern "C" { +GLAPI void GLAPIENTRY glColor3i(GLint red, GLint green, GLint blue); +} +void OVR::GLEContext::glColor3i_Hook(GLint red, GLint green, GLint blue) { + glColor3i(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3iv +extern "C" { +GLAPI void GLAPIENTRY glColor3iv(const GLint* v); +} +void OVR::GLEContext::glColor3iv_Hook(const GLint* v) { + glColor3iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3s +extern "C" { +GLAPI void GLAPIENTRY glColor3s(GLshort red, GLshort green, GLshort blue); +} +void OVR::GLEContext::glColor3s_Hook(GLshort red, GLshort green, GLshort blue) { + glColor3s(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3sv +extern "C" { +GLAPI void GLAPIENTRY glColor3sv(const GLshort* v); +} +void OVR::GLEContext::glColor3sv_Hook(const GLshort* v) { + glColor3sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3ub +extern "C" { +GLAPI void GLAPIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue); +} +void OVR::GLEContext::glColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue) { + glColor3ub(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3ubv +extern "C" { +GLAPI void GLAPIENTRY glColor3ubv(const GLubyte* v); +} +void OVR::GLEContext::glColor3ubv_Hook(const GLubyte* v) { + glColor3ubv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3ui +extern "C" { +GLAPI void GLAPIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue); +} +void OVR::GLEContext::glColor3ui_Hook(GLuint red, GLuint green, GLuint blue) { + glColor3ui(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3uiv +extern "C" { +GLAPI void GLAPIENTRY glColor3uiv(const GLuint* v); +} +void OVR::GLEContext::glColor3uiv_Hook(const GLuint* v) { + glColor3uiv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3us +extern "C" { +GLAPI void GLAPIENTRY glColor3us(GLushort red, GLushort green, GLushort blue); +} +void OVR::GLEContext::glColor3us_Hook(GLushort red, GLushort green, GLushort blue) { + glColor3us(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor3usv +extern "C" { +GLAPI void GLAPIENTRY glColor3usv(const GLushort* v); +} +void OVR::GLEContext::glColor3usv_Hook(const GLushort* v) { + glColor3usv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4b +extern "C" { +GLAPI void GLAPIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +} +void OVR::GLEContext::glColor4b_Hook(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) { + glColor4b(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4bv +extern "C" { +GLAPI void GLAPIENTRY glColor4bv(const GLbyte* v); +} +void OVR::GLEContext::glColor4bv_Hook(const GLbyte* v) { + glColor4bv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4d +extern "C" { +GLAPI void GLAPIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +} +void OVR::GLEContext::glColor4d_Hook(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) { + glColor4d(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4dv +extern "C" { +GLAPI void GLAPIENTRY glColor4dv(const GLdouble* v); +} +void OVR::GLEContext::glColor4dv_Hook(const GLdouble* v) { + glColor4dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4f +extern "C" { +GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +} +void OVR::GLEContext::glColor4f_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + glColor4f(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4fv +extern "C" { +GLAPI void GLAPIENTRY glColor4fv(const GLfloat* v); +} +void OVR::GLEContext::glColor4fv_Hook(const GLfloat* v) { + glColor4fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4i +extern "C" { +GLAPI void GLAPIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha); +} +void OVR::GLEContext::glColor4i_Hook(GLint red, GLint green, GLint blue, GLint alpha) { + glColor4i(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4iv +extern "C" { +GLAPI void GLAPIENTRY glColor4iv(const GLint* v); +} +void OVR::GLEContext::glColor4iv_Hook(const GLint* v) { + glColor4iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4s +extern "C" { +GLAPI void GLAPIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha); +} +void OVR::GLEContext::glColor4s_Hook(GLshort red, GLshort green, GLshort blue, GLshort alpha) { + glColor4s(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4sv +extern "C" { +GLAPI void GLAPIENTRY glColor4sv(const GLshort* v); +} +void OVR::GLEContext::glColor4sv_Hook(const GLshort* v) { + glColor4sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4ub +extern "C" { +GLAPI void GLAPIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +} +void OVR::GLEContext::glColor4ub_Hook(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) { + glColor4ub(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4ubv +extern "C" { +GLAPI void GLAPIENTRY glColor4ubv(const GLubyte* v); +} +void OVR::GLEContext::glColor4ubv_Hook(const GLubyte* v) { + glColor4ubv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4ui +extern "C" { +GLAPI void GLAPIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha); +} +void OVR::GLEContext::glColor4ui_Hook(GLuint red, GLuint green, GLuint blue, GLuint alpha) { + glColor4ui(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4uiv +extern "C" { +GLAPI void GLAPIENTRY glColor4uiv(const GLuint* v); +} +void OVR::GLEContext::glColor4uiv_Hook(const GLuint* v) { + glColor4uiv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4us +extern "C" { +GLAPI void GLAPIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha); +} +void OVR::GLEContext::glColor4us_Hook(GLushort red, GLushort green, GLushort blue, GLushort alpha) { + glColor4us(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColor4usv +extern "C" { +GLAPI void GLAPIENTRY glColor4usv(const GLushort* v); +} +void OVR::GLEContext::glColor4usv_Hook(const GLushort* v) { + glColor4usv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColorMask +extern "C" { +GLAPI void GLAPIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +} +void OVR::GLEContext::glColorMask_Hook( + GLboolean red, + GLboolean green, + GLboolean blue, + GLboolean alpha) { + glColorMask(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColorMaterial +extern "C" { +GLAPI void GLAPIENTRY glColorMaterial(GLenum face, GLenum mode); +} +void OVR::GLEContext::glColorMaterial_Hook(GLenum face, GLenum mode) { + glColorMaterial(face, mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glColorPointer +extern "C" { +GLAPI void GLAPIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const void* pointer); +} +void OVR::GLEContext::glColorPointer_Hook( + GLint size, + GLenum type, + GLsizei stride, + const void* pointer) { + glColorPointer(size, type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glCopyPixels +extern "C" { +GLAPI void GLAPIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +} +void OVR::GLEContext::glCopyPixels_Hook( + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum type) { + glCopyPixels(x, y, width, height, type); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glCopyTexImage1D +extern "C" { +GLAPI void GLAPIENTRY glCopyTexImage1D( + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLint border); +} +void OVR::GLEContext::glCopyTexImage1D_Hook( + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLint border) { + glCopyTexImage1D(target, level, internalFormat, x, y, width, border); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glCopyTexImage2D +extern "C" { +GLAPI void GLAPIENTRY glCopyTexImage2D( + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); +} +void OVR::GLEContext::glCopyTexImage2D_Hook( + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) { + glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glCopyTexSubImage1D +extern "C" { +GLAPI void GLAPIENTRY +glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +} +void OVR::GLEContext::glCopyTexSubImage1D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width) { + glCopyTexSubImage1D(target, level, xoffset, x, y, width); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glCopyTexSubImage2D +extern "C" { +GLAPI void GLAPIENTRY glCopyTexSubImage2D( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +} +void OVR::GLEContext::glCopyTexSubImage2D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { + glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glCullFace +extern "C" { +GLAPI void GLAPIENTRY glCullFace(GLenum mode); +} +void OVR::GLEContext::glCullFace_Hook(GLenum mode) { + glCullFace(mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDeleteLists +extern "C" { +GLAPI void GLAPIENTRY glDeleteLists(GLuint list, GLsizei range); +} +void OVR::GLEContext::glDeleteLists_Hook(GLuint list, GLsizei range) { + glDeleteLists(list, range); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDeleteTextures +extern "C" { +GLAPI void GLAPIENTRY glDeleteTextures(GLsizei n, const GLuint* textures); +} +void OVR::GLEContext::glDeleteTextures_Hook(GLsizei n, const GLuint* textures) { + glDeleteTextures(n, textures); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDepthFunc +extern "C" { +GLAPI void GLAPIENTRY glDepthFunc(GLenum func); +} +void OVR::GLEContext::glDepthFunc_Hook(GLenum func) { + glDepthFunc(func); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDepthMask +extern "C" { +GLAPI void GLAPIENTRY glDepthMask(GLboolean flag); +} +void OVR::GLEContext::glDepthMask_Hook(GLboolean flag) { + glDepthMask(flag); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDepthRange +extern "C" { +GLAPI void GLAPIENTRY glDepthRange(GLclampd zNear, GLclampd zFar); +} +void OVR::GLEContext::glDepthRange_Hook(GLclampd zNear, GLclampd zFar) { + glDepthRange(zNear, zFar); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDisable +extern "C" { +GLAPI void GLAPIENTRY glDisable(GLenum cap); +} +void OVR::GLEContext::glDisable_Hook(GLenum cap) { + glDisable(cap); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDisableClientState +extern "C" { +GLAPI void GLAPIENTRY glDisableClientState(GLenum array); +} +void OVR::GLEContext::glDisableClientState_Hook(GLenum array) { + glDisableClientState(array); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDrawArrays +extern "C" { +GLAPI void GLAPIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count); +} +void OVR::GLEContext::glDrawArrays_Hook(GLenum mode, GLint first, GLsizei count) { + glDrawArrays(mode, first, count); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDrawBuffer +extern "C" { +GLAPI void GLAPIENTRY glDrawBuffer(GLenum mode); +} +void OVR::GLEContext::glDrawBuffer_Hook(GLenum mode) { + glDrawBuffer(mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDrawElements +extern "C" { +GLAPI void GLAPIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices); +} +void OVR::GLEContext::glDrawElements_Hook( + GLenum mode, + GLsizei count, + GLenum type, + const void* indices) { + glDrawElements(mode, count, type, indices); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glDrawPixels +extern "C" { +GLAPI void GLAPIENTRY +glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +} +void OVR::GLEContext::glDrawPixels_Hook( + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void* pixels) { + glDrawPixels(width, height, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEdgeFlag +extern "C" { +GLAPI void GLAPIENTRY glEdgeFlag(GLboolean flag); +} +void OVR::GLEContext::glEdgeFlag_Hook(GLboolean flag) { + glEdgeFlag(flag); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEdgeFlagPointer +extern "C" { +GLAPI void GLAPIENTRY glEdgeFlagPointer(GLsizei stride, const void* pointer); +} +void OVR::GLEContext::glEdgeFlagPointer_Hook(GLsizei stride, const void* pointer) { + glEdgeFlagPointer(stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEdgeFlagv +extern "C" { +GLAPI void GLAPIENTRY glEdgeFlagv(const GLboolean* flag); +} +void OVR::GLEContext::glEdgeFlagv_Hook(const GLboolean* flag) { + glEdgeFlagv(flag); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEnable +extern "C" { +GLAPI void GLAPIENTRY glEnable(GLenum cap); +} +namespace OVR { +void GLEContext::glEnable_Hook(GLenum cap) { + glEnable(cap); + PostHook(GLE_CURRENT_FUNCTION); +} +} // namespace OVR + +#undef glEnableClientState +extern "C" { +GLAPI void GLAPIENTRY glEnableClientState(GLenum array); +} +void OVR::GLEContext::glEnableClientState_Hook(GLenum array) { + glEnableClientState(array); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEnd +extern "C" { +GLAPI void GLAPIENTRY glEnd(); +} +void OVR::GLEContext::glEnd_Hook() { + glEnd(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEndList +extern "C" { +GLAPI void GLAPIENTRY glEndList(); +} +void OVR::GLEContext::glEndList_Hook() { + glEndList(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalCoord1d +extern "C" { +GLAPI void GLAPIENTRY glEvalCoord1d(GLdouble u); +} +void OVR::GLEContext::glEvalCoord1d_Hook(GLdouble u) { + glEvalCoord1d(u); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalCoord1dv +extern "C" { +GLAPI void GLAPIENTRY glEvalCoord1dv(const GLdouble* u); +} +void OVR::GLEContext::glEvalCoord1dv_Hook(const GLdouble* u) { + glEvalCoord1dv(u); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalCoord1f +extern "C" { +GLAPI void GLAPIENTRY glEvalCoord1f(GLfloat u); +} +void OVR::GLEContext::glEvalCoord1f_Hook(GLfloat u) { + glEvalCoord1f(u); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalCoord1fv +extern "C" { +GLAPI void GLAPIENTRY glEvalCoord1fv(const GLfloat* u); +} +void OVR::GLEContext::glEvalCoord1fv_Hook(const GLfloat* u) { + glEvalCoord1fv(u); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalCoord2d +extern "C" { +GLAPI void GLAPIENTRY glEvalCoord2d(GLdouble u, GLdouble v); +} +void OVR::GLEContext::glEvalCoord2d_Hook(GLdouble u, GLdouble v) { + glEvalCoord2d(u, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalCoord2dv +extern "C" { +GLAPI void GLAPIENTRY glEvalCoord2dv(const GLdouble* u); +} +void OVR::GLEContext::glEvalCoord2dv_Hook(const GLdouble* u) { + glEvalCoord2dv(u); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalCoord2f +extern "C" { +GLAPI void GLAPIENTRY glEvalCoord2f(GLfloat u, GLfloat v); +} +void OVR::GLEContext::glEvalCoord2f_Hook(GLfloat u, GLfloat v) { + glEvalCoord2f(u, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalCoord2fv +extern "C" { +GLAPI void GLAPIENTRY glEvalCoord2fv(const GLfloat* u); +} +void OVR::GLEContext::glEvalCoord2fv_Hook(const GLfloat* u) { + glEvalCoord2fv(u); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalMesh1 +extern "C" { +GLAPI void GLAPIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2); +} +void OVR::GLEContext::glEvalMesh1_Hook(GLenum mode, GLint i1, GLint i2) { + glEvalMesh1(mode, i1, i2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalMesh2 +extern "C" { +GLAPI void GLAPIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +} +void OVR::GLEContext::glEvalMesh2_Hook(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) { + glEvalMesh2(mode, i1, i2, j1, j2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalPoint1 +extern "C" { +GLAPI void GLAPIENTRY glEvalPoint1(GLint i); +} +void OVR::GLEContext::glEvalPoint1_Hook(GLint i) { + glEvalPoint1(i); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glEvalPoint2 +extern "C" { +GLAPI void GLAPIENTRY glEvalPoint2(GLint i, GLint j); +} +void OVR::GLEContext::glEvalPoint2_Hook(GLint i, GLint j) { + glEvalPoint2(i, j); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glFeedbackBuffer +extern "C" { +GLAPI void GLAPIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat* buffer); +} +void OVR::GLEContext::glFeedbackBuffer_Hook(GLsizei size, GLenum type, GLfloat* buffer) { + glFeedbackBuffer(size, type, buffer); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glFinish +extern "C" { +GLAPI void GLAPIENTRY glFinish(); +} +void OVR::GLEContext::glFinish_Hook() { + glFinish(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glFlush +extern "C" { +GLAPI void GLAPIENTRY glFlush(); +} +void OVR::GLEContext::glFlush_Hook() { + glFlush(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glFogf +extern "C" { +GLAPI void GLAPIENTRY glFogf(GLenum pname, GLfloat param); +} +void OVR::GLEContext::glFogf_Hook(GLenum pname, GLfloat param) { + glFogf(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glFogfv +extern "C" { +GLAPI void GLAPIENTRY glFogfv(GLenum pname, const GLfloat* params); +} +void OVR::GLEContext::glFogfv_Hook(GLenum pname, const GLfloat* params) { + glFogfv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glFogi +extern "C" { +GLAPI void GLAPIENTRY glFogi(GLenum pname, GLint param); +} +void OVR::GLEContext::glFogi_Hook(GLenum pname, GLint param) { + glFogi(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glFogiv +extern "C" { +GLAPI void GLAPIENTRY glFogiv(GLenum pname, const GLint* params); +} +void OVR::GLEContext::glFogiv_Hook(GLenum pname, const GLint* params) { + glFogiv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glFrontFace +extern "C" { +GLAPI void GLAPIENTRY glFrontFace(GLenum mode); +} +void OVR::GLEContext::glFrontFace_Hook(GLenum mode) { + glFrontFace(mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glFrustum +extern "C" { +GLAPI void GLAPIENTRY glFrustum( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar); +} +void OVR::GLEContext::glFrustum_Hook( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar) { + glFrustum(left, right, bottom, top, zNear, zFar); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGenLists +extern "C" { +GLAPI GLuint GLAPIENTRY glGenLists(GLsizei range); +} +GLuint OVR::GLEContext::glGenLists_Hook(GLsizei range) { + GLuint u = glGenLists(range); + PostHook(GLE_CURRENT_FUNCTION); + return u; +} + +#undef glGenTextures +extern "C" { +GLAPI void GLAPIENTRY glGenTextures(GLsizei n, GLuint* textures); +} +void OVR::GLEContext::glGenTextures_Hook(GLsizei n, GLuint* textures) { + glGenTextures(n, textures); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetBooleanv +extern "C" { +GLAPI void GLAPIENTRY glGetBooleanv(GLenum pname, GLboolean* params); +} +void OVR::GLEContext::glGetBooleanv_Hook(GLenum pname, GLboolean* params) { + glGetBooleanv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetClipPlane +extern "C" { +GLAPI void GLAPIENTRY glGetClipPlane(GLenum plane, GLdouble* equation); +} +void OVR::GLEContext::glGetClipPlane_Hook(GLenum plane, GLdouble* equation) { + glGetClipPlane(plane, equation); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetDoublev +extern "C" { +GLAPI void GLAPIENTRY glGetDoublev(GLenum pname, GLdouble* params); +} +void OVR::GLEContext::glGetDoublev_Hook(GLenum pname, GLdouble* params) { + glGetDoublev(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +//#undef glGetError Not needed because we happen to do this above already. +// extern "C" { GLAPI GLenum GLAPIENTRY glGetError(); } +GLenum OVR::GLEContext::glGetError_Hook() { + GLenum e = glGetError(); + PostHook(GLE_CURRENT_FUNCTION); + return e; +} + +#undef glGetFloatv +extern "C" { +GLAPI void GLAPIENTRY glGetFloatv(GLenum pname, GLfloat* params); +} +void OVR::GLEContext::glGetFloatv_Hook(GLenum pname, GLfloat* params) { + glGetFloatv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetIntegerv +extern "C" { +GLAPI void GLAPIENTRY glGetIntegerv(GLenum pname, GLint* params); +} +void OVR::GLEContext::glGetIntegerv_Hook(GLenum pname, GLint* params) { + glGetIntegerv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetLightfv +extern "C" { +GLAPI void GLAPIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat* params); +} +void OVR::GLEContext::glGetLightfv_Hook(GLenum light, GLenum pname, GLfloat* params) { + glGetLightfv(light, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetLightiv +extern "C" { +GLAPI void GLAPIENTRY glGetLightiv(GLenum light, GLenum pname, GLint* params); +} +void OVR::GLEContext::glGetLightiv_Hook(GLenum light, GLenum pname, GLint* params) { + glGetLightiv(light, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetMapdv +extern "C" { +GLAPI void GLAPIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble* v); +} +void OVR::GLEContext::glGetMapdv_Hook(GLenum target, GLenum query, GLdouble* v) { + glGetMapdv(target, query, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetMapfv +extern "C" { +GLAPI void GLAPIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat* v); +} +void OVR::GLEContext::glGetMapfv_Hook(GLenum target, GLenum query, GLfloat* v) { + glGetMapfv(target, query, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetMapiv +extern "C" { +GLAPI void GLAPIENTRY glGetMapiv(GLenum target, GLenum query, GLint* v); +} +void OVR::GLEContext::glGetMapiv_Hook(GLenum target, GLenum query, GLint* v) { + glGetMapiv(target, query, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetMaterialfv +extern "C" { +GLAPI void GLAPIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat* params); +} +void OVR::GLEContext::glGetMaterialfv_Hook(GLenum face, GLenum pname, GLfloat* params) { + glGetMaterialfv(face, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetMaterialiv +extern "C" { +GLAPI void GLAPIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint* params); +} +void OVR::GLEContext::glGetMaterialiv_Hook(GLenum face, GLenum pname, GLint* params) { + glGetMaterialiv(face, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetPixelMapfv +extern "C" { +GLAPI void GLAPIENTRY glGetPixelMapfv(GLenum map, GLfloat* values); +} +void OVR::GLEContext::glGetPixelMapfv_Hook(GLenum map, GLfloat* values) { + glGetPixelMapfv(map, values); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetPixelMapuiv +extern "C" { +GLAPI void GLAPIENTRY glGetPixelMapuiv(GLenum map, GLuint* values); +} +void OVR::GLEContext::glGetPixelMapuiv_Hook(GLenum map, GLuint* values) { + glGetPixelMapuiv(map, values); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetPixelMapusv +extern "C" { +GLAPI void GLAPIENTRY glGetPixelMapusv(GLenum map, GLushort* values); +} +void OVR::GLEContext::glGetPixelMapusv_Hook(GLenum map, GLushort* values) { + glGetPixelMapusv(map, values); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetPointerv +extern "C" { +GLAPI void GLAPIENTRY glGetPointerv(GLenum pname, void** params); +} +void OVR::GLEContext::glGetPointerv_Hook(GLenum pname, void** params) { + glGetPointerv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetPolygonStipple +extern "C" { +GLAPI void GLAPIENTRY glGetPolygonStipple(GLubyte* mask); +} +void OVR::GLEContext::glGetPolygonStipple_Hook(GLubyte* mask) { + glGetPolygonStipple(mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +// #undef glGetString // This was already disabled above. +// extern "C" { GLAPI const GLubyte * GLAPIENTRY glGetString(GLenum name); } +const GLubyte* OVR::GLEContext::glGetString_Hook(GLenum name) { + const GLubyte* p = glGetString(name); + PostHook(GLE_CURRENT_FUNCTION); + return p; +} + +#undef glGetTexEnvfv +extern "C" { +GLAPI void GLAPIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat* params); +} +void OVR::GLEContext::glGetTexEnvfv_Hook(GLenum target, GLenum pname, GLfloat* params) { + glGetTexEnvfv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetTexEnviv +extern "C" { +GLAPI void GLAPIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint* params); +} +void OVR::GLEContext::glGetTexEnviv_Hook(GLenum target, GLenum pname, GLint* params) { + glGetTexEnviv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetTexGendv +extern "C" { +GLAPI void GLAPIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble* params); +} +void OVR::GLEContext::glGetTexGendv_Hook(GLenum coord, GLenum pname, GLdouble* params) { + glGetTexGendv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetTexGenfv +extern "C" { +GLAPI void GLAPIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat* params); +} +void OVR::GLEContext::glGetTexGenfv_Hook(GLenum coord, GLenum pname, GLfloat* params) { + glGetTexGenfv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetTexGeniv +extern "C" { +GLAPI void GLAPIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint* params); +} +void OVR::GLEContext::glGetTexGeniv_Hook(GLenum coord, GLenum pname, GLint* params) { + glGetTexGeniv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetTexImage +extern "C" { +GLAPI void GLAPIENTRY +glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +} +void OVR::GLEContext::glGetTexImage_Hook( + GLenum target, + GLint level, + GLenum format, + GLenum type, + void* pixels) { + glGetTexImage(target, level, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetTexLevelParameterfv +extern "C" { +GLAPI void GLAPIENTRY +glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params); +} +void OVR::GLEContext::glGetTexLevelParameterfv_Hook( + GLenum target, + GLint level, + GLenum pname, + GLfloat* params) { + glGetTexLevelParameterfv(target, level, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetTexLevelParameteriv +extern "C" { +GLAPI void GLAPIENTRY +glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params); +} +void OVR::GLEContext::glGetTexLevelParameteriv_Hook( + GLenum target, + GLint level, + GLenum pname, + GLint* params) { + glGetTexLevelParameteriv(target, level, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetTexParameterfv +extern "C" { +GLAPI void GLAPIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params); +} +void OVR::GLEContext::glGetTexParameterfv_Hook(GLenum target, GLenum pname, GLfloat* params) { + glGetTexParameterfv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glGetTexParameteriv +extern "C" { +GLAPI void GLAPIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params); +} +void OVR::GLEContext::glGetTexParameteriv_Hook(GLenum target, GLenum pname, GLint* params) { + glGetTexParameteriv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glHint +extern "C" { +GLAPI void GLAPIENTRY glHint(GLenum target, GLenum mode); +} +void OVR::GLEContext::glHint_Hook(GLenum target, GLenum mode) { + glHint(target, mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexMask +extern "C" { +GLAPI void GLAPIENTRY glIndexMask(GLuint mask); +} +void OVR::GLEContext::glIndexMask_Hook(GLuint mask) { + glIndexMask(mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexPointer +extern "C" { +GLAPI void GLAPIENTRY glIndexPointer(GLenum type, GLsizei stride, const void* pointer); +} +void OVR::GLEContext::glIndexPointer_Hook(GLenum type, GLsizei stride, const void* pointer) { + glIndexPointer(type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexd +extern "C" { +GLAPI void GLAPIENTRY glIndexd(GLdouble c); +} +void OVR::GLEContext::glIndexd_Hook(GLdouble c) { + glIndexd(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexdv +extern "C" { +GLAPI void GLAPIENTRY glIndexdv(const GLdouble* c); +} +void OVR::GLEContext::glIndexdv_Hook(const GLdouble* c) { + glIndexdv(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexf +extern "C" { +GLAPI void GLAPIENTRY glIndexf(GLfloat c); +} +void OVR::GLEContext::glIndexf_Hook(GLfloat c) { + glIndexf(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexfv +extern "C" { +GLAPI void GLAPIENTRY glIndexfv(const GLfloat* c); +} +void OVR::GLEContext::glIndexfv_Hook(const GLfloat* c) { + glIndexfv(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexi +extern "C" { +GLAPI void GLAPIENTRY glIndexi(GLint c); +} +void OVR::GLEContext::glIndexi_Hook(GLint c) { + glIndexi(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexiv +extern "C" { +GLAPI void GLAPIENTRY glIndexiv(const GLint* c); +} +void OVR::GLEContext::glIndexiv_Hook(const GLint* c) { + glIndexiv(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexs +extern "C" { +GLAPI void GLAPIENTRY glIndexs(GLshort c); +} +void OVR::GLEContext::glIndexs_Hook(GLshort c) { + glIndexs(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexsv +extern "C" { +GLAPI void GLAPIENTRY glIndexsv(const GLshort* c); +} +void OVR::GLEContext::glIndexsv_Hook(const GLshort* c) { + glIndexsv(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexub +extern "C" { +GLAPI void GLAPIENTRY glIndexub(GLubyte c); +} +void OVR::GLEContext::glIndexub_Hook(GLubyte c) { + glIndexub(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIndexubv +extern "C" { +GLAPI void GLAPIENTRY glIndexubv(const GLubyte* c); +} +void OVR::GLEContext::glIndexubv_Hook(const GLubyte* c) { + glIndexubv(c); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glInitNames +extern "C" { +GLAPI void GLAPIENTRY glInitNames(); +} +void OVR::GLEContext::glInitNames_Hook() { + glInitNames(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glInterleavedArrays +extern "C" { +GLAPI void GLAPIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const void* pointer); +} +void OVR::GLEContext::glInterleavedArrays_Hook(GLenum format, GLsizei stride, const void* pointer) { + glInterleavedArrays(format, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glIsEnabled +extern "C" { +GLAPI GLboolean GLAPIENTRY glIsEnabled(GLenum cap); +} +GLboolean OVR::GLEContext::glIsEnabled_Hook(GLenum cap) { + GLboolean b = glIsEnabled(cap); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef glIsList +extern "C" { +GLAPI GLboolean GLAPIENTRY glIsList(GLuint list); +} +GLboolean OVR::GLEContext::glIsList_Hook(GLuint list) { + GLboolean b = glIsList(list); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef glIsTexture +extern "C" { +GLAPI GLboolean GLAPIENTRY glIsTexture(GLuint texture); +} +GLboolean OVR::GLEContext::glIsTexture_Hook(GLuint texture) { + GLboolean b = glIsTexture(texture); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef glLightModelf +extern "C" { +GLAPI void GLAPIENTRY glLightModelf(GLenum pname, GLfloat param); +} +void OVR::GLEContext::glLightModelf_Hook(GLenum pname, GLfloat param) { + glLightModelf(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLightModelfv +extern "C" { +GLAPI void GLAPIENTRY glLightModelfv(GLenum pname, const GLfloat* params); +} +void OVR::GLEContext::glLightModelfv_Hook(GLenum pname, const GLfloat* params) { + glLightModelfv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLightModeli +extern "C" { +GLAPI void GLAPIENTRY glLightModeli(GLenum pname, GLint param); +} +void OVR::GLEContext::glLightModeli_Hook(GLenum pname, GLint param) { + glLightModeli(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLightModeliv +extern "C" { +GLAPI void GLAPIENTRY glLightModeliv(GLenum pname, const GLint* params); +} +void OVR::GLEContext::glLightModeliv_Hook(GLenum pname, const GLint* params) { + glLightModeliv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLightf +extern "C" { +GLAPI void GLAPIENTRY glLightf(GLenum light, GLenum pname, GLfloat param); +} +void OVR::GLEContext::glLightf_Hook(GLenum light, GLenum pname, GLfloat param) { + glLightf(light, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLightfv +extern "C" { +GLAPI void GLAPIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat* params); +} +void OVR::GLEContext::glLightfv_Hook(GLenum light, GLenum pname, const GLfloat* params) { + glLightfv(light, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLighti +extern "C" { +GLAPI void GLAPIENTRY glLighti(GLenum light, GLenum pname, GLint param); +} +void OVR::GLEContext::glLighti_Hook(GLenum light, GLenum pname, GLint param) { + glLighti(light, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLightiv +extern "C" { +GLAPI void GLAPIENTRY glLightiv(GLenum light, GLenum pname, const GLint* params); +} +void OVR::GLEContext::glLightiv_Hook(GLenum light, GLenum pname, const GLint* params) { + glLightiv(light, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLineStipple +extern "C" { +GLAPI void GLAPIENTRY glLineStipple(GLint factor, GLushort pattern); +} +void OVR::GLEContext::glLineStipple_Hook(GLint factor, GLushort pattern) { + glLineStipple(factor, pattern); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLineWidth +extern "C" { +GLAPI void GLAPIENTRY glLineWidth(GLfloat width); +} +void OVR::GLEContext::glLineWidth_Hook(GLfloat width) { + glLineWidth(width); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glListBase +extern "C" { +GLAPI void GLAPIENTRY glListBase(GLuint base); +} +void OVR::GLEContext::glListBase_Hook(GLuint base) { + glListBase(base); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLoadIdentity +extern "C" { +GLAPI void GLAPIENTRY glLoadIdentity(); +} +void OVR::GLEContext::glLoadIdentity_Hook() { + glLoadIdentity(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLoadMatrixd +extern "C" { +GLAPI void GLAPIENTRY glLoadMatrixd(const GLdouble* m); +} +void OVR::GLEContext::glLoadMatrixd_Hook(const GLdouble* m) { + glLoadMatrixd(m); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLoadMatrixf +extern "C" { +GLAPI void GLAPIENTRY glLoadMatrixf(const GLfloat* m); +} +void OVR::GLEContext::glLoadMatrixf_Hook(const GLfloat* m) { + glLoadMatrixf(m); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLoadName +extern "C" { +GLAPI void GLAPIENTRY glLoadName(GLuint name); +} +void OVR::GLEContext::glLoadName_Hook(GLuint name) { + glLoadName(name); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glLogicOp +extern "C" { +GLAPI void GLAPIENTRY glLogicOp(GLenum opcode); +} +void OVR::GLEContext::glLogicOp_Hook(GLenum opcode) { + glLogicOp(opcode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMap1d +extern "C" { +GLAPI void GLAPIENTRY +glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points); +} +void OVR::GLEContext::glMap1d_Hook( + GLenum target, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble* points) { + glMap1d(target, u1, u2, stride, order, points); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMap1f +extern "C" { +GLAPI void GLAPIENTRY +glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points); +} +void OVR::GLEContext::glMap1f_Hook( + GLenum target, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat* points) { + glMap1f(target, u1, u2, stride, order, points); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMap2d +extern "C" { +GLAPI void GLAPIENTRY glMap2d( + GLenum target, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble* points); +} +void OVR::GLEContext::glMap2d_Hook( + GLenum target, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble* points) { + glMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMap2f +extern "C" { +GLAPI void GLAPIENTRY glMap2f( + GLenum target, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat* points); +} +void OVR::GLEContext::glMap2f_Hook( + GLenum target, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat* points) { + glMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMapGrid1d +extern "C" { +GLAPI void GLAPIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2); +} +void OVR::GLEContext::glMapGrid1d_Hook(GLint un, GLdouble u1, GLdouble u2) { + glMapGrid1d(un, u1, u2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMapGrid1f +extern "C" { +GLAPI void GLAPIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2); +} +void OVR::GLEContext::glMapGrid1f_Hook(GLint un, GLfloat u1, GLfloat u2) { + glMapGrid1f(un, u1, u2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMapGrid2d +extern "C" { +GLAPI void GLAPIENTRY +glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +} +void OVR::GLEContext::glMapGrid2d_Hook( + GLint un, + GLdouble u1, + GLdouble u2, + GLint vn, + GLdouble v1, + GLdouble v2) { + glMapGrid2d(un, u1, u2, vn, v1, v2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMapGrid2f +extern "C" { +GLAPI void GLAPIENTRY +glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +} +void OVR::GLEContext::glMapGrid2f_Hook( + GLint un, + GLfloat u1, + GLfloat u2, + GLint vn, + GLfloat v1, + GLfloat v2) { + glMapGrid2f(un, u1, u2, vn, v1, v2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMaterialf +extern "C" { +GLAPI void GLAPIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param); +} +void OVR::GLEContext::glMaterialf_Hook(GLenum face, GLenum pname, GLfloat param) { + glMaterialf(face, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMaterialfv +extern "C" { +GLAPI void GLAPIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat* params); +} +void OVR::GLEContext::glMaterialfv_Hook(GLenum face, GLenum pname, const GLfloat* params) { + glMaterialfv(face, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMateriali +extern "C" { +GLAPI void GLAPIENTRY glMateriali(GLenum face, GLenum pname, GLint param); +} +void OVR::GLEContext::glMateriali_Hook(GLenum face, GLenum pname, GLint param) { + glMateriali(face, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMaterialiv +extern "C" { +GLAPI void GLAPIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint* params); +} +void OVR::GLEContext::glMaterialiv_Hook(GLenum face, GLenum pname, const GLint* params) { + glMaterialiv(face, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMatrixMode +extern "C" { +GLAPI void GLAPIENTRY glMatrixMode(GLenum mode); +} +void OVR::GLEContext::glMatrixMode_Hook(GLenum mode) { + glMatrixMode(mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMultMatrixd +extern "C" { +GLAPI void GLAPIENTRY glMultMatrixd(const GLdouble* m); +} +void OVR::GLEContext::glMultMatrixd_Hook(const GLdouble* m) { + glMultMatrixd(m); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glMultMatrixf +extern "C" { +GLAPI void GLAPIENTRY glMultMatrixf(const GLfloat* m); +} +void OVR::GLEContext::glMultMatrixf_Hook(const GLfloat* m) { + glMultMatrixf(m); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNewList +extern "C" { +GLAPI void GLAPIENTRY glNewList(GLuint list, GLenum mode); +} +void OVR::GLEContext::glNewList_Hook(GLuint list, GLenum mode) { + glNewList(list, mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormal3b +extern "C" { +GLAPI void GLAPIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz); +} +void OVR::GLEContext::glNormal3b_Hook(GLbyte nx, GLbyte ny, GLbyte nz) { + glNormal3b(nx, ny, nz); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormal3bv +extern "C" { +GLAPI void GLAPIENTRY glNormal3bv(const GLbyte* v); +} +void OVR::GLEContext::glNormal3bv_Hook(const GLbyte* v) { + glNormal3bv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormal3d +extern "C" { +GLAPI void GLAPIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz); +} +void OVR::GLEContext::glNormal3d_Hook(GLdouble nx, GLdouble ny, GLdouble nz) { + glNormal3d(nx, ny, nz); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormal3dv +extern "C" { +GLAPI void GLAPIENTRY glNormal3dv(const GLdouble* v); +} +void OVR::GLEContext::glNormal3dv_Hook(const GLdouble* v) { + glNormal3dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormal3f +extern "C" { +GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz); +} +void OVR::GLEContext::glNormal3f_Hook(GLfloat nx, GLfloat ny, GLfloat nz) { + glNormal3f(nx, ny, nz); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormal3fv +extern "C" { +GLAPI void GLAPIENTRY glNormal3fv(const GLfloat* v); +} +void OVR::GLEContext::glNormal3fv_Hook(const GLfloat* v) { + glNormal3fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormal3i +extern "C" { +GLAPI void GLAPIENTRY glNormal3i(GLint nx, GLint ny, GLint nz); +} +void OVR::GLEContext::glNormal3i_Hook(GLint nx, GLint ny, GLint nz) { + glNormal3i(nx, ny, nz); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormal3iv +extern "C" { +GLAPI void GLAPIENTRY glNormal3iv(const GLint* v); +} +void OVR::GLEContext::glNormal3iv_Hook(const GLint* v) { + glNormal3iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormal3s +extern "C" { +GLAPI void GLAPIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz); +} +void OVR::GLEContext::glNormal3s_Hook(GLshort nx, GLshort ny, GLshort nz) { + glNormal3s(nx, ny, nz); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormal3sv +extern "C" { +GLAPI void GLAPIENTRY glNormal3sv(const GLshort* v); +} +void OVR::GLEContext::glNormal3sv_Hook(const GLshort* v) { + glNormal3sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glNormalPointer +extern "C" { +GLAPI void GLAPIENTRY glNormalPointer(GLenum type, GLsizei stride, const void* pointer); +} +void OVR::GLEContext::glNormalPointer_Hook(GLenum type, GLsizei stride, const void* pointer) { + glNormalPointer(type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glOrtho +extern "C" { +GLAPI void GLAPIENTRY glOrtho( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar); +} +void OVR::GLEContext::glOrtho_Hook( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar) { + glOrtho(left, right, bottom, top, zNear, zFar); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPassThrough +extern "C" { +GLAPI void GLAPIENTRY glPassThrough(GLfloat token); +} +void OVR::GLEContext::glPassThrough_Hook(GLfloat token) { + glPassThrough(token); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPixelMapfv +extern "C" { +GLAPI void GLAPIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat* values); +} +void OVR::GLEContext::glPixelMapfv_Hook(GLenum map, GLsizei mapsize, const GLfloat* values) { + glPixelMapfv(map, mapsize, values); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPixelMapuiv +extern "C" { +GLAPI void GLAPIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint* values); +} +void OVR::GLEContext::glPixelMapuiv_Hook(GLenum map, GLsizei mapsize, const GLuint* values) { + glPixelMapuiv(map, mapsize, values); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPixelMapusv +extern "C" { +GLAPI void GLAPIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort* values); +} +void OVR::GLEContext::glPixelMapusv_Hook(GLenum map, GLsizei mapsize, const GLushort* values) { + glPixelMapusv(map, mapsize, values); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPixelStoref +extern "C" { +GLAPI void GLAPIENTRY glPixelStoref(GLenum pname, GLfloat param); +} +void OVR::GLEContext::glPixelStoref_Hook(GLenum pname, GLfloat param) { + glPixelStoref(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPixelStorei +extern "C" { +GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param); +} +void OVR::GLEContext::glPixelStorei_Hook(GLenum pname, GLint param) { + glPixelStorei(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPixelTransferf +extern "C" { +GLAPI void GLAPIENTRY glPixelTransferf(GLenum pname, GLfloat param); +} +void OVR::GLEContext::glPixelTransferf_Hook(GLenum pname, GLfloat param) { + glPixelTransferf(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPixelTransferi +extern "C" { +GLAPI void GLAPIENTRY glPixelTransferi(GLenum pname, GLint param); +} +void OVR::GLEContext::glPixelTransferi_Hook(GLenum pname, GLint param) { + glPixelTransferi(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPixelZoom +extern "C" { +GLAPI void GLAPIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor); +} +void OVR::GLEContext::glPixelZoom_Hook(GLfloat xfactor, GLfloat yfactor) { + glPixelZoom(xfactor, yfactor); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPointSize +extern "C" { +GLAPI void GLAPIENTRY glPointSize(GLfloat size); +} +void OVR::GLEContext::glPointSize_Hook(GLfloat size) { + glPointSize(size); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPolygonMode +extern "C" { +GLAPI void GLAPIENTRY glPolygonMode(GLenum face, GLenum mode); +} +void OVR::GLEContext::glPolygonMode_Hook(GLenum face, GLenum mode) { + glPolygonMode(face, mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPolygonOffset +extern "C" { +GLAPI void GLAPIENTRY glPolygonOffset(GLfloat factor, GLfloat units); +} +void OVR::GLEContext::glPolygonOffset_Hook(GLfloat factor, GLfloat units) { + glPolygonOffset(factor, units); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPolygonStipple +extern "C" { +GLAPI void GLAPIENTRY glPolygonStipple(const GLubyte* mask); +} +void OVR::GLEContext::glPolygonStipple_Hook(const GLubyte* mask) { + glPolygonStipple(mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPopAttrib +extern "C" { +GLAPI void GLAPIENTRY glPopAttrib(); +} +void OVR::GLEContext::glPopAttrib_Hook() { + glPopAttrib(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPopClientAttrib +extern "C" { +GLAPI void GLAPIENTRY glPopClientAttrib(); +} +void OVR::GLEContext::glPopClientAttrib_Hook() { + glPopClientAttrib(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPopMatrix +extern "C" { +GLAPI void GLAPIENTRY glPopMatrix(); +} +void OVR::GLEContext::glPopMatrix_Hook() { + glPopMatrix(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPopName +extern "C" { +GLAPI void GLAPIENTRY glPopName(); +} +void OVR::GLEContext::glPopName_Hook() { + glPopName(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPrioritizeTextures +extern "C" { +GLAPI void GLAPIENTRY +glPrioritizeTextures(GLsizei n, const GLuint* textures, const GLclampf* priorities); +} +void OVR::GLEContext::glPrioritizeTextures_Hook( + GLsizei n, + const GLuint* textures, + const GLclampf* priorities) { + glPrioritizeTextures(n, textures, priorities); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPushAttrib +extern "C" { +GLAPI void GLAPIENTRY glPushAttrib(GLbitfield mask); +} +void OVR::GLEContext::glPushAttrib_Hook(GLbitfield mask) { + glPushAttrib(mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPushClientAttrib +extern "C" { +GLAPI void GLAPIENTRY glPushClientAttrib(GLbitfield mask); +} +void OVR::GLEContext::glPushClientAttrib_Hook(GLbitfield mask) { + glPushClientAttrib(mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPushMatrix +extern "C" { +GLAPI void GLAPIENTRY glPushMatrix(); +} +void OVR::GLEContext::glPushMatrix_Hook() { + glPushMatrix(); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glPushName +extern "C" { +GLAPI void GLAPIENTRY glPushName(GLuint name); +} +void OVR::GLEContext::glPushName_Hook(GLuint name) { + glPushName(name); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos2d +extern "C" { +GLAPI void GLAPIENTRY glRasterPos2d(GLdouble x, GLdouble y); +} +void OVR::GLEContext::glRasterPos2d_Hook(GLdouble x, GLdouble y) { + glRasterPos2d(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos2dv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos2dv(const GLdouble* v); +} +void OVR::GLEContext::glRasterPos2dv_Hook(const GLdouble* v) { + glRasterPos2dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos2f +extern "C" { +GLAPI void GLAPIENTRY glRasterPos2f(GLfloat x, GLfloat y); +} +void OVR::GLEContext::glRasterPos2f_Hook(GLfloat x, GLfloat y) { + glRasterPos2f(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos2fv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos2fv(const GLfloat* v); +} +void OVR::GLEContext::glRasterPos2fv_Hook(const GLfloat* v) { + glRasterPos2fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos2i +extern "C" { +GLAPI void GLAPIENTRY glRasterPos2i(GLint x, GLint y); +} +void OVR::GLEContext::glRasterPos2i_Hook(GLint x, GLint y) { + glRasterPos2i(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos2iv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos2iv(const GLint* v); +} +void OVR::GLEContext::glRasterPos2iv_Hook(const GLint* v) { + glRasterPos2iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos2s +extern "C" { +GLAPI void GLAPIENTRY glRasterPos2s(GLshort x, GLshort y); +} +void OVR::GLEContext::glRasterPos2s_Hook(GLshort x, GLshort y) { + glRasterPos2s(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos2sv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos2sv(const GLshort* v); +} +void OVR::GLEContext::glRasterPos2sv_Hook(const GLshort* v) { + glRasterPos2sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos3d +extern "C" { +GLAPI void GLAPIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z); +} +void OVR::GLEContext::glRasterPos3d_Hook(GLdouble x, GLdouble y, GLdouble z) { + glRasterPos3d(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos3dv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos3dv(const GLdouble* v); +} +void OVR::GLEContext::glRasterPos3dv_Hook(const GLdouble* v) { + glRasterPos3dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos3f +extern "C" { +GLAPI void GLAPIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z); +} +void OVR::GLEContext::glRasterPos3f_Hook(GLfloat x, GLfloat y, GLfloat z) { + glRasterPos3f(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos3fv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos3fv(const GLfloat* v); +} +void OVR::GLEContext::glRasterPos3fv_Hook(const GLfloat* v) { + glRasterPos3fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos3i +extern "C" { +GLAPI void GLAPIENTRY glRasterPos3i(GLint x, GLint y, GLint z); +} +void OVR::GLEContext::glRasterPos3i_Hook(GLint x, GLint y, GLint z) { + glRasterPos3i(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos3iv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos3iv(const GLint* v); +} +void OVR::GLEContext::glRasterPos3iv_Hook(const GLint* v) { + glRasterPos3iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos3s +extern "C" { +GLAPI void GLAPIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z); +} +void OVR::GLEContext::glRasterPos3s_Hook(GLshort x, GLshort y, GLshort z) { + glRasterPos3s(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos3sv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos3sv(const GLshort* v); +} +void OVR::GLEContext::glRasterPos3sv_Hook(const GLshort* v) { + glRasterPos3sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos4d +extern "C" { +GLAPI void GLAPIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +} +void OVR::GLEContext::glRasterPos4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { + glRasterPos4d(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos4dv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos4dv(const GLdouble* v); +} +void OVR::GLEContext::glRasterPos4dv_Hook(const GLdouble* v) { + glRasterPos4dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos4f +extern "C" { +GLAPI void GLAPIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +} +void OVR::GLEContext::glRasterPos4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + glRasterPos4f(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos4fv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos4fv(const GLfloat* v); +} +void OVR::GLEContext::glRasterPos4fv_Hook(const GLfloat* v) { + glRasterPos4fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos4i +extern "C" { +GLAPI void GLAPIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w); +} +void OVR::GLEContext::glRasterPos4i_Hook(GLint x, GLint y, GLint z, GLint w) { + glRasterPos4i(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos4iv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos4iv(const GLint* v); +} +void OVR::GLEContext::glRasterPos4iv_Hook(const GLint* v) { + glRasterPos4iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos4s +extern "C" { +GLAPI void GLAPIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w); +} +void OVR::GLEContext::glRasterPos4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w) { + glRasterPos4s(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRasterPos4sv +extern "C" { +GLAPI void GLAPIENTRY glRasterPos4sv(const GLshort* v); +} +void OVR::GLEContext::glRasterPos4sv_Hook(const GLshort* v) { + glRasterPos4sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glReadBuffer +extern "C" { +GLAPI void GLAPIENTRY glReadBuffer(GLenum mode); +} +void OVR::GLEContext::glReadBuffer_Hook(GLenum mode) { + glReadBuffer(mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glReadPixels +extern "C" { +GLAPI void GLAPIENTRY glReadPixels( + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void* pixels); +} +void OVR::GLEContext::glReadPixels_Hook( + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void* pixels) { + glReadPixels(x, y, width, height, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRectd +extern "C" { +GLAPI void GLAPIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +} +void OVR::GLEContext::glRectd_Hook(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) { + glRectd(x1, y1, x2, y2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRectdv +extern "C" { +GLAPI void GLAPIENTRY glRectdv(const GLdouble* v1, const GLdouble* v2); +} +void OVR::GLEContext::glRectdv_Hook(const GLdouble* v1, const GLdouble* v2) { + glRectdv(v1, v2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRectf +extern "C" { +GLAPI void GLAPIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +} +void OVR::GLEContext::glRectf_Hook(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { + glRectf(x1, y1, x2, y2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRectfv +extern "C" { +GLAPI void GLAPIENTRY glRectfv(const GLfloat* v1, const GLfloat* v2); +} +void OVR::GLEContext::glRectfv_Hook(const GLfloat* v1, const GLfloat* v2) { + glRectfv(v1, v2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRecti +extern "C" { +GLAPI void GLAPIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2); +} +void OVR::GLEContext::glRecti_Hook(GLint x1, GLint y1, GLint x2, GLint y2) { + glRecti(x1, y1, x2, y2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRectiv +extern "C" { +GLAPI void GLAPIENTRY glRectiv(const GLint* v1, const GLint* v2); +} +void OVR::GLEContext::glRectiv_Hook(const GLint* v1, const GLint* v2) { + glRectiv(v1, v2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRects +extern "C" { +GLAPI void GLAPIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +} +void OVR::GLEContext::glRects_Hook(GLshort x1, GLshort y1, GLshort x2, GLshort y2) { + glRects(x1, y1, x2, y2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRectsv +extern "C" { +GLAPI void GLAPIENTRY glRectsv(const GLshort* v1, const GLshort* v2); +} +void OVR::GLEContext::glRectsv_Hook(const GLshort* v1, const GLshort* v2) { + glRectsv(v1, v2); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRenderMode +extern "C" { +GLAPI GLint GLAPIENTRY glRenderMode(GLenum mode); +} +GLint OVR::GLEContext::glRenderMode_Hook(GLenum mode) { + GLint i = glRenderMode(mode); + PostHook(GLE_CURRENT_FUNCTION); + return i; +} + +#undef glRotated +extern "C" { +GLAPI void GLAPIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +} +void OVR::GLEContext::glRotated_Hook(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) { + glRotated(angle, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glRotatef +extern "C" { +GLAPI void GLAPIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +} +void OVR::GLEContext::glRotatef_Hook(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { + glRotatef(angle, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glScaled +extern "C" { +GLAPI void GLAPIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z); +} +void OVR::GLEContext::glScaled_Hook(GLdouble x, GLdouble y, GLdouble z) { + glScaled(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glScalef +extern "C" { +GLAPI void GLAPIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z); +} +void OVR::GLEContext::glScalef_Hook(GLfloat x, GLfloat y, GLfloat z) { + glScalef(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glScissor +extern "C" { +GLAPI void GLAPIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height); +} +void OVR::GLEContext::glScissor_Hook(GLint x, GLint y, GLsizei width, GLsizei height) { + glScissor(x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glSelectBuffer +extern "C" { +GLAPI void GLAPIENTRY glSelectBuffer(GLsizei size, GLuint* buffer); +} +void OVR::GLEContext::glSelectBuffer_Hook(GLsizei size, GLuint* buffer) { + glSelectBuffer(size, buffer); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glShadeModel +extern "C" { +GLAPI void GLAPIENTRY glShadeModel(GLenum mode); +} +void OVR::GLEContext::glShadeModel_Hook(GLenum mode) { + glShadeModel(mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glStencilFunc +extern "C" { +GLAPI void GLAPIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask); +} +void OVR::GLEContext::glStencilFunc_Hook(GLenum func, GLint ref, GLuint mask) { + glStencilFunc(func, ref, mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glStencilMask +extern "C" { +GLAPI void GLAPIENTRY glStencilMask(GLuint mask); +} +void OVR::GLEContext::glStencilMask_Hook(GLuint mask) { + glStencilMask(mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glStencilOp +extern "C" { +GLAPI void GLAPIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass); +} +void OVR::GLEContext::glStencilOp_Hook(GLenum fail, GLenum zfail, GLenum zpass) { + glStencilOp(fail, zfail, zpass); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord1d +extern "C" { +GLAPI void GLAPIENTRY glTexCoord1d(GLdouble s); +} +void OVR::GLEContext::glTexCoord1d_Hook(GLdouble s) { + glTexCoord1d(s); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord1dv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord1dv(const GLdouble* v); +} +void OVR::GLEContext::glTexCoord1dv_Hook(const GLdouble* v) { + glTexCoord1dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord1f +extern "C" { +GLAPI void GLAPIENTRY glTexCoord1f(GLfloat s); +} +void OVR::GLEContext::glTexCoord1f_Hook(GLfloat s) { + glTexCoord1f(s); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord1fv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord1fv(const GLfloat* v); +} +void OVR::GLEContext::glTexCoord1fv_Hook(const GLfloat* v) { + glTexCoord1fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord1i +extern "C" { +GLAPI void GLAPIENTRY glTexCoord1i(GLint s); +} +void OVR::GLEContext::glTexCoord1i_Hook(GLint s) { + glTexCoord1i(s); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord1iv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord1iv(const GLint* v); +} +void OVR::GLEContext::glTexCoord1iv_Hook(const GLint* v) { + glTexCoord1iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord1s +extern "C" { +GLAPI void GLAPIENTRY glTexCoord1s(GLshort s); +} +void OVR::GLEContext::glTexCoord1s_Hook(GLshort s) { + glTexCoord1s(s); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord1sv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord1sv(const GLshort* v); +} +void OVR::GLEContext::glTexCoord1sv_Hook(const GLshort* v) { + glTexCoord1sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord2d +extern "C" { +GLAPI void GLAPIENTRY glTexCoord2d(GLdouble s, GLdouble t); +} +void OVR::GLEContext::glTexCoord2d_Hook(GLdouble s, GLdouble t) { + glTexCoord2d(s, t); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord2dv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord2dv(const GLdouble* v); +} +void OVR::GLEContext::glTexCoord2dv_Hook(const GLdouble* v) { + glTexCoord2dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord2f +extern "C" { +GLAPI void GLAPIENTRY glTexCoord2f(GLfloat s, GLfloat t); +} +void OVR::GLEContext::glTexCoord2f_Hook(GLfloat s, GLfloat t) { + glTexCoord2f(s, t); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord2fv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord2fv(const GLfloat* v); +} +void OVR::GLEContext::glTexCoord2fv_Hook(const GLfloat* v) { + glTexCoord2fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord2i +extern "C" { +GLAPI void GLAPIENTRY glTexCoord2i(GLint s, GLint t); +} +void OVR::GLEContext::glTexCoord2i_Hook(GLint s, GLint t) { + glTexCoord2i(s, t); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord2iv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord2iv(const GLint* v); +} +void OVR::GLEContext::glTexCoord2iv_Hook(const GLint* v) { + glTexCoord2iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord2s +extern "C" { +GLAPI void GLAPIENTRY glTexCoord2s(GLshort s, GLshort t); +} +void OVR::GLEContext::glTexCoord2s_Hook(GLshort s, GLshort t) { + glTexCoord2s(s, t); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord2sv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord2sv(const GLshort* v); +} +void OVR::GLEContext::glTexCoord2sv_Hook(const GLshort* v) { + glTexCoord2sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord3d +extern "C" { +GLAPI void GLAPIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r); +} +void OVR::GLEContext::glTexCoord3d_Hook(GLdouble s, GLdouble t, GLdouble r) { + glTexCoord3d(s, t, r); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord3dv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord3dv(const GLdouble* v); +} +void OVR::GLEContext::glTexCoord3dv_Hook(const GLdouble* v) { + glTexCoord3dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord3f +extern "C" { +GLAPI void GLAPIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r); +} +void OVR::GLEContext::glTexCoord3f_Hook(GLfloat s, GLfloat t, GLfloat r) { + glTexCoord3f(s, t, r); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord3fv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord3fv(const GLfloat* v); +} +void OVR::GLEContext::glTexCoord3fv_Hook(const GLfloat* v) { + glTexCoord3fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord3i +extern "C" { +GLAPI void GLAPIENTRY glTexCoord3i(GLint s, GLint t, GLint r); +} +void OVR::GLEContext::glTexCoord3i_Hook(GLint s, GLint t, GLint r) { + glTexCoord3i(s, t, r); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord3iv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord3iv(const GLint* v); +} +void OVR::GLEContext::glTexCoord3iv_Hook(const GLint* v) { + glTexCoord3iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord3s +extern "C" { +GLAPI void GLAPIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r); +} +void OVR::GLEContext::glTexCoord3s_Hook(GLshort s, GLshort t, GLshort r) { + glTexCoord3s(s, t, r); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord3sv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord3sv(const GLshort* v); +} +void OVR::GLEContext::glTexCoord3sv_Hook(const GLshort* v) { + glTexCoord3sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord4d +extern "C" { +GLAPI void GLAPIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +} +void OVR::GLEContext::glTexCoord4d_Hook(GLdouble s, GLdouble t, GLdouble r, GLdouble q) { + glTexCoord4d(s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord4dv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord4dv(const GLdouble* v); +} +void OVR::GLEContext::glTexCoord4dv_Hook(const GLdouble* v) { + glTexCoord4dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord4f +extern "C" { +GLAPI void GLAPIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +} +void OVR::GLEContext::glTexCoord4f_Hook(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { + glTexCoord4f(s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord4fv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord4fv(const GLfloat* v); +} +void OVR::GLEContext::glTexCoord4fv_Hook(const GLfloat* v) { + glTexCoord4fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord4i +extern "C" { +GLAPI void GLAPIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q); +} +void OVR::GLEContext::glTexCoord4i_Hook(GLint s, GLint t, GLint r, GLint q) { + glTexCoord4i(s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord4iv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord4iv(const GLint* v); +} +void OVR::GLEContext::glTexCoord4iv_Hook(const GLint* v) { + glTexCoord4iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord4s +extern "C" { +GLAPI void GLAPIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q); +} +void OVR::GLEContext::glTexCoord4s_Hook(GLshort s, GLshort t, GLshort r, GLshort q) { + glTexCoord4s(s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoord4sv +extern "C" { +GLAPI void GLAPIENTRY glTexCoord4sv(const GLshort* v); +} +void OVR::GLEContext::glTexCoord4sv_Hook(const GLshort* v) { + glTexCoord4sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexCoordPointer +extern "C" { +GLAPI void GLAPIENTRY +glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void* pointer); +} +void OVR::GLEContext::glTexCoordPointer_Hook( + GLint size, + GLenum type, + GLsizei stride, + const void* pointer) { + glTexCoordPointer(size, type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexEnvf +extern "C" { +GLAPI void GLAPIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param); +} +void OVR::GLEContext::glTexEnvf_Hook(GLenum target, GLenum pname, GLfloat param) { + glTexEnvf(target, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexEnvfv +extern "C" { +GLAPI void GLAPIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat* params); +} +void OVR::GLEContext::glTexEnvfv_Hook(GLenum target, GLenum pname, const GLfloat* params) { + glTexEnvfv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexEnvi +extern "C" { +GLAPI void GLAPIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param); +} +void OVR::GLEContext::glTexEnvi_Hook(GLenum target, GLenum pname, GLint param) { + glTexEnvi(target, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexEnviv +extern "C" { +GLAPI void GLAPIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint* params); +} +void OVR::GLEContext::glTexEnviv_Hook(GLenum target, GLenum pname, const GLint* params) { + glTexEnviv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexGend +extern "C" { +GLAPI void GLAPIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param); +} +void OVR::GLEContext::glTexGend_Hook(GLenum coord, GLenum pname, GLdouble param) { + glTexGend(coord, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexGendv +extern "C" { +GLAPI void GLAPIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble* params); +} +void OVR::GLEContext::glTexGendv_Hook(GLenum coord, GLenum pname, const GLdouble* params) { + glTexGendv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexGenf +extern "C" { +GLAPI void GLAPIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param); +} +void OVR::GLEContext::glTexGenf_Hook(GLenum coord, GLenum pname, GLfloat param) { + glTexGenf(coord, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexGenfv +extern "C" { +GLAPI void GLAPIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat* params); +} +void OVR::GLEContext::glTexGenfv_Hook(GLenum coord, GLenum pname, const GLfloat* params) { + glTexGenfv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexGeni +extern "C" { +GLAPI void GLAPIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param); +} +void OVR::GLEContext::glTexGeni_Hook(GLenum coord, GLenum pname, GLint param) { + glTexGeni(coord, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexGeniv +extern "C" { +GLAPI void GLAPIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint* params); +} +void OVR::GLEContext::glTexGeniv_Hook(GLenum coord, GLenum pname, const GLint* params) { + glTexGeniv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexImage1D +extern "C" { +GLAPI void GLAPIENTRY glTexImage1D( + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const void* pixels); +} +void OVR::GLEContext::glTexImage1D_Hook( + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const void* pixels) { + glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexImage2D +extern "C" { +GLAPI void GLAPIENTRY glTexImage2D( + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void* pixels); +} +void OVR::GLEContext::glTexImage2D_Hook( + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void* pixels) { + glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexParameterf +extern "C" { +GLAPI void GLAPIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param); +} +void OVR::GLEContext::glTexParameterf_Hook(GLenum target, GLenum pname, GLfloat param) { + glTexParameterf(target, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexParameterfv +extern "C" { +GLAPI void GLAPIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params); +} +void OVR::GLEContext::glTexParameterfv_Hook(GLenum target, GLenum pname, const GLfloat* params) { + glTexParameterfv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexParameteri +extern "C" { +GLAPI void GLAPIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param); +} +void OVR::GLEContext::glTexParameteri_Hook(GLenum target, GLenum pname, GLint param) { + glTexParameteri(target, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexParameteriv +extern "C" { +GLAPI void GLAPIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params); +} +void OVR::GLEContext::glTexParameteriv_Hook(GLenum target, GLenum pname, const GLint* params) { + glTexParameteriv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexSubImage1D +extern "C" { +GLAPI void GLAPIENTRY glTexSubImage1D( + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void* pixels); +} +void OVR::GLEContext::glTexSubImage1D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void* pixels) { + glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTexSubImage2D +extern "C" { +GLAPI void GLAPIENTRY glTexSubImage2D( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void* pixels); +} +void OVR::GLEContext::glTexSubImage2D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void* pixels) { + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTranslated +extern "C" { +GLAPI void GLAPIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z); +} +void OVR::GLEContext::glTranslated_Hook(GLdouble x, GLdouble y, GLdouble z) { + glTranslated(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glTranslatef +extern "C" { +GLAPI void GLAPIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z); +} +void OVR::GLEContext::glTranslatef_Hook(GLfloat x, GLfloat y, GLfloat z) { + glTranslatef(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex2d +extern "C" { +GLAPI void GLAPIENTRY glVertex2d(GLdouble x, GLdouble y); +} +void OVR::GLEContext::glVertex2d_Hook(GLdouble x, GLdouble y) { + glVertex2d(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex2dv +extern "C" { +GLAPI void GLAPIENTRY glVertex2dv(const GLdouble* v); +} +void OVR::GLEContext::glVertex2dv_Hook(const GLdouble* v) { + glVertex2dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex2f +extern "C" { +GLAPI void GLAPIENTRY glVertex2f(GLfloat x, GLfloat y); +} +void OVR::GLEContext::glVertex2f_Hook(GLfloat x, GLfloat y) { + glVertex2f(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex2fv +extern "C" { +GLAPI void GLAPIENTRY glVertex2fv(const GLfloat* v); +} +void OVR::GLEContext::glVertex2fv_Hook(const GLfloat* v) { + glVertex2fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex2i +extern "C" { +GLAPI void GLAPIENTRY glVertex2i(GLint x, GLint y); +} +void OVR::GLEContext::glVertex2i_Hook(GLint x, GLint y) { + glVertex2i(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex2iv +extern "C" { +GLAPI void GLAPIENTRY glVertex2iv(const GLint* v); +} +void OVR::GLEContext::glVertex2iv_Hook(const GLint* v) { + glVertex2iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex2s +extern "C" { +GLAPI void GLAPIENTRY glVertex2s(GLshort x, GLshort y); +} +void OVR::GLEContext::glVertex2s_Hook(GLshort x, GLshort y) { + glVertex2s(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex2sv +extern "C" { +GLAPI void GLAPIENTRY glVertex2sv(const GLshort* v); +} +void OVR::GLEContext::glVertex2sv_Hook(const GLshort* v) { + glVertex2sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex3d +extern "C" { +GLAPI void GLAPIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z); +} +void OVR::GLEContext::glVertex3d_Hook(GLdouble x, GLdouble y, GLdouble z) { + glVertex3d(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex3dv +extern "C" { +GLAPI void GLAPIENTRY glVertex3dv(const GLdouble* v); +} +void OVR::GLEContext::glVertex3dv_Hook(const GLdouble* v) { + glVertex3dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex3f +extern "C" { +GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z); +} +void OVR::GLEContext::glVertex3f_Hook(GLfloat x, GLfloat y, GLfloat z) { + glVertex3f(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex3fv +extern "C" { +GLAPI void GLAPIENTRY glVertex3fv(const GLfloat* v); +} +void OVR::GLEContext::glVertex3fv_Hook(const GLfloat* v) { + glVertex3fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex3i +extern "C" { +GLAPI void GLAPIENTRY glVertex3i(GLint x, GLint y, GLint z); +} +void OVR::GLEContext::glVertex3i_Hook(GLint x, GLint y, GLint z) { + glVertex3i(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex3iv +extern "C" { +GLAPI void GLAPIENTRY glVertex3iv(const GLint* v); +} +void OVR::GLEContext::glVertex3iv_Hook(const GLint* v) { + glVertex3iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex3s +extern "C" { +GLAPI void GLAPIENTRY glVertex3s(GLshort x, GLshort y, GLshort z); +} +void OVR::GLEContext::glVertex3s_Hook(GLshort x, GLshort y, GLshort z) { + glVertex3s(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex3sv +extern "C" { +GLAPI void GLAPIENTRY glVertex3sv(const GLshort* v); +} +void OVR::GLEContext::glVertex3sv_Hook(const GLshort* v) { + glVertex3sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex4d +extern "C" { +GLAPI void GLAPIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +} +void OVR::GLEContext::glVertex4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { + glVertex4d(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex4dv +extern "C" { +GLAPI void GLAPIENTRY glVertex4dv(const GLdouble* v); +} +void OVR::GLEContext::glVertex4dv_Hook(const GLdouble* v) { + glVertex4dv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex4f +extern "C" { +GLAPI void GLAPIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +} +void OVR::GLEContext::glVertex4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + glVertex4f(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex4fv +extern "C" { +GLAPI void GLAPIENTRY glVertex4fv(const GLfloat* v); +} +void OVR::GLEContext::glVertex4fv_Hook(const GLfloat* v) { + glVertex4fv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex4i +extern "C" { +GLAPI void GLAPIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w); +} +void OVR::GLEContext::glVertex4i_Hook(GLint x, GLint y, GLint z, GLint w) { + glVertex4i(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex4iv +extern "C" { +GLAPI void GLAPIENTRY glVertex4iv(const GLint* v); +} +void OVR::GLEContext::glVertex4iv_Hook(const GLint* v) { + glVertex4iv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex4s +extern "C" { +GLAPI void GLAPIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w); +} +void OVR::GLEContext::glVertex4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w) { + glVertex4s(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertex4sv +extern "C" { +GLAPI void GLAPIENTRY glVertex4sv(const GLshort* v); +} +void OVR::GLEContext::glVertex4sv_Hook(const GLshort* v) { + glVertex4sv(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glVertexPointer +extern "C" { +GLAPI void GLAPIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const void* pointer); +} +void OVR::GLEContext::glVertexPointer_Hook( + GLint size, + GLenum type, + GLsizei stride, + const void* pointer) { + glVertexPointer(size, type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +#undef glViewport +extern "C" { +GLAPI void GLAPIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height); +} +void OVR::GLEContext::glViewport_Hook(GLint x, GLint y, GLsizei width, GLsizei height) { + glViewport(x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); +} + +// Pointer-based functions +void OVR::GLEContext::glBlendColor_Hook( + GLclampf red, + GLclampf green, + GLclampf blue, + GLclampf alpha) { + if (glBlendColor_Impl) + glBlendColor_Impl(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBlendEquation_Hook(GLenum mode) { + if (glBlendEquation_Impl) + glBlendEquation_Impl(mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDrawRangeElements_Hook( + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid* indices) { + if (glDrawRangeElements_Impl) + glDrawRangeElements_Impl(mode, start, end, count, type, indices); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTexImage3D_Hook( + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const GLvoid* pixels) { + if (glTexImage3D_Impl) + glTexImage3D_Impl( + target, level, internalformat, width, height, depth, border, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTexSubImage3D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const GLvoid* pixels) { + if (glTexSubImage3D_Impl) + glTexSubImage3D_Impl( + target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCopyTexSubImage3D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { + if (glCopyTexSubImage3D_Impl) + glCopyTexSubImage3D_Impl(target, level, xoffset, yoffset, zoffset, x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_1_2 deprecated functions +/* Not currently supported +void OVR::GLEContext::glColorTable_Hook(GLenum target, GLenum internalformat, GLsizei width, GLenum +format, GLenum type, const GLvoid *table) +{ + if(glColorTable_Impl) + glColorTable_Impl(target, internalformat, width, format, type, table); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glColorTableParameterfv_Hook(GLenum target, GLenum pname, const GLfloat +*params) +{ + if(glColorTableParameterfv_Impl) + glColorTableParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glColorTableParameteriv_Hook(GLenum target, GLenum pname, const GLint *params) +{ + if(glColorTableParameteriv_Impl) + glColorTableParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCopyColorTable_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, +GLsizei width) +{ + if(glCopyColorTable_Impl) + glCopyColorTable_Impl(target, internalformat, x, y, width); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetColorTable_Hook(GLenum target, GLenum format, GLenum type, GLvoid *table) +{ + if(glGetColorTable_Impl) + glGetColorTable_Impl(target, format, type, table); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetColorTableParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) +{ + if(glGetColorTableParameterfv_Impl) + glGetColorTableParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetColorTableParameteriv_Hook(GLenum target, GLenum pname, GLint *params) +{ + if(glGetColorTableParameteriv_Impl) + glGetColorTableParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glColorSubTable_Hook(GLenum target, GLsizei start, GLsizei count, GLenum +format, GLenum type, const GLvoid *data) +{ + if(glColorSubTable_Impl) + glColorSubTable_Impl(target, start, count, format, type, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCopyColorSubTable_Hook(GLenum target, GLsizei start, GLint x, GLint y, +GLsizei width) +{ + if(glCopyColorSubTable_Impl) + glCopyColorSubTable_Impl(target, start, x, y, width); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLsizei +width, GLenum format, GLenum type, const GLvoid *image) +{ + if(glConvolutionFilter1D_Impl) + glConvolutionFilter1D_Impl(target, internalformat, width, format, type, image); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei +width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) +{ + if(glConvolutionFilter2D_Impl) + glConvolutionFilter2D_Impl(target, internalformat, width, height, format, type, image); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glConvolutionParameterf_Hook(GLenum target, GLenum pname, GLfloat params) +{ + if(glConvolutionParameterf_Impl) + glConvolutionParameterf_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glConvolutionParameterfv_Hook(GLenum target, GLenum pname, const GLfloat +*params) +{ + if(glConvolutionParameterfv_Impl) + glConvolutionParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glConvolutionParameteri_Hook(GLenum target, GLenum pname, GLint params) +{ + if(glConvolutionParameteri_Impl) + glConvolutionParameteri_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glConvolutionParameteriv_Hook(GLenum target, GLenum pname, const GLint +*params) +{ + if(glConvolutionParameteriv_Impl) + glConvolutionParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCopyConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLint x, +GLint y, GLsizei width) +{ + if(glCopyConvolutionFilter1D_Impl) + glCopyConvolutionFilter1D_Impl(target, internalformat, x, y, width); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCopyConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLint x, +GLint y, GLsizei width, GLsizei height) +{ + if(glCopyConvolutionFilter2D_Impl) + glCopyConvolutionFilter2D_Impl(target, internalformat, x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetConvolutionFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid +*image) +{ + if(glGetConvolutionFilter_Impl) + glGetConvolutionFilter_Impl(target, format, type, image); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetConvolutionParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) +{ + if(glGetConvolutionParameterfv_Impl) + glGetConvolutionParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetConvolutionParameteriv_Hook(GLenum target, GLenum pname, GLint *params) +{ + if(glGetConvolutionParameteriv_Impl) + glGetConvolutionParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetSeparableFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid +*row, GLvoid *column, GLvoid *span) +{ + if(glGetSeparableFilter_Impl) + glGetSeparableFilter_Impl(target, format, type, row, column, span); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSeparableFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, +GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) +{ + if(glSeparableFilter2D_Impl) + glSeparableFilter2D_Impl(target, internalformat, width, height, format, type, row, column); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetHistogram_Hook(GLenum target, GLboolean reset, GLenum format, GLenum +type, GLvoid *values) +{ + if(glGetHistogram_Impl) + glGetHistogram_Impl(target, reset, format, type, values); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetHistogramParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) +{ + if(glGetHistogramParameterfv_Impl) + glGetHistogramParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetHistogramParameteriv_Hook(GLenum target, GLenum pname, GLint *params) +{ + if(glGetHistogramParameteriv_Impl) + glGetHistogramParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetMinmax_Hook(GLenum target, GLboolean reset, GLenum format, GLenum type, +GLvoid *values) +{ + if(glGetMinmax_Impl) + glGetMinmax_Impl(target, reset, format, type, values); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetMinmaxParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) +{ + if(glGetMinmaxParameterfv_Impl) + glGetMinmaxParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetMinmaxParameteriv_Hook(GLenum target, GLenum pname, GLint *params) +{ + if(glGetMinmaxParameteriv_Impl) + glGetMinmaxParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glHistogram_Hook(GLenum target, GLsizei width, GLenum internalformat, +GLboolean sink) +{ + if(glHistogram_Impl) + glHistogram_Impl(target, width, internalformat, sink); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMinmax_Hook(GLenum target, GLenum internalformat, GLboolean sink) +{ + if(glMinmax_Impl) + glMinmax_Impl(target, internalformat, sink); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glResetHistogram_Hook(GLenum target) +{ + if(glResetHistogram_Impl) + glResetHistogram_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glResetMinmax_Hook(GLenum target) +{ + if(glResetMinmax_Impl) + glResetMinmax_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); +} +*/ + +// GL_VERSION_1_3 +void OVR::GLEContext::glActiveTexture_Hook(GLenum texture) { + if (glActiveTexture_Impl) + glActiveTexture_Impl(texture); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSampleCoverage_Hook(GLclampf value, GLboolean invert) { + if (glSampleCoverage_Impl) + glSampleCoverage_Impl(value, invert); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCompressedTexImage3D_Hook( + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const GLvoid* data) { + if (glCompressedTexImage3D_Impl) + glCompressedTexImage3D_Impl( + target, level, internalformat, width, height, depth, border, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCompressedTexImage2D_Hook( + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const GLvoid* data) { + if (glCompressedTexImage2D_Impl) + glCompressedTexImage2D_Impl( + target, level, internalformat, width, height, border, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCompressedTexImage1D_Hook( + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLint border, + GLsizei imageSize, + const GLvoid* data) { + if (glCompressedTexImage1D_Impl) + glCompressedTexImage1D_Impl(target, level, internalformat, width, border, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCompressedTexSubImage3D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const GLvoid* data) { + if (glCompressedTexSubImage3D_Impl) + glCompressedTexSubImage3D_Impl( + target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCompressedTexSubImage2D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const GLvoid* data) { + if (glCompressedTexSubImage2D_Impl) + glCompressedTexSubImage2D_Impl( + target, level, xoffset, yoffset, width, height, format, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCompressedTexSubImage1D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const GLvoid* data) { + if (glCompressedTexSubImage1D_Impl) + glCompressedTexSubImage1D_Impl(target, level, xoffset, width, format, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetCompressedTexImage_Hook(GLenum target, GLint level, GLvoid* img) { + if (glGetCompressedTexImage_Impl) + glGetCompressedTexImage_Impl(target, level, img); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_1_3 deprecated functions +void OVR::GLEContext::glClientActiveTexture_Hook(GLenum texture) { + if (glClientActiveTexture_Impl) + glClientActiveTexture_Impl(texture); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord1d_Hook(GLenum target, GLdouble s) { + if (glMultiTexCoord1d_Impl) + glMultiTexCoord1d_Impl(target, s); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord1dv_Hook(GLenum target, const GLdouble* v) { + if (glMultiTexCoord1dv_Impl) + glMultiTexCoord1dv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord1f_Hook(GLenum target, GLfloat s) { + if (glMultiTexCoord1f_Impl) + glMultiTexCoord1f_Impl(target, s); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord1fv_Hook(GLenum target, const GLfloat* v) { + if (glMultiTexCoord1fv_Impl) + glMultiTexCoord1fv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord1i_Hook(GLenum target, GLint s) { + if (glMultiTexCoord1i_Impl) + glMultiTexCoord1i_Impl(target, s); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord1iv_Hook(GLenum target, const GLint* v) { + if (glMultiTexCoord1iv_Impl) + glMultiTexCoord1iv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord1s_Hook(GLenum target, GLshort s) { + if (glMultiTexCoord1s_Impl) + glMultiTexCoord1s_Impl(target, s); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord1sv_Hook(GLenum target, const GLshort* v) { + if (glMultiTexCoord1sv_Impl) + glMultiTexCoord1sv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord2d_Hook(GLenum target, GLdouble s, GLdouble t) { + if (glMultiTexCoord2d_Impl) + glMultiTexCoord2d_Impl(target, s, t); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord2dv_Hook(GLenum target, const GLdouble* v) { + if (glMultiTexCoord2dv_Impl) + glMultiTexCoord2dv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord2f_Hook(GLenum target, GLfloat s, GLfloat t) { + if (glMultiTexCoord2f_Impl) + glMultiTexCoord2f_Impl(target, s, t); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord2fv_Hook(GLenum target, const GLfloat* v) { + if (glMultiTexCoord2fv_Impl) + glMultiTexCoord2fv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord2i_Hook(GLenum target, GLint s, GLint t) { + if (glMultiTexCoord2i_Impl) + glMultiTexCoord2i_Impl(target, s, t); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord2iv_Hook(GLenum target, const GLint* v) { + if (glMultiTexCoord2iv_Impl) + glMultiTexCoord2iv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord2s_Hook(GLenum target, GLshort s, GLshort t) { + if (glMultiTexCoord2s_Impl) + glMultiTexCoord2s_Impl(target, s, t); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord2sv_Hook(GLenum target, const GLshort* v) { + if (glMultiTexCoord2sv_Impl) + glMultiTexCoord2sv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord3d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r) { + if (glMultiTexCoord3d_Impl) + glMultiTexCoord3d_Impl(target, s, t, r); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord3dv_Hook(GLenum target, const GLdouble* v) { + if (glMultiTexCoord3dv_Impl) + glMultiTexCoord3dv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord3f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r) { + if (glMultiTexCoord3f_Impl) + glMultiTexCoord3f_Impl(target, s, t, r); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord3fv_Hook(GLenum target, const GLfloat* v) { + if (glMultiTexCoord3fv_Impl) + glMultiTexCoord3fv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord3i_Hook(GLenum target, GLint s, GLint t, GLint r) { + if (glMultiTexCoord3i_Impl) + glMultiTexCoord3i_Impl(target, s, t, r); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord3iv_Hook(GLenum target, const GLint* v) { + if (glMultiTexCoord3iv_Impl) + glMultiTexCoord3iv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord3s_Hook(GLenum target, GLshort s, GLshort t, GLshort r) { + if (glMultiTexCoord3s_Impl) + glMultiTexCoord3s_Impl(target, s, t, r); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord3sv_Hook(GLenum target, const GLshort* v) { + if (glMultiTexCoord3sv_Impl) + glMultiTexCoord3sv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord4d_Hook( + GLenum target, + GLdouble s, + GLdouble t, + GLdouble r, + GLdouble q) { + if (glMultiTexCoord4d_Impl) + glMultiTexCoord4d_Impl(target, s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord4dv_Hook(GLenum target, const GLdouble* v) { + if (glMultiTexCoord4dv_Impl) + glMultiTexCoord4dv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord4f_Hook( + GLenum target, + GLfloat s, + GLfloat t, + GLfloat r, + GLfloat q) { + if (glMultiTexCoord4f_Impl) + glMultiTexCoord4f_Impl(target, s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord4fv_Hook(GLenum target, const GLfloat* v) { + if (glMultiTexCoord4fv_Impl) + glMultiTexCoord4fv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord4i_Hook(GLenum target, GLint s, GLint t, GLint r, GLint q) { + if (glMultiTexCoord4i_Impl) + glMultiTexCoord4i_Impl(target, s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord4iv_Hook(GLenum target, const GLint* v) { + if (glMultiTexCoord4iv_Impl) + glMultiTexCoord4iv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord4s_Hook( + GLenum target, + GLshort s, + GLshort t, + GLshort r, + GLshort q) { + if (glMultiTexCoord4s_Impl) + glMultiTexCoord4s_Impl(target, s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiTexCoord4sv_Hook(GLenum target, const GLshort* v) { + if (glMultiTexCoord4sv_Impl) + glMultiTexCoord4sv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glLoadTransposeMatrixf_Hook(const GLfloat* m) { + if (glLoadTransposeMatrixf_Impl) + glLoadTransposeMatrixf_Impl(m); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glLoadTransposeMatrixd_Hook(const GLdouble* m) { + if (glLoadTransposeMatrixd_Impl) + glLoadTransposeMatrixd_Impl(m); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultTransposeMatrixf_Hook(const GLfloat* m) { + if (glMultTransposeMatrixf_Impl) + glMultTransposeMatrixf_Impl(m); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultTransposeMatrixd_Hook(const GLdouble* m) { + if (glMultTransposeMatrixd_Impl) + glMultTransposeMatrixd_Impl(m); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_1_4 +void OVR::GLEContext::glBlendFuncSeparate_Hook( + GLenum sfactorRGB, + GLenum dfactorRGB, + GLenum sfactorAlpha, + GLenum dfactorAlpha) { + if (glBlendFuncSeparate_Impl) + glBlendFuncSeparate_Impl(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiDrawArrays_Hook( + GLenum mode, + const GLint* first, + const GLsizei* count, + GLsizei primcount) { + if (glMultiDrawArrays_Impl) + glMultiDrawArrays_Impl(mode, first, count, primcount); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiDrawElements_Hook( + GLenum mode, + const GLsizei* count, + GLenum type, + const GLvoid** indices, + GLsizei primcount) { + if (glMultiDrawElements_Impl) + glMultiDrawElements_Impl(mode, count, type, indices, primcount); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glPointParameterf_Hook(GLenum pname, GLfloat param) { + if (glPointParameterf_Impl) + glPointParameterf_Impl(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glPointParameterfv_Hook(GLenum pname, const GLfloat* params) { + if (glPointParameterfv_Impl) + glPointParameterfv_Impl(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glPointParameteri_Hook(GLenum pname, GLint param) { + if (glPointParameteri_Impl) + glPointParameteri_Impl(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glPointParameteriv_Hook(GLenum pname, const GLint* params) { + if (glPointParameteriv_Impl) + glPointParameteriv_Impl(pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_1_4 deprecated functions +void OVR::GLEContext::glFogCoordf_Hook(GLfloat coord) { + if (glFogCoordf_Impl) + glFogCoordf_Impl(coord); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFogCoordfv_Hook(const GLfloat* coord) { + if (glFogCoordfv_Impl) + glFogCoordfv_Impl(coord); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFogCoordd_Hook(GLdouble coord) { + if (glFogCoordd_Impl) + glFogCoordd_Impl(coord); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFogCoorddv_Hook(const GLdouble* coord) { + if (glFogCoorddv_Impl) + glFogCoorddv_Impl(coord); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFogCoordPointer_Hook(GLenum type, GLsizei stride, const GLvoid* pointer) { + if (glFogCoordPointer_Impl) + glFogCoordPointer_Impl(type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue) { + if (glSecondaryColor3b_Impl) + glSecondaryColor3b_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3bv_Hook(const GLbyte* v) { + if (glSecondaryColor3bv_Impl) + glSecondaryColor3bv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue) { + if (glSecondaryColor3d_Impl) + glSecondaryColor3d_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3dv_Hook(const GLdouble* v) { + if (glSecondaryColor3dv_Impl) + glSecondaryColor3dv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue) { + if (glSecondaryColor3f_Impl) + glSecondaryColor3f_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3fv_Hook(const GLfloat* v) { + if (glSecondaryColor3fv_Impl) + glSecondaryColor3fv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3i_Hook(GLint red, GLint green, GLint blue) { + if (glSecondaryColor3i_Impl) + glSecondaryColor3i_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3iv_Hook(const GLint* v) { + if (glSecondaryColor3iv_Impl) + glSecondaryColor3iv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3s_Hook(GLshort red, GLshort green, GLshort blue) { + if (glSecondaryColor3s_Impl) + glSecondaryColor3s_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3sv_Hook(const GLshort* v) { + if (glSecondaryColor3sv_Impl) + glSecondaryColor3sv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue) { + if (glSecondaryColor3ub_Impl) + glSecondaryColor3ub_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3ubv_Hook(const GLubyte* v) { + if (glSecondaryColor3ubv_Impl) + glSecondaryColor3ubv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3ui_Hook(GLuint red, GLuint green, GLuint blue) { + if (glSecondaryColor3ui_Impl) + glSecondaryColor3ui_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3uiv_Hook(const GLuint* v) { + if (glSecondaryColor3uiv_Impl) + glSecondaryColor3uiv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3us_Hook(GLushort red, GLushort green, GLushort blue) { + if (glSecondaryColor3us_Impl) + glSecondaryColor3us_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColor3usv_Hook(const GLushort* v) { + if (glSecondaryColor3usv_Impl) + glSecondaryColor3usv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSecondaryColorPointer_Hook( + GLint size, + GLenum type, + GLsizei stride, + const GLvoid* pointer) { + if (glSecondaryColorPointer_Impl) + glSecondaryColorPointer_Impl(size, type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos2d_Hook(GLdouble x, GLdouble y) { + if (glWindowPos2d_Impl) + glWindowPos2d_Impl(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos2dv_Hook(const GLdouble* v) { + if (glWindowPos2dv_Impl) + glWindowPos2dv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos2f_Hook(GLfloat x, GLfloat y) { + if (glWindowPos2f_Impl) + glWindowPos2f_Impl(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos2fv_Hook(const GLfloat* v) { + if (glWindowPos2fv_Impl) + glWindowPos2fv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos2i_Hook(GLint x, GLint y) { + if (glWindowPos2i_Impl) + glWindowPos2i_Impl(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos2iv_Hook(const GLint* v) { + if (glWindowPos2iv_Impl) + glWindowPos2iv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos2s_Hook(GLshort x, GLshort y) { + if (glWindowPos2s_Impl) + glWindowPos2s_Impl(x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos2sv_Hook(const GLshort* v) { + if (glWindowPos2sv_Impl) + glWindowPos2sv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos3d_Hook(GLdouble x, GLdouble y, GLdouble z) { + if (glWindowPos3d_Impl) + glWindowPos3d_Impl(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos3dv_Hook(const GLdouble* v) { + if (glWindowPos3dv_Impl) + glWindowPos3dv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos3f_Hook(GLfloat x, GLfloat y, GLfloat z) { + if (glWindowPos3f_Impl) + glWindowPos3f_Impl(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos3fv_Hook(const GLfloat* v) { + if (glWindowPos3fv_Impl) + glWindowPos3fv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos3i_Hook(GLint x, GLint y, GLint z) { + if (glWindowPos3i_Impl) + glWindowPos3i_Impl(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos3iv_Hook(const GLint* v) { + if (glWindowPos3iv_Impl) + glWindowPos3iv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos3s_Hook(GLshort x, GLshort y, GLshort z) { + if (glWindowPos3s_Impl) + glWindowPos3s_Impl(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glWindowPos3sv_Hook(const GLshort* v) { + if (glWindowPos3sv_Impl) + glWindowPos3sv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_1_5 +void OVR::GLEContext::glGenQueries_Hook(GLsizei n, GLuint* ids) { + if (glGenQueries_Impl) + glGenQueries_Impl(n, ids); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDeleteQueries_Hook(GLsizei n, const GLuint* ids) { + if (glDeleteQueries_Impl) + glDeleteQueries_Impl(n, ids); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glIsQuery_Hook(GLuint id) { + GLboolean b = GL_FALSE; + if (glIsQuery_Impl) + b = glIsQuery_Impl(id); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +void OVR::GLEContext::glBeginQuery_Hook(GLenum target, GLuint id) { + if (glBeginQuery_Impl) + glBeginQuery_Impl(target, id); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glEndQuery_Hook(GLenum target) { + if (glEndQuery_Impl) + glEndQuery_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetQueryiv_Hook(GLenum target, GLenum pname, GLint* params) { + if (glGetQueryiv_Impl) + glGetQueryiv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetQueryObjectiv_Hook(GLuint id, GLenum pname, GLint* params) { + if (glGetQueryObjectiv_Impl) + glGetQueryObjectiv_Impl(id, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetQueryObjectuiv_Hook(GLuint id, GLenum pname, GLuint* params) { + if (glGetQueryObjectuiv_Impl) + glGetQueryObjectuiv_Impl(id, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBindBuffer_Hook(GLenum target, GLuint buffer) { + if (glBindBuffer_Impl) + glBindBuffer_Impl(target, buffer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDeleteBuffers_Hook(GLsizei n, const GLuint* buffers) { + if (glDeleteBuffers_Impl) + glDeleteBuffers_Impl(n, buffers); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGenBuffers_Hook(GLsizei n, GLuint* buffers) { + if (glGenBuffers_Impl) + glGenBuffers_Impl(n, buffers); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glIsBuffer_Hook(GLuint buffer) { + GLboolean b = GL_FALSE; + if (glIsBuffer_Impl) + b = glIsBuffer_Impl(buffer); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +void OVR::GLEContext::glBufferData_Hook( + GLenum target, + GLsizeiptr size, + const GLvoid* data, + GLenum usage) { + if (glBufferData_Impl) + glBufferData_Impl(target, size, data, usage); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBufferSubData_Hook( + GLenum target, + GLintptr offset, + GLsizeiptr size, + const GLvoid* data) { + if (glBufferSubData_Impl) + glBufferSubData_Impl(target, offset, size, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetBufferSubData_Hook( + GLenum target, + GLintptr offset, + GLsizeiptr size, + GLvoid* data) { + if (glGetBufferSubData_Impl) + glGetBufferSubData_Impl(target, offset, size, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLvoid* OVR::GLEContext::glMapBuffer_Hook(GLenum target, GLenum access) { + GLvoid* p = NULL; + if (glMapBuffer_Impl) + p = glMapBuffer_Impl(target, access); + PostHook(GLE_CURRENT_FUNCTION); + return p; +} + +GLboolean OVR::GLEContext::glUnmapBuffer_Hook(GLenum target) { + GLboolean b = GL_FALSE; + if (glUnmapBuffer_Impl) + b = glUnmapBuffer_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +void OVR::GLEContext::glGetBufferParameteriv_Hook(GLenum target, GLenum pname, GLint* params) { + if (glGetBufferParameteriv_Impl) + glGetBufferParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetBufferPointerv_Hook(GLenum target, GLenum pname, GLvoid** params) { + if (glGetBufferPointerv_Impl) + glGetBufferPointerv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_2_0 +void OVR::GLEContext::glBlendEquationSeparate_Hook(GLenum modeRGB, GLenum modeAlpha) { + if (glBlendEquationSeparate_Impl) + glBlendEquationSeparate_Impl(modeRGB, modeAlpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDrawBuffers_Hook(GLsizei n, const GLenum* bufs) { + if (glDrawBuffers_Impl) + glDrawBuffers_Impl(n, bufs); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glStencilOpSeparate_Hook( + GLenum face, + GLenum sfail, + GLenum dpfail, + GLenum dppass) { + if (glStencilOpSeparate_Impl) + glStencilOpSeparate_Impl(face, sfail, dpfail, dppass); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glStencilFuncSeparate_Hook(GLenum face, GLenum func, GLint ref, GLuint mask) { + if (glStencilFuncSeparate_Impl) + glStencilFuncSeparate_Impl(face, func, ref, mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glStencilMaskSeparate_Hook(GLenum face, GLuint mask) { + if (glStencilMaskSeparate_Impl) + glStencilMaskSeparate_Impl(face, mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glAttachShader_Hook(GLuint program, GLuint shader) { + if (glAttachShader_Impl) + glAttachShader_Impl(program, shader); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBindAttribLocation_Hook(GLuint program, GLuint index, const GLchar* name) { + if (glBindAttribLocation_Impl) + glBindAttribLocation_Impl(program, index, name); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glCompileShader_Hook(GLuint shader) { + if (glCompileShader_Impl) + glCompileShader_Impl(shader); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLuint OVR::GLEContext::glCreateProgram_Hook() { + GLuint u = 0; + if (glCreateProgram_Impl) + u = glCreateProgram_Impl(); + PostHook(GLE_CURRENT_FUNCTION); + return u; +} + +GLuint OVR::GLEContext::glCreateShader_Hook(GLenum type) { + GLuint u = 0; + if (glCreateShader_Impl) + u = glCreateShader_Impl(type); + PostHook(GLE_CURRENT_FUNCTION); + return u; +} + +void OVR::GLEContext::glDeleteProgram_Hook(GLuint program) { + if (glDeleteProgram_Impl) + glDeleteProgram_Impl(program); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDeleteShader_Hook(GLuint shader) { + if (glDeleteShader_Impl) + glDeleteShader_Impl(shader); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDetachShader_Hook(GLuint program, GLuint shader) { + if (glDetachShader_Impl) + glDetachShader_Impl(program, shader); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDisableVertexAttribArray_Hook(GLuint index) { + if (glDisableVertexAttribArray_Impl) + glDisableVertexAttribArray_Impl(index); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glEnableVertexAttribArray_Hook(GLuint index) { + if (glEnableVertexAttribArray_Impl) + glEnableVertexAttribArray_Impl(index); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetActiveAttrib_Hook( + GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei* length, + GLint* size, + GLenum* type, + GLchar* name) { + if (glGetActiveAttrib_Impl) + glGetActiveAttrib_Impl(program, index, bufSize, length, size, type, name); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetActiveUniform_Hook( + GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei* length, + GLint* size, + GLenum* type, + GLchar* name) { + if (glGetActiveUniform_Impl) + glGetActiveUniform_Impl(program, index, bufSize, length, size, type, name); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetAttachedShaders_Hook( + GLuint program, + GLsizei maxCount, + GLsizei* count, + GLuint* obj) { + if (glGetAttachedShaders_Impl) + glGetAttachedShaders_Impl(program, maxCount, count, obj); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLint OVR::GLEContext::glGetAttribLocation_Hook(GLuint program, const GLchar* name) { + GLint i = 0; + if (glGetAttribLocation_Impl) + i = glGetAttribLocation_Impl(program, name); + PostHook(GLE_CURRENT_FUNCTION); + return i; +} + +void OVR::GLEContext::glGetProgramiv_Hook(GLuint program, GLenum pname, GLint* params) { + if (glGetProgramiv_Impl) + glGetProgramiv_Impl(program, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetProgramInfoLog_Hook( + GLuint program, + GLsizei bufSize, + GLsizei* length, + GLchar* infoLog) { + if (glGetProgramInfoLog_Impl) + glGetProgramInfoLog_Impl(program, bufSize, length, infoLog); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetShaderiv_Hook(GLuint shader, GLenum pname, GLint* params) { + if (glGetShaderiv_Impl) + glGetShaderiv_Impl(shader, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetShaderInfoLog_Hook( + GLuint shader, + GLsizei bufSize, + GLsizei* length, + GLchar* infoLog) { + if (glGetShaderInfoLog_Impl) + glGetShaderInfoLog_Impl(shader, bufSize, length, infoLog); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetShaderSource_Hook( + GLuint shader, + GLsizei bufSize, + GLsizei* length, + GLchar* source) { + if (glGetShaderSource_Impl) + glGetShaderSource_Impl(shader, bufSize, length, source); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLint OVR::GLEContext::glGetUniformLocation_Hook(GLuint program, const GLchar* name) { + GLint i = 0; + if (glGetUniformLocation_Impl) + i = glGetUniformLocation_Impl(program, name); + PostHook(GLE_CURRENT_FUNCTION); + return i; +} + +void OVR::GLEContext::glGetUniformfv_Hook(GLuint program, GLint location, GLfloat* params) { + if (glGetUniformfv_Impl) + glGetUniformfv_Impl(program, location, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetUniformiv_Hook(GLuint program, GLint location, GLint* params) { + if (glGetUniformiv_Impl) + glGetUniformiv_Impl(program, location, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetVertexAttribdv_Hook(GLuint index, GLenum pname, GLdouble* params) { + if (glGetVertexAttribdv_Impl) + glGetVertexAttribdv_Impl(index, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetVertexAttribfv_Hook(GLuint index, GLenum pname, GLfloat* params) { + if (glGetVertexAttribfv_Impl) + glGetVertexAttribfv_Impl(index, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetVertexAttribiv_Hook(GLuint index, GLenum pname, GLint* params) { + if (glGetVertexAttribiv_Impl) + glGetVertexAttribiv_Impl(index, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetVertexAttribPointerv_Hook(GLuint index, GLenum pname, GLvoid** pointer) { + if (glGetVertexAttribPointerv_Impl) + glGetVertexAttribPointerv_Impl(index, pname, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glIsProgram_Hook(GLuint program) { + GLboolean b = GL_FALSE; + if (glIsProgram_Impl) + b = glIsProgram_Impl(program); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +GLboolean OVR::GLEContext::glIsShader_Hook(GLuint shader) { + GLboolean b = GL_FALSE; + if (glIsShader_Impl) + b = glIsShader_Impl(shader); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +void OVR::GLEContext::glLinkProgram_Hook(GLuint program) { + if (glLinkProgram_Impl) + glLinkProgram_Impl(program); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glShaderSource_Hook( + GLuint shader, + GLsizei count, + const GLchar** string, + const GLint* length) { + if (glShaderSource_Impl) + glShaderSource_Impl(shader, count, string, length); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUseProgram_Hook(GLuint program) { + if (glUseProgram_Impl) + glUseProgram_Impl(program); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform1f_Hook(GLint location, GLfloat v0) { + if (glUniform1f_Impl) + glUniform1f_Impl(location, v0); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform2f_Hook(GLint location, GLfloat v0, GLfloat v1) { + if (glUniform2f_Impl) + glUniform2f_Impl(location, v0, v1); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform3f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { + if (glUniform3f_Impl) + glUniform3f_Impl(location, v0, v1, v2); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform4f_Hook( + GLint location, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3) { + if (glUniform4f_Impl) + glUniform4f_Impl(location, v0, v1, v2, v3); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform1i_Hook(GLint location, GLint v0) { + if (glUniform1i_Impl) + glUniform1i_Impl(location, v0); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform2i_Hook(GLint location, GLint v0, GLint v1) { + if (glUniform2i_Impl) + glUniform2i_Impl(location, v0, v1); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform3i_Hook(GLint location, GLint v0, GLint v1, GLint v2) { + if (glUniform3i_Impl) + glUniform3i_Impl(location, v0, v1, v2); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform4i_Hook(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) { + if (glUniform4i_Impl) + glUniform4i_Impl(location, v0, v1, v2, v3); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform1fv_Hook(GLint location, GLsizei count, const GLfloat* value) { + if (glUniform1fv_Impl) + glUniform1fv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform2fv_Hook(GLint location, GLsizei count, const GLfloat* value) { + if (glUniform2fv_Impl) + glUniform2fv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform3fv_Hook(GLint location, GLsizei count, const GLfloat* value) { + if (glUniform3fv_Impl) + glUniform3fv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform4fv_Hook(GLint location, GLsizei count, const GLfloat* value) { + if (glUniform4fv_Impl) + glUniform4fv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform1iv_Hook(GLint location, GLsizei count, const GLint* value) { + if (glUniform1iv_Impl) + glUniform1iv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform2iv_Hook(GLint location, GLsizei count, const GLint* value) { + if (glUniform2iv_Impl) + glUniform2iv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform3iv_Hook(GLint location, GLsizei count, const GLint* value) { + if (glUniform3iv_Impl) + glUniform3iv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform4iv_Hook(GLint location, GLsizei count, const GLint* value) { + if (glUniform4iv_Impl) + glUniform4iv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniformMatrix2fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + if (glUniformMatrix2fv_Impl) + glUniformMatrix2fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniformMatrix3fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + if (glUniformMatrix3fv_Impl) + glUniformMatrix3fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniformMatrix4fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + if (glUniformMatrix4fv_Impl) + glUniformMatrix4fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glValidateProgram_Hook(GLuint program) { + if (glValidateProgram_Impl) + glValidateProgram_Impl(program); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib1d_Hook(GLuint index, GLdouble x) { + if (glVertexAttrib1d_Impl) + glVertexAttrib1d_Impl(index, x); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib1dv_Hook(GLuint index, const GLdouble* v) { + if (glVertexAttrib1dv_Impl) + glVertexAttrib1dv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib1f_Hook(GLuint index, GLfloat x) { + if (glVertexAttrib1f_Impl) + glVertexAttrib1f_Impl(index, x); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib1fv_Hook(GLuint index, const GLfloat* v) { + if (glVertexAttrib1fv_Impl) + glVertexAttrib1fv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib1s_Hook(GLuint index, GLshort x) { + if (glVertexAttrib1s_Impl) + glVertexAttrib1s_Impl(index, x); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib1sv_Hook(GLuint index, const GLshort* v) { + if (glVertexAttrib1sv_Impl) + glVertexAttrib1sv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib2d_Hook(GLuint index, GLdouble x, GLdouble y) { + if (glVertexAttrib2d_Impl) + glVertexAttrib2d_Impl(index, x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib2dv_Hook(GLuint index, const GLdouble* v) { + if (glVertexAttrib2dv_Impl) + glVertexAttrib2dv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib2f_Hook(GLuint index, GLfloat x, GLfloat y) { + if (glVertexAttrib2f_Impl) + glVertexAttrib2f_Impl(index, x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib2fv_Hook(GLuint index, const GLfloat* v) { + if (glVertexAttrib2fv_Impl) + glVertexAttrib2fv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib2s_Hook(GLuint index, GLshort x, GLshort y) { + if (glVertexAttrib2s_Impl) + glVertexAttrib2s_Impl(index, x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib2sv_Hook(GLuint index, const GLshort* v) { + if (glVertexAttrib2sv_Impl) + glVertexAttrib2sv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib3d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z) { + if (glVertexAttrib3d_Impl) + glVertexAttrib3d_Impl(index, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib3dv_Hook(GLuint index, const GLdouble* v) { + if (glVertexAttrib3dv_Impl) + glVertexAttrib3dv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib3f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z) { + if (glVertexAttrib3f_Impl) + glVertexAttrib3f_Impl(index, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib3fv_Hook(GLuint index, const GLfloat* v) { + if (glVertexAttrib3fv_Impl) + glVertexAttrib3fv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib3s_Hook(GLuint index, GLshort x, GLshort y, GLshort z) { + if (glVertexAttrib3s_Impl) + glVertexAttrib3s_Impl(index, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib3sv_Hook(GLuint index, const GLshort* v) { + if (glVertexAttrib3sv_Impl) + glVertexAttrib3sv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4Nbv_Hook(GLuint index, const GLbyte* v) { + if (glVertexAttrib4Nbv_Impl) + glVertexAttrib4Nbv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4Niv_Hook(GLuint index, const GLint* v) { + if (glVertexAttrib4Niv_Impl) + glVertexAttrib4Niv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4Nsv_Hook(GLuint index, const GLshort* v) { + if (glVertexAttrib4Nsv_Impl) + glVertexAttrib4Nsv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4Nub_Hook( + GLuint index, + GLubyte x, + GLubyte y, + GLubyte z, + GLubyte w) { + if (glVertexAttrib4Nub_Impl) + glVertexAttrib4Nub_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4Nubv_Hook(GLuint index, const GLubyte* v) { + if (glVertexAttrib4Nubv_Impl) + glVertexAttrib4Nubv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4Nuiv_Hook(GLuint index, const GLuint* v) { + if (glVertexAttrib4Nuiv_Impl) + glVertexAttrib4Nuiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4Nusv_Hook(GLuint index, const GLushort* v) { + if (glVertexAttrib4Nusv_Impl) + glVertexAttrib4Nusv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4bv_Hook(GLuint index, const GLbyte* v) { + if (glVertexAttrib4bv_Impl) + glVertexAttrib4bv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4d_Hook( + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w) { + if (glVertexAttrib4d_Impl) + glVertexAttrib4d_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4dv_Hook(GLuint index, const GLdouble* v) { + if (glVertexAttrib4dv_Impl) + glVertexAttrib4dv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4f_Hook( + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w) { + if (glVertexAttrib4f_Impl) + glVertexAttrib4f_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4fv_Hook(GLuint index, const GLfloat* v) { + if (glVertexAttrib4fv_Impl) + glVertexAttrib4fv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4iv_Hook(GLuint index, const GLint* v) { + if (glVertexAttrib4iv_Impl) + glVertexAttrib4iv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4s_Hook( + GLuint index, + GLshort x, + GLshort y, + GLshort z, + GLshort w) { + if (glVertexAttrib4s_Impl) + glVertexAttrib4s_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4sv_Hook(GLuint index, const GLshort* v) { + if (glVertexAttrib4sv_Impl) + glVertexAttrib4sv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4ubv_Hook(GLuint index, const GLubyte* v) { + if (glVertexAttrib4ubv_Impl) + glVertexAttrib4ubv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4uiv_Hook(GLuint index, const GLuint* v) { + if (glVertexAttrib4uiv_Impl) + glVertexAttrib4uiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttrib4usv_Hook(GLuint index, const GLushort* v) { + if (glVertexAttrib4usv_Impl) + glVertexAttrib4usv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribPointer_Hook( + GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const GLvoid* pointer) { + if (glVertexAttribPointer_Impl) + glVertexAttribPointer_Impl(index, size, type, normalized, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_2_1 +void OVR::GLEContext::glUniformMatrix2x3fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + if (glUniformMatrix2x3fv_Impl) + glUniformMatrix2x3fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniformMatrix3x2fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + if (glUniformMatrix3x2fv_Impl) + glUniformMatrix3x2fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniformMatrix2x4fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + if (glUniformMatrix2x4fv_Impl) + glUniformMatrix2x4fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniformMatrix4x2fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + if (glUniformMatrix4x2fv_Impl) + glUniformMatrix4x2fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniformMatrix3x4fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + if (glUniformMatrix3x4fv_Impl) + glUniformMatrix3x4fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniformMatrix4x3fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value) { + if (glUniformMatrix4x3fv_Impl) + glUniformMatrix4x3fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_3_0 +void OVR::GLEContext::glColorMaski_Hook( + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a) { + if (glColorMaski_Impl) + glColorMaski_Impl(index, r, g, b, a); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetBooleani_v_Hook(GLenum target, GLuint index, GLboolean* data) { + if (glGetBooleani_v_Impl) + glGetBooleani_v_Impl(target, index, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetIntegeri_v_Hook(GLenum target, GLuint index, GLint* data) { + if (glGetIntegeri_v_Impl) + glGetIntegeri_v_Impl(target, index, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glEnablei_Hook(GLenum target, GLuint index) { + if (glEnablei_Impl) + glEnablei_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDisablei_Hook(GLenum target, GLuint index) { + if (glDisablei_Impl) + glDisablei_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glIsEnabledi_Hook(GLenum target, GLuint index) { + GLboolean b = GL_FALSE; + if (glIsEnabledi_Impl) + b = glIsEnabledi_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +void OVR::GLEContext::glBeginTransformFeedback_Hook(GLenum primitiveMode) { + if (glBeginTransformFeedback_Impl) + glBeginTransformFeedback_Impl(primitiveMode); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glEndTransformFeedback_Hook() { + if (glEndTransformFeedback_Impl) + glEndTransformFeedback_Impl(); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBindBufferRange_Hook( + GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) { + if (glBindBufferRange_Impl) + glBindBufferRange_Impl(target, index, buffer, offset, size); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBindBufferBase_Hook(GLenum target, GLuint index, GLuint buffer) { + if (glBindBufferBase_Impl) + glBindBufferBase_Impl(target, index, buffer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTransformFeedbackVaryings_Hook( + GLuint program, + GLsizei count, + const GLchar** varyings, + GLenum bufferMode) { + if (glTransformFeedbackVaryings_Impl) + glTransformFeedbackVaryings_Impl(program, count, varyings, bufferMode); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetTransformFeedbackVarying_Hook( + GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei* length, + GLsizei* size, + GLenum* type, + GLchar* name) { + if (glGetTransformFeedbackVarying_Impl) + glGetTransformFeedbackVarying_Impl(program, index, bufSize, length, size, type, name); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glClampColor_Hook(GLenum target, GLenum clamp) { + if (glClampColor_Impl) + glClampColor_Impl(target, clamp); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBeginConditionalRender_Hook(GLuint id, GLenum mode) { + if (glBeginConditionalRender_Impl) + glBeginConditionalRender_Impl(id, mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glEndConditionalRender_Hook() { + if (glEndConditionalRender_Impl) + glEndConditionalRender_Impl(); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribIPointer_Hook( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid* pointer) { + if (glVertexAttribIPointer_Impl) + glVertexAttribIPointer_Impl(index, size, type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetVertexAttribIiv_Hook(GLuint index, GLenum pname, GLint* params) { + if (glGetVertexAttribIiv_Impl) + glGetVertexAttribIiv_Impl(index, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetVertexAttribIuiv_Hook(GLuint index, GLenum pname, GLuint* params) { + if (glGetVertexAttribIuiv_Impl) + glGetVertexAttribIuiv_Impl(index, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI1i_Hook(GLuint index, GLint x) { + if (glVertexAttribI1i_Impl) + glVertexAttribI1i_Impl(index, x); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI2i_Hook(GLuint index, GLint x, GLint y) { + if (glVertexAttribI2i_Impl) + glVertexAttribI2i_Impl(index, x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI3i_Hook(GLuint index, GLint x, GLint y, GLint z) { + if (glVertexAttribI3i_Impl) + glVertexAttribI3i_Impl(index, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI4i_Hook(GLuint index, GLint x, GLint y, GLint z, GLint w) { + if (glVertexAttribI4i_Impl) + glVertexAttribI4i_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI1ui_Hook(GLuint index, GLuint x) { + if (glVertexAttribI1ui_Impl) + glVertexAttribI1ui_Impl(index, x); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI2ui_Hook(GLuint index, GLuint x, GLuint y) { + if (glVertexAttribI2ui_Impl) + glVertexAttribI2ui_Impl(index, x, y); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI3ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z) { + if (glVertexAttribI3ui_Impl) + glVertexAttribI3ui_Impl(index, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI4ui_Hook( + GLuint index, + GLuint x, + GLuint y, + GLuint z, + GLuint w) { + if (glVertexAttribI4ui_Impl) + glVertexAttribI4ui_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI1iv_Hook(GLuint index, const GLint* v) { + if (glVertexAttribI1iv_Impl) + glVertexAttribI1iv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI2iv_Hook(GLuint index, const GLint* v) { + if (glVertexAttribI2iv_Impl) + glVertexAttribI2iv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI3iv_Hook(GLuint index, const GLint* v) { + if (glVertexAttribI3iv_Impl) + glVertexAttribI3iv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI4iv_Hook(GLuint index, const GLint* v) { + if (glVertexAttribI4iv_Impl) + glVertexAttribI4iv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI1uiv_Hook(GLuint index, const GLuint* v) { + if (glVertexAttribI1uiv_Impl) + glVertexAttribI1uiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI2uiv_Hook(GLuint index, const GLuint* v) { + if (glVertexAttribI2uiv_Impl) + glVertexAttribI2uiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI3uiv_Hook(GLuint index, const GLuint* v) { + if (glVertexAttribI3uiv_Impl) + glVertexAttribI3uiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI4uiv_Hook(GLuint index, const GLuint* v) { + if (glVertexAttribI4uiv_Impl) + glVertexAttribI4uiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI4bv_Hook(GLuint index, const GLbyte* v) { + if (glVertexAttribI4bv_Impl) + glVertexAttribI4bv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI4sv_Hook(GLuint index, const GLshort* v) { + if (glVertexAttribI4sv_Impl) + glVertexAttribI4sv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI4ubv_Hook(GLuint index, const GLubyte* v) { + if (glVertexAttribI4ubv_Impl) + glVertexAttribI4ubv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexAttribI4usv_Hook(GLuint index, const GLushort* v) { + if (glVertexAttribI4usv_Impl) + glVertexAttribI4usv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetUniformuiv_Hook(GLuint program, GLint location, GLuint* params) { + if (glGetUniformuiv_Impl) + glGetUniformuiv_Impl(program, location, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBindFragDataLocation_Hook( + GLuint program, + GLuint color, + const GLchar* name) { + if (glBindFragDataLocation_Impl) + glBindFragDataLocation_Impl(program, color, name); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLint OVR::GLEContext::glGetFragDataLocation_Hook(GLuint program, const GLchar* name) { + GLint i = 0; + if (glGetFragDataLocation_Impl) + i = glGetFragDataLocation_Impl(program, name); + PostHook(GLE_CURRENT_FUNCTION); + return i; +} + +void OVR::GLEContext::glUniform1ui_Hook(GLint location, GLuint v0) { + if (glUniform1ui_Impl) + glUniform1ui_Impl(location, v0); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform2ui_Hook(GLint location, GLuint v0, GLuint v1) { + if (glUniform2ui_Impl) + glUniform2ui_Impl(location, v0, v1); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform3ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2) { + if (glUniform3ui_Impl) + glUniform3ui_Impl(location, v0, v1, v2); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform4ui_Hook( + GLint location, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) { + if (glUniform4ui_Impl) + glUniform4ui_Impl(location, v0, v1, v2, v3); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform1uiv_Hook(GLint location, GLsizei count, const GLuint* value) { + if (glUniform1uiv_Impl) + glUniform1uiv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform2uiv_Hook(GLint location, GLsizei count, const GLuint* value) { + if (glUniform2uiv_Impl) + glUniform2uiv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform3uiv_Hook(GLint location, GLsizei count, const GLuint* value) { + if (glUniform3uiv_Impl) + glUniform3uiv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glUniform4uiv_Hook(GLint location, GLsizei count, const GLuint* value) { + if (glUniform4uiv_Impl) + glUniform4uiv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTexParameterIiv_Hook(GLenum target, GLenum pname, const GLint* params) { + if (glTexParameterIiv_Impl) + glTexParameterIiv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTexParameterIuiv_Hook(GLenum target, GLenum pname, const GLuint* params) { + if (glTexParameterIuiv_Impl) + glTexParameterIuiv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetTexParameterIiv_Hook(GLenum target, GLenum pname, GLint* params) { + if (glGetTexParameterIiv_Impl) + glGetTexParameterIiv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetTexParameterIuiv_Hook(GLenum target, GLenum pname, GLuint* params) { + if (glGetTexParameterIuiv_Impl) + glGetTexParameterIuiv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glClearBufferiv_Hook(GLenum buffer, GLint drawbuffer, const GLint* value) { + if (glClearBufferiv_Impl) + glClearBufferiv_Impl(buffer, drawbuffer, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glClearBufferuiv_Hook(GLenum buffer, GLint drawbuffer, const GLuint* value) { + if (glClearBufferuiv_Impl) + glClearBufferuiv_Impl(buffer, drawbuffer, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glClearBufferfv_Hook(GLenum buffer, GLint drawbuffer, const GLfloat* value) { + if (glClearBufferfv_Impl) + glClearBufferfv_Impl(buffer, drawbuffer, value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glClearBufferfi_Hook( + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) { + if (glClearBufferfi_Impl) + glClearBufferfi_Impl(buffer, drawbuffer, depth, stencil); + PostHook(GLE_CURRENT_FUNCTION); +} + +const GLubyte* OVR::GLEContext::glGetStringi_Hook(GLenum name, GLuint index) { + const GLubyte* p = NULL; + if (glGetStringi_Impl) + p = glGetStringi_Impl(name, index); + PostHook(GLE_CURRENT_FUNCTION); + return p; +} + +// GL_VERSION_3_1 +void OVR::GLEContext::glDrawArraysInstanced_Hook( + GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount) { + if (glDrawArraysInstanced_Impl) + glDrawArraysInstanced_Impl(mode, first, count, primcount); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDrawElementsInstanced_Hook( + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid* indices, + GLsizei primcount) { + if (glDrawElementsInstanced_Impl) + glDrawElementsInstanced_Impl(mode, count, type, indices, primcount); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTexBuffer_Hook(GLenum target, GLenum internalformat, GLuint buffer) { + if (glTexBuffer_Impl) + glTexBuffer_Impl(target, internalformat, buffer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glPrimitiveRestartIndex_Hook(GLuint index) { + if (glPrimitiveRestartIndex_Impl) + glPrimitiveRestartIndex_Impl(index); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_3_2 +void OVR::GLEContext::glGetInteger64i_v_Hook(GLenum target, GLuint index, GLint64* data) { + if (glGetInteger64i_v_Impl) + glGetInteger64i_v_Impl(target, index, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetBufferParameteri64v_Hook(GLenum target, GLenum pname, GLint64* params) { + if (glGetBufferParameteri64v_Impl) + glGetBufferParameteri64v_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFramebufferTexture_Hook( + GLenum target, + GLenum attachment, + GLuint texture, + GLint level) { + if (glFramebufferTexture_Impl) + glFramebufferTexture_Impl(target, attachment, texture, level); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_3_3 +void OVR::GLEContext::glVertexAttribDivisor_Hook(GLuint index, GLuint divisor) { + if (glVertexAttribDivisor_Impl) + glVertexAttribDivisor_Impl(index, divisor); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_VERSION_4_0 +void OVR::GLEContext::glMinSampleShading_Hook(GLclampf value) { + if (glMinSampleShading_Impl) + glMinSampleShading_Impl(value); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBlendEquationi_Hook(GLuint buf, GLenum mode) { + if (glBlendEquationi_Impl) + glBlendEquationi_Impl(buf, mode); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBlendEquationSeparatei_Hook(GLuint buf, GLenum modeRGB, GLenum modeAlpha) { + if (glBlendEquationSeparatei_Impl) + glBlendEquationSeparatei_Impl(buf, modeRGB, modeAlpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBlendFunci_Hook(GLuint buf, GLenum src, GLenum dst) { + if (glBlendFunci_Impl) + glBlendFunci_Impl(buf, src, dst); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBlendFuncSeparatei_Hook( + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha) { + if (glBlendFuncSeparatei_Impl) + glBlendFuncSeparatei_Impl(buf, srcRGB, dstRGB, srcAlpha, dstAlpha); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_AMD_debug_output +void OVR::GLEContext::glDebugMessageEnableAMD_Hook( + GLenum category, + GLenum severity, + GLsizei count, + const GLuint* ids, + GLboolean enabled) { + if (glDebugMessageEnableAMD_Impl) + glDebugMessageEnableAMD_Impl(category, severity, count, ids, enabled); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDebugMessageInsertAMD_Hook( + GLenum category, + GLenum severity, + GLuint id, + GLsizei length, + const GLchar* buf) { + if (glDebugMessageInsertAMD_Impl) + glDebugMessageInsertAMD_Impl(category, severity, id, length, buf); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDebugMessageCallbackAMD_Hook(GLDEBUGPROCAMD callback, GLvoid* userParam) { + if (glDebugMessageCallbackAMD_Impl) + glDebugMessageCallbackAMD_Impl(callback, userParam); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLuint OVR::GLEContext::glGetDebugMessageLogAMD_Hook( + GLuint count, + GLsizei bufsize, + GLenum* categories, + GLuint* severities, + GLuint* ids, + GLsizei* lengths, + GLchar* message) { + GLuint u = 0; + if (glGetDebugMessageLogAMD_Impl) + u = glGetDebugMessageLogAMD_Impl(count, bufsize, categories, severities, ids, lengths, message); + PostHook(GLE_CURRENT_FUNCTION); + return u; +} + +#if defined(GLE_CGL_ENABLED) +// GL_APPLE_element_array +void OVR::GLEContext::glElementPointerAPPLE_Hook(GLenum type, const GLvoid* pointer) { + if (glElementPointerAPPLE_Impl) + glElementPointerAPPLE_Impl(type, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDrawElementArrayAPPLE_Hook(GLenum mode, GLint first, GLsizei count) { + if (glDrawElementArrayAPPLE_Impl) + glDrawElementArrayAPPLE_Impl(mode, first, count); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDrawRangeElementArrayAPPLE_Hook( + GLenum mode, + GLuint start, + GLuint end, + GLint first, + GLsizei count) { + if (glDrawRangeElementArrayAPPLE_Impl) + glDrawRangeElementArrayAPPLE_Impl(mode, start, end, first, count); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiDrawElementArrayAPPLE_Hook( + GLenum mode, + const GLint* first, + const GLsizei* count, + GLsizei primcount) { + if (glMultiDrawElementArrayAPPLE_Impl) + glMultiDrawElementArrayAPPLE_Impl(mode, first, count, primcount); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMultiDrawRangeElementArrayAPPLE_Hook( + GLenum mode, + GLuint start, + GLuint end, + const GLint* first, + const GLsizei* count, + GLsizei primcount) { + if (glMultiDrawRangeElementArrayAPPLE_Impl) + glMultiDrawRangeElementArrayAPPLE_Impl(mode, start, end, first, count, primcount); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_APPLE_fence +void OVR::GLEContext::glGenFencesAPPLE_Hook(GLsizei n, GLuint* fences) { + if (glGenFencesAPPLE_Impl) + glGenFencesAPPLE_Impl(n, fences); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDeleteFencesAPPLE_Hook(GLsizei n, const GLuint* fences) { + if (glDeleteFencesAPPLE_Impl) + glDeleteFencesAPPLE_Impl(n, fences); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSetFenceAPPLE_Hook(GLuint fence) { + if (glSetFenceAPPLE_Impl) + glSetFenceAPPLE_Impl(fence); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glIsFenceAPPLE_Hook(GLuint fence) { + GLboolean b = GL_FALSE; + if (glIsFenceAPPLE_Impl) + b = glIsFenceAPPLE_Impl(fence); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +GLboolean OVR::GLEContext::glTestFenceAPPLE_Hook(GLuint fence) { + GLboolean b = GL_FALSE; + if (glTestFenceAPPLE_Impl) + b = glTestFenceAPPLE_Impl(fence); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +void OVR::GLEContext::glFinishFenceAPPLE_Hook(GLuint fence) { + if (glFinishFenceAPPLE_Impl) + glFinishFenceAPPLE_Impl(fence); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glTestObjectAPPLE_Hook(GLenum object, GLuint name) { + GLboolean b = GL_FALSE; + if (glTestObjectAPPLE_Impl) + b = glTestObjectAPPLE_Impl(object, name); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +void OVR::GLEContext::glFinishObjectAPPLE_Hook(GLenum object, GLint name) { + if (glFinishObjectAPPLE_Impl) + glFinishObjectAPPLE_Impl(object, name); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_APPLE_flush_buffer_range +void OVR::GLEContext::glBufferParameteriAPPLE_Hook(GLenum target, GLenum pname, GLint param) { + if (glBufferParameteriAPPLE_Impl) + glBufferParameteriAPPLE_Impl(target, pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFlushMappedBufferRangeAPPLE_Hook( + GLenum target, + GLintptr offset, + GLsizeiptr size) { + if (glFlushMappedBufferRangeAPPLE_Impl) + glFlushMappedBufferRangeAPPLE_Impl(target, offset, size); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_APPLE_object_purgeable +GLenum OVR::GLEContext::glObjectPurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option) { + GLenum e = 0; + if (glObjectPurgeableAPPLE_Impl) + e = glObjectPurgeableAPPLE_Impl(objectType, name, option); + PostHook(GLE_CURRENT_FUNCTION); + return e; +} + +GLenum +OVR::GLEContext::glObjectUnpurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option) { + GLenum e = 0; + if (glObjectUnpurgeableAPPLE_Impl) + e = glObjectUnpurgeableAPPLE_Impl(objectType, name, option); + PostHook(GLE_CURRENT_FUNCTION); + return e; +} + +void OVR::GLEContext::glGetObjectParameterivAPPLE_Hook( + GLenum objectType, + GLuint name, + GLenum pname, + GLint* params) { + if (glGetObjectParameterivAPPLE_Impl) + glGetObjectParameterivAPPLE_Impl(objectType, name, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_APPLE_texture_range +void OVR::GLEContext::glTextureRangeAPPLE_Hook( + GLenum target, + GLsizei length, + const GLvoid* pointer) { + if (glTextureRangeAPPLE_Impl) + glTextureRangeAPPLE_Impl(target, length, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetTexParameterPointervAPPLE_Hook( + GLenum target, + GLenum pname, + GLvoid** params) { + if (glGetTexParameterPointervAPPLE_Impl) + glGetTexParameterPointervAPPLE_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_APPLE_vertex_array_object +void OVR::GLEContext::glBindVertexArrayAPPLE_Hook(GLuint array) { + if (glBindVertexArrayAPPLE_Impl) + glBindVertexArrayAPPLE_Impl(array); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDeleteVertexArraysAPPLE_Hook(GLsizei n, const GLuint* arrays) { + if (glDeleteVertexArraysAPPLE_Impl) + glDeleteVertexArraysAPPLE_Impl(n, arrays); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGenVertexArraysAPPLE_Hook(GLsizei n, GLuint* arrays) { + if (glGenVertexArraysAPPLE_Impl) + glGenVertexArraysAPPLE_Impl(n, arrays); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glIsVertexArrayAPPLE_Hook(GLuint array) { + GLboolean b = GL_FALSE; + if (glIsVertexArrayAPPLE_Impl) + b = glIsVertexArrayAPPLE_Impl(array); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +// GL_APPLE_vertex_array_range +void OVR::GLEContext::glVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid* pointer) { + if (glVertexArrayRangeAPPLE_Impl) + glVertexArrayRangeAPPLE_Impl(length, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFlushVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid* pointer) { + if (glFlushVertexArrayRangeAPPLE_Impl) + glFlushVertexArrayRangeAPPLE_Impl(length, pointer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glVertexArrayParameteriAPPLE_Hook(GLenum pname, GLint param) { + if (glVertexArrayParameteriAPPLE_Impl) + glVertexArrayParameteriAPPLE_Impl(pname, param); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_APPLE_vertex_program_evaluators +void OVR::GLEContext::glEnableVertexAttribAPPLE_Hook(GLuint index, GLenum pname) { + if (glEnableVertexAttribAPPLE_Impl) + glEnableVertexAttribAPPLE_Impl(index, pname); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDisableVertexAttribAPPLE_Hook(GLuint index, GLenum pname) { + if (glDisableVertexAttribAPPLE_Impl) + glDisableVertexAttribAPPLE_Impl(index, pname); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glIsVertexAttribEnabledAPPLE_Hook(GLuint index, GLenum pname) { + GLboolean b = GL_FALSE; + if (glIsVertexAttribEnabledAPPLE_Impl) + b = glIsVertexAttribEnabledAPPLE_Impl(index, pname); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +void OVR::GLEContext::glMapVertexAttrib1dAPPLE_Hook( + GLuint index, + GLuint size, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble* points) { + if (glMapVertexAttrib1dAPPLE_Impl) + glMapVertexAttrib1dAPPLE_Impl(index, size, u1, u2, stride, order, points); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMapVertexAttrib1fAPPLE_Hook( + GLuint index, + GLuint size, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat* points) { + if (glMapVertexAttrib1fAPPLE_Impl) + glMapVertexAttrib1fAPPLE_Impl(index, size, u1, u2, stride, order, points); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMapVertexAttrib2dAPPLE_Hook( + GLuint index, + GLuint size, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble* points) { + if (glMapVertexAttrib2dAPPLE_Impl) + glMapVertexAttrib2dAPPLE_Impl( + index, size, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glMapVertexAttrib2fAPPLE_Hook( + GLuint index, + GLuint size, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat* points) { + if (glMapVertexAttrib2fAPPLE_Impl) + glMapVertexAttrib2fAPPLE_Impl( + index, size, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); + PostHook(GLE_CURRENT_FUNCTION); +} +#endif // GLE_CGL_ENABLED + +// GL_ARB_copy_buffer +void OVR::GLEContext::glCopyBufferSubData_Hook( + GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size) { + if (glCopyBufferSubData_Impl) + glCopyBufferSubData_Impl(readtarget, writetarget, readoffset, writeoffset, size); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_ARB_debug_output +void OVR::GLEContext::glDebugMessageControlARB_Hook( + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint* ids, + GLboolean enabled) { + if (glDebugMessageControlARB_Impl) + glDebugMessageControlARB_Impl(source, type, severity, count, ids, enabled); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDebugMessageInsertARB_Hook( + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* buf) { + if (glDebugMessageInsertARB_Impl) + glDebugMessageInsertARB_Impl(source, type, id, severity, length, buf); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDebugMessageCallbackARB_Hook( + GLDEBUGPROCARB callback, + const GLvoid* userParam) { + if (glDebugMessageCallbackARB_Impl) + glDebugMessageCallbackARB_Impl(callback, userParam); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLuint OVR::GLEContext::glGetDebugMessageLogARB_Hook( + GLuint count, + GLsizei bufsize, + GLenum* sources, + GLenum* types, + GLuint* ids, + GLenum* severities, + GLsizei* lengths, + GLchar* messageLog) { + GLuint u = 0; + if (glGetDebugMessageLogARB_Impl) + u = glGetDebugMessageLogARB_Impl( + count, bufsize, sources, types, ids, severities, lengths, messageLog); + PostHook(GLE_CURRENT_FUNCTION); + return u; +} + +// GL_ARB_ES2_compatibility +void OVR::GLEContext::glReleaseShaderCompiler_Hook() { + if (glReleaseShaderCompiler_Impl) + glReleaseShaderCompiler_Impl(); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glShaderBinary_Hook( + GLsizei count, + const GLuint* shaders, + GLenum binaryformat, + const GLvoid* binary, + GLsizei length) { + if (glShaderBinary_Impl) + glShaderBinary_Impl(count, shaders, binaryformat, binary, length); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetShaderPrecisionFormat_Hook( + GLenum shadertype, + GLenum precisiontype, + GLint* range, + GLint* precision) { + if (glGetShaderPrecisionFormat_Impl) + glGetShaderPrecisionFormat_Impl(shadertype, precisiontype, range, precision); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDepthRangef_Hook(GLclampf n, GLclampf f) { + if (glDepthRangef_Impl) + glDepthRangef_Impl(n, f); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glClearDepthf_Hook(GLclampf d) { + if (glClearDepthf_Impl) + glClearDepthf_Impl(d); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_ARB_framebuffer_object +GLboolean OVR::GLEContext::glIsRenderbuffer_Hook(GLuint renderbuffer) { + GLboolean b = GL_FALSE; + if (glIsRenderbuffer_Impl) + b = glIsRenderbuffer_Impl(renderbuffer); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +void OVR::GLEContext::glBindRenderbuffer_Hook(GLenum target, GLuint renderbuffer) { + if (glBindRenderbuffer_Impl) + glBindRenderbuffer_Impl(target, renderbuffer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDeleteRenderbuffers_Hook(GLsizei n, const GLuint* renderbuffers) { + if (glDeleteRenderbuffers_Impl) + glDeleteRenderbuffers_Impl(n, renderbuffers); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGenRenderbuffers_Hook(GLsizei n, GLuint* renderbuffers) { + if (glGenRenderbuffers_Impl) + glGenRenderbuffers_Impl(n, renderbuffers); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glRenderbufferStorage_Hook( + GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height) { + if (glRenderbufferStorage_Impl) + glRenderbufferStorage_Impl(target, internalformat, width, height); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetRenderbufferParameteriv_Hook( + GLenum target, + GLenum pname, + GLint* params) { + if (glGetRenderbufferParameteriv_Impl) + glGetRenderbufferParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glIsFramebuffer_Hook(GLuint framebuffer) { + GLboolean b = GL_FALSE; + if (glIsFramebuffer_Impl) + b = glIsFramebuffer_Impl(framebuffer); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +void OVR::GLEContext::glBindFramebuffer_Hook(GLenum target, GLuint framebuffer) { + if (glBindFramebuffer_Impl) + glBindFramebuffer_Impl(target, framebuffer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDeleteFramebuffers_Hook(GLsizei n, const GLuint* framebuffers) { + if (glDeleteFramebuffers_Impl) + glDeleteFramebuffers_Impl(n, framebuffers); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGenFramebuffers_Hook(GLsizei n, GLuint* framebuffers) { + if (glGenFramebuffers_Impl) + glGenFramebuffers_Impl(n, framebuffers); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLenum OVR::GLEContext::glCheckFramebufferStatus_Hook(GLenum target) { + GLenum e = 0; + if (glCheckFramebufferStatus_Impl) + e = glCheckFramebufferStatus_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); + return e; +} + +void OVR::GLEContext::glFramebufferTexture1D_Hook( + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level) { + if (glFramebufferTexture1D_Impl) + glFramebufferTexture1D_Impl(target, attachment, textarget, texture, level); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFramebufferTexture2D_Hook( + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level) { + if (glFramebufferTexture2D_Impl) + glFramebufferTexture2D_Impl(target, attachment, textarget, texture, level); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFramebufferTexture3D_Hook( + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level, + GLint zoffset) { + if (glFramebufferTexture3D_Impl) + glFramebufferTexture3D_Impl(target, attachment, textarget, texture, level, zoffset); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFramebufferRenderbuffer_Hook( + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer) { + if (glFramebufferRenderbuffer_Impl) + glFramebufferRenderbuffer_Impl(target, attachment, renderbuffertarget, renderbuffer); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetFramebufferAttachmentParameteriv_Hook( + GLenum target, + GLenum attachment, + GLenum pname, + GLint* params) { + if (glGetFramebufferAttachmentParameteriv_Impl) + glGetFramebufferAttachmentParameteriv_Impl(target, attachment, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGenerateMipmap_Hook(GLenum target) { + if (glGenerateMipmap_Impl) + glGenerateMipmap_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glBlitFramebuffer_Hook( + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) { + if (glBlitFramebuffer_Impl) + glBlitFramebuffer_Impl(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glRenderbufferStorageMultisample_Hook( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) { + if (glRenderbufferStorageMultisample_Impl) + glRenderbufferStorageMultisample_Impl(target, samples, internalformat, width, height); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glFramebufferTextureLayer_Hook( + GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) { + if (glFramebufferTextureLayer_Impl) + glFramebufferTextureLayer_Impl(target, attachment, texture, level, layer); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_ARB_texture_multisample +void OVR::GLEContext::glTexImage2DMultisample_Hook( + GLenum target, + GLsizei samples, + GLint internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) { + if (glTexImage2DMultisample_Impl) + glTexImage2DMultisample_Impl( + target, samples, internalformat, width, height, fixedsamplelocations); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTexImage3DMultisample_Hook( + GLenum target, + GLsizei samples, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) { + if (glTexImage3DMultisample_Impl) + glTexImage3DMultisample_Impl( + target, samples, internalformat, width, height, depth, fixedsamplelocations); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetMultisamplefv_Hook(GLenum pname, GLuint index, GLfloat* val) { + if (glGetMultisamplefv_Impl) + glGetMultisamplefv_Impl(pname, index, val); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glSampleMaski_Hook(GLuint index, GLbitfield mask) { + if (glSampleMaski_Impl) + glSampleMaski_Impl(index, mask); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_ARB_texture_storage +void OVR::GLEContext::glTexStorage1D_Hook( + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width) { + if (glTexStorage1D_Impl) + glTexStorage1D_Impl(target, levels, internalformat, width); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTexStorage2D_Hook( + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height) { + if (glTexStorage2D_Impl) + glTexStorage2D_Impl(target, levels, internalformat, width, height); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTexStorage3D_Hook( + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) { + if (glTexStorage3D_Impl) + glTexStorage3D_Impl(target, levels, internalformat, width, height, depth); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTextureStorage1DEXT_Hook( + GLuint texture, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width) { + if (glTextureStorage1DEXT_Impl) + glTextureStorage1DEXT_Impl(texture, target, levels, internalformat, width); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTextureStorage2DEXT_Hook( + GLuint texture, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height) { + if (glTextureStorage2DEXT_Impl) + glTextureStorage2DEXT_Impl(texture, target, levels, internalformat, width, height); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTextureStorage3DEXT_Hook( + GLuint texture, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) { + if (glTextureStorage3DEXT_Impl) + glTextureStorage3DEXT_Impl(texture, target, levels, internalformat, width, height, depth); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_ARB_texture_storage_multisample +void OVR::GLEContext::glTexStorage2DMultisample_Hook( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) { + if (glTexStorage2DMultisample_Impl) + glTexStorage2DMultisample_Impl( + target, samples, internalformat, width, height, fixedsamplelocations); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTexStorage3DMultisample_Hook( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) { + if (glTexStorage3DMultisample_Impl) + glTexStorage3DMultisample_Impl( + target, samples, internalformat, width, height, depth, fixedsamplelocations); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTextureStorage2DMultisampleEXT_Hook( + GLuint texture, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) { + if (glTextureStorage2DMultisampleEXT_Impl) + glTextureStorage2DMultisampleEXT_Impl( + texture, target, samples, internalformat, width, height, fixedsamplelocations); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glTextureStorage3DMultisampleEXT_Hook( + GLuint texture, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) { + if (glTextureStorage3DMultisampleEXT_Impl) + glTextureStorage3DMultisampleEXT_Impl( + texture, target, samples, internalformat, width, height, depth, fixedsamplelocations); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_ARB_timer_query +void OVR::GLEContext::glQueryCounter_Hook(GLuint id, GLenum target) { + if (glQueryCounter_Impl) + glQueryCounter_Impl(id, target); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetQueryObjecti64v_Hook(GLuint id, GLenum pname, GLint64* params) { + if (glGetQueryObjecti64v_Impl) + glGetQueryObjecti64v_Impl(id, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetQueryObjectui64v_Hook(GLuint id, GLenum pname, GLuint64* params) { + if (glGetQueryObjectui64v_Impl) + glGetQueryObjectui64v_Impl(id, pname, params); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_ARB_vertex_array_object +void OVR::GLEContext::glBindVertexArray_Hook(GLuint array) { + if (glBindVertexArray_Impl) + glBindVertexArray_Impl(array); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDeleteVertexArrays_Hook(GLsizei n, const GLuint* arrays) { + if (glDeleteVertexArrays_Impl) + glDeleteVertexArrays_Impl(n, arrays); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGenVertexArrays_Hook(GLsizei n, GLuint* arrays) { + if (glGenVertexArrays_Impl) + glGenVertexArrays_Impl(n, arrays); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glIsVertexArray_Hook(GLuint array) { + GLboolean b = GL_FALSE; + if (glIsVertexArray_Impl) + b = glIsVertexArray_Impl(array); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +// GL_EXT_draw_buffers2 +void OVR::GLEContext::glColorMaskIndexedEXT_Hook( + GLuint index, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a) { + if (glColorMaskIndexedEXT_Impl) + glColorMaskIndexedEXT_Impl(index, r, g, b, a); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetBooleanIndexedvEXT_Hook(GLenum target, GLuint index, GLboolean* data) { + if (glGetBooleanIndexedvEXT_Impl) + glGetBooleanIndexedvEXT_Impl(target, index, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetIntegerIndexedvEXT_Hook(GLenum target, GLuint index, GLint* data) { + if (glGetIntegerIndexedvEXT_Impl) + glGetIntegerIndexedvEXT_Impl(target, index, data); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glEnableIndexedEXT_Hook(GLenum target, GLuint index) { + if (glEnableIndexedEXT_Impl) + glEnableIndexedEXT_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDisableIndexedEXT_Hook(GLenum target, GLuint index) { + if (glDisableIndexedEXT_Impl) + glDisableIndexedEXT_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLboolean OVR::GLEContext::glIsEnabledIndexedEXT_Hook(GLenum target, GLuint index) { + GLboolean b = GL_FALSE; + if (glIsEnabledIndexedEXT_Impl) + b = glIsEnabledIndexedEXT_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +// GL_KHR_debug +void OVR::GLEContext::glDebugMessageControl_Hook( + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint* ids, + GLboolean enabled) { + if (glDebugMessageControl_Impl) + glDebugMessageControl_Impl(source, type, severity, count, ids, enabled); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDebugMessageInsert_Hook( + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const char* buf) { + if (glDebugMessageInsert_Impl) + glDebugMessageInsert_Impl(source, type, id, severity, length, buf); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glDebugMessageCallback_Hook(GLDEBUGPROC callback, const void* userParam) { + if (glDebugMessageCallback_Impl) + glDebugMessageCallback_Impl(callback, userParam); + PostHook(GLE_CURRENT_FUNCTION); +} + +GLuint OVR::GLEContext::glGetDebugMessageLog_Hook( + GLuint count, + GLsizei bufSize, + GLenum* sources, + GLenum* types, + GLuint* ids, + GLenum* severities, + GLsizei* lengths, + char* messageLog) { + GLuint u = 0; + if (glGetDebugMessageLog_Impl) + u = glGetDebugMessageLog_Impl( + count, bufSize, sources, types, ids, severities, lengths, messageLog); + PostHook(GLE_CURRENT_FUNCTION); + return u; +} + +void OVR::GLEContext::glPushDebugGroup_Hook( + GLenum source, + GLuint id, + GLsizei length, + const char* message) { + if (glPushDebugGroup_Impl) + glPushDebugGroup_Impl(source, id, length, message); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glPopDebugGroup_Hook() { + if (glPopDebugGroup_Impl) + glPopDebugGroup_Impl(); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glObjectLabel_Hook( + GLenum identifier, + GLuint name, + GLsizei length, + const char* label) { + if (glObjectLabel_Impl) + glObjectLabel_Impl(identifier, name, length, label); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetObjectLabel_Hook( + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei* length, + char* label) { + if (glGetObjectLabel_Impl) + glGetObjectLabel_Impl(identifier, name, bufSize, length, label); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glObjectPtrLabel_Hook(void* ptr, GLsizei length, const char* label) { + if (glObjectPtrLabel_Impl) + glObjectPtrLabel_Impl(ptr, length, label); + PostHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glGetObjectPtrLabel_Hook( + void* ptr, + GLsizei bufSize, + GLsizei* length, + char* label) { + if (glGetObjectPtrLabel_Impl) + glGetObjectPtrLabel_Impl(ptr, bufSize, length, label); + PostHook(GLE_CURRENT_FUNCTION); +} + +// GL_WIN_swap_hint +void OVR::GLEContext::glAddSwapHintRectWIN_Hook(GLint x, GLint y, GLsizei width, GLsizei height) { + if (glAddSwapHintRectWIN_Impl) + glAddSwapHintRectWIN_Impl(x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); +} + +#if defined(GLE_WGL_ENABLED) +// WGL +void OVR::GLEContext::PostWGLHook(const char* /*function*/) { + // Empty for now. WGL functions don't have a function like glGetError(). +} + +/* We currently don't hook these +#undef wglCopyContext +extern "C" { GLAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask); } +BOOL OVR::GLEContext::wglCopyContext_Hook(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) +{ + BOOL b = wglCopyContext(hglrcSrc, hglrcDst, mask); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglCreateContext +extern "C" { GLAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc); } +HGLRC OVR::GLEContext::wglCreateContext_Hook(HDC hdc) +{ + HGLRC h = wglCreateContext(hdc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +#undef wglCreateLayerContext +extern "C" { GLAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc, int iLayerPlane); } +HGLRC OVR::GLEContext::wglCreateLayerContext_Hook(HDC hdc, int iLayerPlane) +{ + HGLRC h = wglCreateLayerContext(hdc, iLayerPlane); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +#undef wglDeleteContext +extern "C" { GLAPI BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc); } +BOOL OVR::GLEContext::wglDeleteContext_Hook(HGLRC hglrc) +{ + BOOL b = wglDeleteContext(hglrc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglGetCurrentContext +extern "C" { GLAPI HGLRC GLAPIENTRY wglGetCurrentContext(); } +HGLRC OVR::GLEContext::wglGetCurrentContext_Hook() +{ + HGLRC h = wglGetCurrentContext(); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +#undef wglGetCurrentDC +extern "C" { GLAPI HDC GLAPIENTRY wglGetCurrentDC(); } +HDC OVR::GLEContext::wglGetCurrentDC_Hook() +{ + HDC h = wglGetCurrentDC(); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +//#undef wglGetProcAddress Not needed because we happen to do it above already. +//extern "C" { GLAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc); } +PROC OVR::GLEContext::wglGetProcAddress_Hook(LPCSTR lpszProc) +{ + PROC p = wglGetProcAddress(lpszProc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return p; +} + +#undef wglMakeCurrent +extern "C" { GLAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc, HGLRC hglrc); } +BOOL OVR::GLEContext::wglMakeCurrent_Hook(HDC hdc, HGLRC hglrc) +{ + BOOL b = wglMakeCurrent(hdc, hglrc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglShareLists +extern "C" { GLAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1, HGLRC hglrc2); } +BOOL OVR::GLEContext::wglShareLists_Hook(HGLRC hglrc1, HGLRC hglrc2) +{ + BOOL b = wglShareLists(hglrc1, hglrc2); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglUseFontBitmapsA +extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first, DWORD count, DWORD +listBase); } BOOL OVR::GLEContext::wglUseFontBitmapsA_Hook(HDC hdc, DWORD first, DWORD count, DWORD +listBase) +{ + BOOL b = wglUseFontBitmapsA(hdc, first, count, listBase); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglUseFontBitmapsW +extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc, DWORD first, DWORD count, DWORD +listBase); } BOOL OVR::GLEContext::wglUseFontBitmapsW_Hook(HDC hdc, DWORD first, DWORD count, DWORD +listBase) +{ + BOOL b = wglUseFontBitmapsW(hdc, first, count, listBase); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglUseFontOutlinesA +extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc, DWORD first, DWORD count, DWORD +listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf); } BOOL +OVR::GLEContext::wglUseFontOutlinesA_Hook(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT +deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) +{ + BOOL b = wglUseFontOutlinesA(hdc, first, count, listBase, deviation, extrusion, format, lpgmf); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglUseFontOutlinesW +extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc, DWORD first, DWORD count, DWORD +listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf); } BOOL +OVR::GLEContext::wglUseFontOutlinesW_Hook(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT +deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) +{ + BOOL b = wglUseFontOutlinesW(hdc, first, count, listBase, deviation, extrusion, format, lpgmf); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglDescribeLayerPlane +extern "C" { GLAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc, int iPixelFormat, int iLayerPlane, +UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd); } BOOL OVR::GLEContext::wglDescribeLayerPlane_Hook(HDC +hdc, int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd) +{ + BOOL b = wglDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglSetLayerPaletteEntries +extern "C" { GLAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc, int iLayerPlane, int iStart, +int cEntries, const COLORREF *pcr); } int OVR::GLEContext::wglSetLayerPaletteEntries_Hook(HDC hdc, +int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr) +{ + int i = wglSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; +} + +#undef wglGetLayerPaletteEntries +extern "C" { GLAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc, int iLayerPlane, int iStart, +int cEntries, COLORREF *pcr); } int OVR::GLEContext::wglGetLayerPaletteEntries_Hook(HDC hdc, int +iLayerPlane, int iStart, int cEntries, COLORREF *pcr) +{ + int i = wglGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; +} + +#undef wglRealizeLayerPalette +extern "C" { GLAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc, int iLayerPlane, BOOL bRealize); +} BOOL OVR::GLEContext::wglRealizeLayerPalette_Hook(HDC hdc, int iLayerPlane, BOOL bRealize) +{ + BOOL b = wglRealizeLayerPalette(hdc, iLayerPlane, bRealize); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglSwapLayerBuffers +extern "C" { GLAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc, UINT fuPlanes); } +BOOL OVR::GLEContext::wglSwapLayerBuffers_Hook(HDC hdc, UINT fuPlanes) +{ + BOOL b = wglSwapLayerBuffers(hdc, fuPlanes); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#undef wglSwapMultipleBuffers +extern "C" { GLAPI DWORD GLAPIENTRY wglSwapMultipleBuffers(UINT i, CONST WGLSWAP* p); } +DWORD OVR::GLEContext::wglSwapMultipleBuffers_Hook(UINT i, CONST WGLSWAP* p) +{ + DWORD dw = wglSwapMultipleBuffers(i, p); + PostWGLHook(GLE_CURRENT_FUNCTION); + return dw; +} +*/ + +// The rest of the functions are pointer-based. + +// WGL_ARB_buffer_region +HANDLE OVR::GLEContext::wglCreateBufferRegionARB_Hook(HDC hDC, int iLayerPlane, UINT uType) { + HANDLE h = NULL; + if (wglCreateBufferRegionARB_Impl) + h = wglCreateBufferRegionARB_Impl(hDC, iLayerPlane, uType); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +VOID OVR::GLEContext::wglDeleteBufferRegionARB_Hook(HANDLE hRegion) { + if (wglDeleteBufferRegionARB_Impl) + wglDeleteBufferRegionARB_Impl(hRegion); + PostWGLHook(GLE_CURRENT_FUNCTION); +} + +BOOL OVR::GLEContext::wglSaveBufferRegionARB_Hook( + HANDLE hRegion, + int x, + int y, + int width, + int height) { + BOOL b = FALSE; + if (wglSaveBufferRegionARB_Impl) + b = wglSaveBufferRegionARB_Impl(hRegion, x, y, width, height); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglRestoreBufferRegionARB_Hook( + HANDLE hRegion, + int x, + int y, + int width, + int height, + int xSrc, + int ySrc) { + BOOL b = FALSE; + if (wglRestoreBufferRegionARB_Impl) + b = wglRestoreBufferRegionARB_Impl(hRegion, x, y, width, height, xSrc, ySrc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +// WGL_ARB_extensions_string +const char* OVR::GLEContext::wglGetExtensionsStringARB_Hook(HDC hdc) { + const char* p = NULL; + if (wglGetExtensionsStringARB_Impl) + p = wglGetExtensionsStringARB_Impl(hdc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return p; +} + +// WGL_ARB_pixel_format +BOOL OVR::GLEContext::wglGetPixelFormatAttribivARB_Hook( + HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int* piAttributes, + int* piValues) { + BOOL b = FALSE; + if (wglGetPixelFormatAttribivARB_Impl) + b = wglGetPixelFormatAttribivARB_Impl( + hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglGetPixelFormatAttribfvARB_Hook( + HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int* piAttributes, + FLOAT* pfValues) { + BOOL b = FALSE; + if (wglGetPixelFormatAttribfvARB_Impl) + b = wglGetPixelFormatAttribfvARB_Impl( + hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglChoosePixelFormatARB_Hook( + HDC hdc, + const int* piAttribIList, + const FLOAT* pfAttribFList, + UINT nMaxFormats, + int* piFormats, + UINT* nNumFormats) { + BOOL b = FALSE; + if (wglChoosePixelFormatARB_Impl) + b = wglChoosePixelFormatARB_Impl( + hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +// WGL_ARB_make_current_read +BOOL OVR::GLEContext::wglMakeContextCurrentARB_Hook(HDC hDrawDC, HDC hReadDC, HGLRC hglrc) { + BOOL b = FALSE; + if (wglMakeContextCurrentARB_Impl) + b = wglMakeContextCurrentARB_Impl(hDrawDC, hReadDC, hglrc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +HDC OVR::GLEContext::wglGetCurrentReadDCARB_Hook() { + HDC h = NULL; + if (wglGetCurrentReadDCARB_Impl) + h = wglGetCurrentReadDCARB_Impl(); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +// WGL_ARB_pbuffer +HPBUFFERARB OVR::GLEContext::wglCreatePbufferARB_Hook( + HDC hDC, + int iPixelFormat, + int iWidth, + int iHeight, + const int* piAttribList) { + HPBUFFERARB h = NULL; + if (wglCreatePbufferARB_Impl) + h = wglCreatePbufferARB_Impl(hDC, iPixelFormat, iWidth, iHeight, piAttribList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +HDC OVR::GLEContext::wglGetPbufferDCARB_Hook(HPBUFFERARB hPbuffer) { + HDC h = NULL; + if (wglGetPbufferDCARB_Impl) + h = wglGetPbufferDCARB_Impl(hPbuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +int OVR::GLEContext::wglReleasePbufferDCARB_Hook(HPBUFFERARB hPbuffer, HDC hDC) { + int i = 0; + if (wglReleasePbufferDCARB_Impl) + i = wglReleasePbufferDCARB_Impl(hPbuffer, hDC); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; +} + +BOOL OVR::GLEContext::wglDestroyPbufferARB_Hook(HPBUFFERARB hPbuffer) { + BOOL b = FALSE; + if (wglDestroyPbufferARB_Impl) + b = wglDestroyPbufferARB_Impl(hPbuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglQueryPbufferARB_Hook(HPBUFFERARB hPbuffer, int iAttribute, int* piValue) { + BOOL b = FALSE; + if (wglQueryPbufferARB_Impl) + b = wglQueryPbufferARB_Impl(hPbuffer, iAttribute, piValue); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +// WGL_ARB_render_texture +BOOL OVR::GLEContext::wglBindTexImageARB_Hook(HPBUFFERARB hPbuffer, int iBuffer) { + BOOL b = FALSE; + if (wglBindTexImageARB_Impl) + b = wglBindTexImageARB_Impl(hPbuffer, iBuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglReleaseTexImageARB_Hook(HPBUFFERARB hPbuffer, int iBuffer) { + BOOL b = FALSE; + if (wglReleaseTexImageARB_Impl) + b = wglReleaseTexImageARB_Impl(hPbuffer, iBuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglSetPbufferAttribARB_Hook(HPBUFFERARB hPbuffer, const int* piAttribList) { + BOOL b = FALSE; + if (wglSetPbufferAttribARB_Impl) + b = wglSetPbufferAttribARB_Impl(hPbuffer, piAttribList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +// WGL_NV_present_video +int OVR::GLEContext::wglEnumerateVideoDevicesNV_Hook(HDC hDC, HVIDEOOUTPUTDEVICENV* phDeviceList) { + int i = 0; + if (wglEnumerateVideoDevicesNV_Impl) + i = wglEnumerateVideoDevicesNV_Impl(hDC, phDeviceList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; +} + +BOOL OVR::GLEContext::wglBindVideoDeviceNV_Hook( + HDC hDC, + unsigned int uVideoSlot, + HVIDEOOUTPUTDEVICENV hVideoDevice, + const int* piAttribList) { + BOOL b = FALSE; + if (wglBindVideoDeviceNV_Impl) + b = wglBindVideoDeviceNV_Impl(hDC, uVideoSlot, hVideoDevice, piAttribList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglQueryCurrentContextNV_Hook(int iAttribute, int* piValue) { + BOOL b = FALSE; + if (wglQueryCurrentContextNV_Impl) + b = wglQueryCurrentContextNV_Impl(iAttribute, piValue); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +// WGL_ARB_create_context +HGLRC OVR::GLEContext::wglCreateContextAttribsARB_Hook( + HDC hDC, + HGLRC hShareContext, + const int* attribList) { + HGLRC h = NULL; + if (wglCreateContextAttribsARB_Impl) + h = wglCreateContextAttribsARB_Impl(hDC, hShareContext, attribList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +// WGL_EXT_extensions_string +const char* OVR::GLEContext::wglGetExtensionsStringEXT_Hook() { + const char* p = NULL; + if (wglGetExtensionsStringEXT_Impl) + p = wglGetExtensionsStringEXT_Impl(); + PostWGLHook(GLE_CURRENT_FUNCTION); + return p; +} + +// WGL_EXT_swap_control +BOOL OVR::GLEContext::wglSwapIntervalEXT_Hook(int interval) { + BOOL b = FALSE; + if (wglSwapIntervalEXT_Impl) + b = wglSwapIntervalEXT_Impl(interval); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +int OVR::GLEContext::wglGetSwapIntervalEXT_Hook() { + int i = 0; + if (wglGetSwapIntervalEXT_Impl) + i = wglGetSwapIntervalEXT_Impl(); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; +} + +// WGL_OML_sync_control +BOOL OVR::GLEContext::wglGetSyncValuesOML_Hook(HDC hdc, INT64* ust, INT64* msc, INT64* sbc) { + BOOL b = FALSE; + if (wglGetSyncValuesOML_Impl) + b = wglGetSyncValuesOML_Impl(hdc, ust, msc, sbc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglGetMscRateOML_Hook(HDC hdc, INT32* numerator, INT32* denominator) { + BOOL b = FALSE; + if (wglGetMscRateOML_Impl) + b = wglGetMscRateOML_Impl(hdc, numerator, denominator); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +INT64 OVR::GLEContext::wglSwapBuffersMscOML_Hook( + HDC hdc, + INT64 target_msc, + INT64 divisor, + INT64 remainder) { + INT64 i = 0; + if (wglSwapBuffersMscOML_Impl) + i = wglSwapBuffersMscOML_Impl(hdc, target_msc, divisor, remainder); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; +} + +INT64 OVR::GLEContext::wglSwapLayerBuffersMscOML_Hook( + HDC hdc, + int fuPlanes, + INT64 target_msc, + INT64 divisor, + INT64 remainder) { + INT64 i = 0; + if (wglSwapLayerBuffersMscOML_Impl) + i = wglSwapLayerBuffersMscOML_Impl(hdc, fuPlanes, target_msc, divisor, remainder); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; +} + +BOOL OVR::GLEContext::wglWaitForMscOML_Hook( + HDC hdc, + INT64 target_msc, + INT64 divisor, + INT64 remainder, + INT64* ust, + INT64* msc, + INT64* sbc) { + BOOL b = FALSE; + if (wglWaitForMscOML_Impl) + b = wglWaitForMscOML_Impl(hdc, target_msc, divisor, remainder, ust, msc, sbc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglWaitForSbcOML_Hook( + HDC hdc, + INT64 target_sbc, + INT64* ust, + INT64* msc, + INT64* sbc) { + BOOL b = FALSE; + if (wglWaitForSbcOML_Impl) + b = wglWaitForSbcOML_Impl(hdc, target_sbc, ust, msc, sbc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +// WGL_NV_video_output +BOOL OVR::GLEContext::wglGetVideoDeviceNV_Hook(HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice) { + BOOL b = FALSE; + if (wglGetVideoDeviceNV_Impl) + b = wglGetVideoDeviceNV_Impl(hDC, numDevices, hVideoDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglReleaseVideoDeviceNV_Hook(HPVIDEODEV hVideoDevice) { + BOOL b = FALSE; + if (wglReleaseVideoDeviceNV_Impl) + b = wglReleaseVideoDeviceNV_Impl(hVideoDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglBindVideoImageNV_Hook( + HPVIDEODEV hVideoDevice, + HPBUFFERARB hPbuffer, + int iVideoBuffer) { + BOOL b = FALSE; + if (wglBindVideoImageNV_Impl) + b = wglBindVideoImageNV_Impl(hVideoDevice, hPbuffer, iVideoBuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglReleaseVideoImageNV_Hook(HPBUFFERARB hPbuffer, int iVideoBuffer) { + BOOL b = FALSE; + if (wglReleaseVideoImageNV_Impl) + b = wglReleaseVideoImageNV_Impl(hPbuffer, iVideoBuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglSendPbufferToVideoNV_Hook( + HPBUFFERARB hPbuffer, + int iBufferType, + unsigned long* pulCounterPbuffer, + BOOL bBlock) { + BOOL b = FALSE; + if (wglSendPbufferToVideoNV_Impl) + b = wglSendPbufferToVideoNV_Impl(hPbuffer, iBufferType, pulCounterPbuffer, bBlock); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglGetVideoInfoNV_Hook( + HPVIDEODEV hpVideoDevice, + unsigned long* pulCounterOutputPbuffer, + unsigned long* pulCounterOutputVideo) { + BOOL b = FALSE; + if (wglGetVideoInfoNV_Impl) + b = wglGetVideoInfoNV_Impl(hpVideoDevice, pulCounterOutputPbuffer, pulCounterOutputVideo); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +// WGL_NV_swap_group +BOOL OVR::GLEContext::wglJoinSwapGroupNV_Hook(HDC hDC, GLuint group) { + BOOL b = FALSE; + if (wglJoinSwapGroupNV_Impl) + b = wglJoinSwapGroupNV_Impl(hDC, group); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglBindSwapBarrierNV_Hook(GLuint group, GLuint barrier) { + BOOL b = FALSE; + if (wglBindSwapBarrierNV_Impl) + b = wglBindSwapBarrierNV_Impl(group, barrier); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglQuerySwapGroupNV_Hook(HDC hDC, GLuint* group, GLuint* barrier) { + BOOL b = FALSE; + if (wglQuerySwapGroupNV_Impl) + b = wglQuerySwapGroupNV_Impl(hDC, group, barrier); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglQueryMaxSwapGroupsNV_Hook( + HDC hDC, + GLuint* maxGroups, + GLuint* maxBarriers) { + BOOL b = FALSE; + if (wglQueryMaxSwapGroupsNV_Impl) + b = wglQueryMaxSwapGroupsNV_Impl(hDC, maxGroups, maxBarriers); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglQueryFrameCountNV_Hook(HDC hDC, GLuint* count) { + BOOL b = FALSE; + if (wglQueryFrameCountNV_Impl) + b = wglQueryFrameCountNV_Impl(hDC, count); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglResetFrameCountNV_Hook(HDC hDC) { + BOOL b = FALSE; + if (wglResetFrameCountNV_Impl) + b = wglResetFrameCountNV_Impl(hDC); + PostHook(GLE_CURRENT_FUNCTION); + return b; +} + +// WGL_NV_video_capture +BOOL OVR::GLEContext::wglBindVideoCaptureDeviceNV_Hook( + UINT uVideoSlot, + HVIDEOINPUTDEVICENV hDevice) { + BOOL b = FALSE; + if (wglBindVideoCaptureDeviceNV_Impl) + b = wglBindVideoCaptureDeviceNV_Impl(uVideoSlot, hDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +UINT OVR::GLEContext::wglEnumerateVideoCaptureDevicesNV_Hook( + HDC hDc, + HVIDEOINPUTDEVICENV* phDeviceList) { + UINT u = 0; + if (wglEnumerateVideoCaptureDevicesNV_Impl) + u = wglEnumerateVideoCaptureDevicesNV_Impl(hDc, phDeviceList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return u; +} + +BOOL OVR::GLEContext::wglLockVideoCaptureDeviceNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV hDevice) { + BOOL b = FALSE; + if (wglLockVideoCaptureDeviceNV_Impl) + b = wglLockVideoCaptureDeviceNV_Impl(hDc, hDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglQueryVideoCaptureDeviceNV_Hook( + HDC hDc, + HVIDEOINPUTDEVICENV hDevice, + int iAttribute, + int* piValue) { + BOOL b = FALSE; + if (wglQueryVideoCaptureDeviceNV_Impl) + b = wglQueryVideoCaptureDeviceNV_Impl(hDc, hDevice, iAttribute, piValue); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglReleaseVideoCaptureDeviceNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV hDevice) { + BOOL b = FALSE; + if (wglReleaseVideoCaptureDeviceNV_Impl) + b = wglReleaseVideoCaptureDeviceNV_Impl(hDc, hDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +// WGL_NV_copy_image +BOOL OVR::GLEContext::wglCopyImageSubDataNV_Hook( + HGLRC hSrcRC, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + HGLRC hDstRC, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei width, + GLsizei height, + GLsizei depth) { + BOOL b = FALSE; + if (wglCopyImageSubDataNV_Impl) + b = wglCopyImageSubDataNV_Impl( + hSrcRC, + srcName, + srcTarget, + srcLevel, + srcX, + srcY, + srcZ, + hDstRC, + dstName, + dstTarget, + dstLevel, + dstX, + dstY, + dstZ, + width, + height, + depth); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +// WGL_NV_DX_interop +BOOL OVR::GLEContext::wglDXSetResourceShareHandleNV_Hook(void* dxObject, HANDLE shareHandle) { + BOOL b = FALSE; + if (wglDXSetResourceShareHandleNV_Impl) + b = wglDXSetResourceShareHandleNV_Impl(dxObject, shareHandle); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +HANDLE OVR::GLEContext::wglDXOpenDeviceNV_Hook(void* dxDevice) { + HANDLE h = NULL; + if (wglDXOpenDeviceNV_Impl) + h = wglDXOpenDeviceNV_Impl(dxDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +BOOL OVR::GLEContext::wglDXCloseDeviceNV_Hook(HANDLE hDevice) { + BOOL b = FALSE; + if (wglDXCloseDeviceNV_Impl) + b = wglDXCloseDeviceNV_Impl(hDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +HANDLE OVR::GLEContext::wglDXRegisterObjectNV_Hook( + HANDLE hDevice, + void* dxObject, + GLuint name, + GLenum type, + GLenum access) { + HANDLE h = NULL; + if (wglDXRegisterObjectNV_Impl) + h = wglDXRegisterObjectNV_Impl(hDevice, dxObject, name, type, access); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; +} + +BOOL OVR::GLEContext::wglDXUnregisterObjectNV_Hook(HANDLE hDevice, HANDLE hObject) { + BOOL b = FALSE; + if (wglDXUnregisterObjectNV_Impl) + b = wglDXUnregisterObjectNV_Impl(hDevice, hObject); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglDXObjectAccessNV_Hook(HANDLE hObject, GLenum access) { + BOOL b = FALSE; + if (wglDXObjectAccessNV_Impl) + b = wglDXObjectAccessNV_Impl(hObject, access); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglDXLockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE* hObjects) { + BOOL b = FALSE; + if (wglDXLockObjectsNV_Impl) + b = wglDXLockObjectsNV_Impl(hDevice, count, hObjects); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +BOOL OVR::GLEContext::wglDXUnlockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE* hObjects) { + BOOL b = FALSE; + if (wglDXUnlockObjectsNV_Impl) + b = wglDXUnlockObjectsNV_Impl(hDevice, count, hObjects); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; +} + +#endif // defined(GLE_WGL_ENABLED) + +#if defined(GLE_GLX_ENABLED) +void OVR::GLEContext::PostGLXHook(const char* /*function*/) { + // Empty for now. GLX functions don't have a function like glGetError(). +} + +// GLX_VERSION_1_0 +// GLX_VERSION_1_1 +// We don't currently implement hooking of these. + +// GLX_VERSION_1_2 +::Display* OVR::GLEContext::glXGetCurrentDisplay_Hook(void) { + ::Display* p = NULL; + if (glXGetCurrentDisplay_Impl) + p = glXGetCurrentDisplay_Impl(); + PostGLXHook(GLE_CURRENT_FUNCTION); + return p; +} + +// GLX_VERSION_1_3 +GLXFBConfig* OVR::GLEContext::glXChooseFBConfig_Hook( + Display* dpy, + int screen, + const int* attrib_list, + int* nelements) { + GLXFBConfig* p = NULL; + if (glXChooseFBConfig_Impl) + p = glXChooseFBConfig_Impl(dpy, screen, attrib_list, nelements); + PostGLXHook(GLE_CURRENT_FUNCTION); + return p; +} + +GLXContext OVR::GLEContext::glXCreateNewContext_Hook( + Display* dpy, + GLXFBConfig config, + int render_type, + GLXContext share_list, + Bool direct) { + GLXContext c = 0; + if (glXCreateNewContext_Impl) + c = glXCreateNewContext_Impl(dpy, config, render_type, share_list, direct); + PostGLXHook(GLE_CURRENT_FUNCTION); + return c; +} + +GLXPbuffer +OVR::GLEContext::glXCreatePbuffer_Hook(Display* dpy, GLXFBConfig config, const int* attrib_list) { + GLXPbuffer b = 0; + if (glXCreatePbuffer_Impl) + b = glXCreatePbuffer_Impl(dpy, config, attrib_list); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; +} + +GLXPixmap OVR::GLEContext::glXCreatePixmap_Hook( + Display* dpy, + GLXFBConfig config, + Pixmap pixmap, + const int* attrib_list) { + GLXPixmap m = 0; + if (glXCreatePixmap_Impl) + m = glXCreatePixmap_Impl(dpy, config, pixmap, attrib_list); + PostGLXHook(GLE_CURRENT_FUNCTION); + return m; +} + +GLXWindow OVR::GLEContext::glXCreateWindow_Hook( + Display* dpy, + GLXFBConfig config, + Window win, + const int* attrib_list) { + GLXWindow w = 0; + if (glXCreateWindow_Impl) + w = glXCreateWindow_Impl(dpy, config, win, attrib_list); + PostGLXHook(GLE_CURRENT_FUNCTION); + return w; +} + +void OVR::GLEContext::glXDestroyPbuffer_Hook(Display* dpy, GLXPbuffer pbuf) { + if (glXDestroyPbuffer_Impl) + glXDestroyPbuffer_Impl(dpy, pbuf); + PostGLXHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glXDestroyPixmap_Hook(Display* dpy, GLXPixmap pixmap) { + if (glXDestroyPixmap_Impl) + glXDestroyPixmap_Impl(dpy, pixmap); + PostGLXHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glXDestroyWindow_Hook(Display* dpy, GLXWindow win) { + if (glXDestroyWindow_Impl) + glXDestroyWindow_Impl(dpy, win); + PostGLXHook(GLE_CURRENT_FUNCTION); +} + +GLXDrawable OVR::GLEContext::glXGetCurrentReadDrawable_Hook(void) { + GLXDrawable d; + if (glXGetCurrentReadDrawable_Impl) + d = glXGetCurrentReadDrawable_Impl(); + PostGLXHook(GLE_CURRENT_FUNCTION); + return d; +} + +int OVR::GLEContext::glXGetFBConfigAttrib_Hook( + Display* dpy, + GLXFBConfig config, + int attribute, + int* value) { + int i = -1; + if (glXGetFBConfigAttrib_Impl) + i = glXGetFBConfigAttrib_Impl(dpy, config, attribute, value); + PostGLXHook(GLE_CURRENT_FUNCTION); + return i; +} + +GLXFBConfig* OVR::GLEContext::glXGetFBConfigs_Hook(Display* dpy, int screen, int* nelements) { + GLXFBConfig* p = NULL; + if (glXGetFBConfigs_Impl) + p = glXGetFBConfigs_Impl(dpy, screen, nelements); + PostGLXHook(GLE_CURRENT_FUNCTION); + return p; +} + +void OVR::GLEContext::glXGetSelectedEvent_Hook( + Display* dpy, + GLXDrawable draw, + unsigned long* event_mask) { + if (glXGetSelectedEvent_Impl) + glXGetSelectedEvent_Impl(dpy, draw, event_mask); + PostGLXHook(GLE_CURRENT_FUNCTION); +} + +XVisualInfo* OVR::GLEContext::glXGetVisualFromFBConfig_Hook(Display* dpy, GLXFBConfig config) { + XVisualInfo* p = NULL; + if (glXGetVisualFromFBConfig_Impl) + p = glXGetVisualFromFBConfig_Impl(dpy, config); + PostGLXHook(GLE_CURRENT_FUNCTION); + return p; +} + +Bool OVR::GLEContext::glXMakeContextCurrent_Hook( + Display* dpy, + GLXDrawable draw, + GLXDrawable read, + GLXContext ctx) { + Bool b = False; + if (glXMakeContextCurrent_Impl) + b = glXMakeContextCurrent_Impl(dpy, draw, read, ctx); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; +} + +int OVR::GLEContext::glXQueryContext_Hook(Display* dpy, GLXContext ctx, int attribute, int* value) { + int i = GLX_BAD_ATTRIBUTE; + if (glXQueryContext_Impl) + i = glXQueryContext_Impl(dpy, ctx, attribute, value); + PostGLXHook(GLE_CURRENT_FUNCTION); + return i; +} + +void OVR::GLEContext::glXQueryDrawable_Hook( + Display* dpy, + GLXDrawable draw, + int attribute, + unsigned int* value) { + if (glXQueryDrawable_Impl) + glXQueryDrawable_Impl(dpy, draw, attribute, value); + PostGLXHook(GLE_CURRENT_FUNCTION); +} + +void OVR::GLEContext::glXSelectEvent_Hook( + Display* dpy, + GLXDrawable draw, + unsigned long event_mask) { + if (glXSelectEvent_Impl) + glXSelectEvent_Impl(dpy, draw, event_mask); + PostGLXHook(GLE_CURRENT_FUNCTION); +} + +// GLX_VERSION_1_4 +// We don't do hooking of this. + +// GLX_ARB_create_context +GLXContext OVR::GLEContext::glXCreateContextAttribsARB_Hook( + Display* dpy, + GLXFBConfig config, + GLXContext share_context, + Bool direct, + const int* attrib_list) { + GLXContext c = 0; + if (glXCreateContextAttribsARB_Impl) + c = glXCreateContextAttribsARB_Impl(dpy, config, share_context, direct, attrib_list); + PostGLXHook(GLE_CURRENT_FUNCTION); + return c; +} + +// GLX_EXT_swap_control +void OVR::GLEContext::glXSwapIntervalEXT_Hook(Display* dpy, GLXDrawable drawable, int interval) { + if (glXSwapIntervalEXT_Impl) + glXSwapIntervalEXT_Impl(dpy, drawable, interval); + PostGLXHook(GLE_CURRENT_FUNCTION); +} + +// GLX_OML_sync_control +Bool OVR::GLEContext::glXGetMscRateOML_Hook( + Display* dpy, + GLXDrawable drawable, + int32_t* numerator, + int32_t* denominator) { + Bool b = False; + if (glXGetMscRateOML_Impl) + b = glXGetMscRateOML_Impl(dpy, drawable, numerator, denominator); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; +} + +Bool OVR::GLEContext::glXGetSyncValuesOML_Hook( + Display* dpy, + GLXDrawable drawable, + int64_t* ust, + int64_t* msc, + int64_t* sbc) { + Bool b = False; + if (glXGetSyncValuesOML_Impl) + b = glXGetSyncValuesOML_Impl(dpy, drawable, ust, msc, sbc); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; +} + +int64_t OVR::GLEContext::glXSwapBuffersMscOML_Hook( + Display* dpy, + GLXDrawable drawable, + int64_t target_msc, + int64_t divisor, + int64_t remainder) { + int64_t i = 0; + if (glXSwapBuffersMscOML_Impl) + i = glXSwapBuffersMscOML_Impl(dpy, drawable, target_msc, divisor, remainder); + PostGLXHook(GLE_CURRENT_FUNCTION); + return i; +} + +Bool OVR::GLEContext::glXWaitForMscOML_Hook( + Display* dpy, + GLXDrawable drawable, + int64_t target_msc, + int64_t divisor, + int64_t remainder, + int64_t* ust, + int64_t* msc, + int64_t* sbc) { + Bool b = False; + if (glXWaitForMscOML_Impl) + b = glXWaitForMscOML_Impl(dpy, drawable, target_msc, divisor, remainder, ust, msc, sbc); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; +} + +Bool OVR::GLEContext::glXWaitForSbcOML_Hook( + Display* dpy, + GLXDrawable drawable, + int64_t target_sbc, + int64_t* ust, + int64_t* msc, + int64_t* sbc) { + Bool b = False; + if (glXWaitForSbcOML_Impl) + b = glXWaitForSbcOML_Impl(dpy, drawable, target_sbc, ust, msc, sbc); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; +} + +// GLX_MESA_swap_control +int OVR::GLEContext::glXGetSwapIntervalMESA_Hook() { + int i = 0; + if (glXGetSwapIntervalMESA_Impl) + i = glXGetSwapIntervalMESA_Impl(); + PostGLXHook(GLE_CURRENT_FUNCTION); + return i; +} + +int OVR::GLEContext::glXSwapIntervalMESA_Hook(unsigned int interval) { + int i = 0; + if (glXSwapIntervalMESA_Impl) + i = glXSwapIntervalMESA_Impl(interval); + PostGLXHook(GLE_CURRENT_FUNCTION); + return i; +} + +#endif // defined(GLE_GLX_ENABLED) + +#endif // GLE_HOOKING_ENABLED + +//} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE.h new file mode 100644 index 0000000..1e6509b --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE.h @@ -0,0 +1,2733 @@ +/************************************************************************************ + +Filename : CAPI_GLE.h +Content : OpenGL extensions support. Implements a stripped down glew-like + interface with some additional functionality. +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +// This file provides functionality similar to a reduced version of GLEW, plus some +// additional functionality that's useful to us, such as function hooking. + +#ifndef OVR_CAPI_GLE_h +#define OVR_CAPI_GLE_h + +#include "CAPI_GLE_GL.h" +#include "Kernel/OVR_Types.h" + +/////////////////////////////////////////////////////////////////////////////// +// How to use this functionality +// +// - You #include this header instead of gl.h, glext.h, wglext.h (Windows), gl3.h (Apple), gl3ext.h +// (Apple), glx.h (Unix), and glxext.h (Unix). +// Currently you still would #include for the base wgl functions on Windows and +// OpenGL.h or NSOpenGL for the base Apple cgl functions. +// +// - You call OpenGL functions just like you would if you were directly using OpenGL +// headers and declarations. The difference is that this module automatically loads +// extensions on init and so you should never need to use GetProcAddress, wglGetProcAddress, etc. +// +// - OpenGL 1.1 functions can be called unilaterally without checking if they are present, +// as it's assumed they are always present. +// +// - In order to use an OpenGL 1.2 or later function you can check the GLEContext::WholeVersion +// variable to tell what version of OpenGL is present and active. Example usage: +// if(GLEContext::GetCurrentContext()->WholeVersion >= 302) // If OpenGL 3.2 or later... +// +// - In order to use an OpenGL extension, you can check the GLE_ helper macro that exists for each +// extension. For example, in order to check of the KHR_debug is present you could do this: +// if(GLE_KHR_debug) ... +// You cannot check for the presence of extensions by testing the function pointer, because +// when hooking is enabled then we aren't using function pointers and thus all functions will +// look like they are present. +// +// - You can test if the OpenGL implementation is OpenGL ES by checking the GLEContext IsGLES +// member variable. For example: if(GLEContext::GetCurrentContext()->IsGLES) ... +// +// - You can test if the OpenGL implementation is a core profile ES by checking the GLEContext +// IsCoreProfile +// member variable. For example: if(GLEContext::GetCurrentContext()->IsCoreProfile) ... +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// How to add support for additional functions to this module. +// +// For an example of how to do this, search the source files for all cases of KHR_Debug and just +// copy the things that it does but for your new extension. +// +// 1) Add the appropriate extension declaration to CAPI_GLE_GL.h, preferably by +// copying it from the standard header file it normally comes from. If it's +// platform-specific (e.g. a Windows wgl function) then make sure it's declared +// within the given platform section. Note that there are potentially #defines, typedefs, +// function typedefs, and function #defines. There is always a GLE_ macro declared which +// lets the user know at runtime whether the extension is present. +// Note that entries are alphabetically sorted in these files. +// e.g. #ifndef GL_KHR_debug +// #define GL_KHR_debug 1 +// #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 etc. +// typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUPPROC) (); +// #define glPopDebugGroup GLEGetCurrentFunction(glPopDebugGroup) +// #define GLE_KHR_debug GLEGetCurrentVariable(gl_KHR_debug) +// #endif etc. +// +// 2) Add a hook function for in the hook section of the GLEContext class in this header, +// ideally in the same order it's declared in the CAPI_GLE_GL.h so it's easily readable. +// e.g. void glDebugMessageControl_Hook(GLenum source, GLenum type, GLenum severity, GLsizei +// count, const GLuint* ids, GLboolean enabled); etc. +// +// 3) Add a declaration for each interface function to the GLEContext class in this header. +// e.g. PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback_Impl; etc. +// +// 4) Add code to GLEContext::InitExtensionLoad to load the function pointer. +// e.g. GLELoadProc(glDebugMessageCallback_Impl, glDebugMessageCallback); etc. +// +// 5) Add code to GLEContext::InitExtensionSupport to detect the extension support. +// On Mac, core profile functions aren't identified as extensions and so in addition +// to detecting them you need to unilaterally set them as available when using 3.2+ +// by adding them to the section at the bottom of InitExtensionSupport. +// e.g. { gl_KHR_debug, "GL_KHR_debug" }, etc. +// +// 6) Implement the GLEContext hook function(s) you declared. +// e.g. void OVR::GLEContext::glDebugMessageControl_Hook(GLenum source, GLenum type, GLenum +// severity, GLsizei count, const GLuint* ids, GLboolean enabled) +// { +// if(glDebugMessageControl_Impl) +// glDebugMessageControl_Impl(source, type, severity, count, ids, enabled); +// PostHook(); +// } +// +// In order to test this, build with GLE_HOOKING_ENABLED defined and not defined. +// +// Note that if the extension is a WGL-, GLX-, or CGL-specific extension, they are handled like +// above but are in their own section below the section for regular OpenGL extensions. +// +// In some cases the given interface may already be present by currently commented out, +// in which case you can simply un-comment it to enable it. +/////////////////////////////////////////////////////////////////////////////// + +namespace OVR { +// Generic OpenGL GetProcAddress function interface. Maps to platform-specific functionality +// internally. On Windows this is equivalent to wglGetProcAddress as opposed to global +// GetProcAddress. +void* GLEGetProcAddress(const char* name); + +// GLEContext +// +// Manages a collection of OpenGL extension interfaces. +// If the application has multiple OpenGL unrelated contexts then you will want to create a +// different instance of this class for each one you intend to use it with. +// +// Example usage: +// GLEContext gGLEContext; +// +// GLEContext::SetCurrentContext(&gGLEContext); +// gGLEContext.PlatformInit(); // Initializes WGL/GLX/etc. platform-specific OpenGL +// functionality +// +// if(GLE_WGL_ARB_create_context) // If wglCreateContextAttribsARB is available... +// { +// int attribList[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 2, +// WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, None }; HGLRC h = +// wglCreateContextAttribsARB(hDC, 0, attribList); +// [...] +// } +// +// gGLEContext.Init(); // Must be called after an OpenGL context has been created. +// +// if(GLE_WHOLE_VERSION() >= 302) // If OpenGL 3.2 or later +// { +// glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, someTexture, 0); // This is an +// OpenGL 3.2 function. +// [...] +// } +// +// if(GLE_GL_ARB_texture_multisample) // If the GL_ARB_texture_multisample extension is +// available... +// { +// glEnable(GL_SAMPLE_MASK); +// glSampleMaski(0, 0x1); +// [...] +// } +// +// [...] +// +// gGLEContext.Shutdown(); +// +GLE_CLASS_EXPORT class GLEContext { + public: + GLEContext(); + ~GLEContext(); + + // Initializes platform-specific functionality (e.g. Windows WGL, Unix GLX, Android EGL, Apple + // CGL). You would typically call this before creating an OpenGL context and using + // platform-specific functions. + void PlatformInit(); + bool IsPlatformInitialized() const; + + // Loads all the extensions from the current OpenGL context. This must be called after an OpenGL + // context has been created and made current. + void Init(); + bool IsInitialized() const; + + // Clears all the extensions initialized by PlatformInit and Init. + void Shutdown(); + + void SetEnableHookGetError(bool enabled) { + EnableHookGetError = enabled; + } + + // Returns the default instance of this class. + static GLEContext* GetCurrentContext(); + + // Sets the default instance of this class. This should be called after enabling a new OpenGL + // context. This sets the current GLEContext; it does not set the underlying OpenGL context + // itself. + static void SetCurrentContext(GLEContext*); + + public: + // OpenGL version information + int MajorVersion; // OpenGL major version + int MinorVersion; // OpenGL minor version + int WholeVersion; // Equals ((MajorVersion * 100) + MinorVersion). Example usage: + // if(glv.WholeVersion >= 302) // If OpenGL v3.02+ ... + bool IsGLES; // Open GL ES? + bool IsCoreProfile; // Is the current OpenGL context a core profile context? Its trueness may be a + // false positive but will never be a false negative. + bool EnableHookGetError; // If enabled then hook functions call glGetError after making the call. + + int PlatformMajorVersion; // GLX/WGL/EGL/CGL version. Not the same as OpenGL version. + int PlatformMinorVersion; + int PlatformWholeVersion; + + void InitVersion(); // Initializes the version information (e.g. MajorVersion). Called by the + // public Init function. + void InitExtensionLoad(); // Loads the function addresses into the function pointers. + void InitExtensionSupport(); // Loads the boolean extension support booleans. + + void InitPlatformVersion(); + void InitPlatformExtensionLoad(); + void InitPlatformExtensionSupport(); + + public: +// GL_VERSION_1_1 +// Not normally included because all OpenGL 1.1 functionality is always present. But if we have +// hooking enabled then we implement our own version of each function. +#if defined(GLE_HOOKING_ENABLED) + // void PreHook(const char* functionName); // Called at the beginning of a hook + // function. + void PostHook(const char* functionName); // Called at the end of a hook function. + + void glAccum_Hook(GLenum op, GLfloat value); + void glAlphaFunc_Hook(GLenum func, GLclampf ref); + GLboolean glAreTexturesResident_Hook(GLsizei n, const GLuint* textures, GLboolean* residences); + void glArrayElement_Hook(GLint i); + void glBegin_Hook(GLenum mode); + void glBindTexture_Hook(GLenum target, GLuint texture); + void glBitmap_Hook( + GLsizei width, + GLsizei height, + GLfloat xorig, + GLfloat yorig, + GLfloat xmove, + GLfloat ymove, + const GLubyte* bitmap); + void glBlendFunc_Hook(GLenum sfactor, GLenum dfactor); + void glCallList_Hook(GLuint list); + void glCallLists_Hook(GLsizei n, GLenum type, const void* lists); + void glClear_Hook(GLbitfield mask); + void glClearAccum_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void glClearColor_Hook(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + void glClearDepth_Hook(GLclampd depth); + void glClearIndex_Hook(GLfloat c); + void glClearStencil_Hook(GLint s); + void glClipPlane_Hook(GLenum plane, const GLdouble* equation); + void glColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue); + void glColor3bv_Hook(const GLbyte* v); + void glColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue); + void glColor3dv_Hook(const GLdouble* v); + void glColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue); + void glColor3fv_Hook(const GLfloat* v); + void glColor3i_Hook(GLint red, GLint green, GLint blue); + void glColor3iv_Hook(const GLint* v); + void glColor3s_Hook(GLshort red, GLshort green, GLshort blue); + void glColor3sv_Hook(const GLshort* v); + void glColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue); + void glColor3ubv_Hook(const GLubyte* v); + void glColor3ui_Hook(GLuint red, GLuint green, GLuint blue); + void glColor3uiv_Hook(const GLuint* v); + void glColor3us_Hook(GLushort red, GLushort green, GLushort blue); + void glColor3usv_Hook(const GLushort* v); + void glColor4b_Hook(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); + void glColor4bv_Hook(const GLbyte* v); + void glColor4d_Hook(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); + void glColor4dv_Hook(const GLdouble* v); + void glColor4f_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void glColor4fv_Hook(const GLfloat* v); + void glColor4i_Hook(GLint red, GLint green, GLint blue, GLint alpha); + void glColor4iv_Hook(const GLint* v); + void glColor4s_Hook(GLshort red, GLshort green, GLshort blue, GLshort alpha); + void glColor4sv_Hook(const GLshort* v); + void glColor4ub_Hook(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); + void glColor4ubv_Hook(const GLubyte* v); + void glColor4ui_Hook(GLuint red, GLuint green, GLuint blue, GLuint alpha); + void glColor4uiv_Hook(const GLuint* v); + void glColor4us_Hook(GLushort red, GLushort green, GLushort blue, GLushort alpha); + void glColor4usv_Hook(const GLushort* v); + void glColorMask_Hook(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + void glColorMaterial_Hook(GLenum face, GLenum mode); + void glColorPointer_Hook(GLint size, GLenum type, GLsizei stride, const void* pointer); + void glCopyPixels_Hook(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); + void glCopyTexImage1D_Hook( + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLint border); + void glCopyTexImage2D_Hook( + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); + void glCopyTexSubImage1D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint x, + GLint y, + GLsizei width); + void glCopyTexSubImage2D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); + void glCullFace_Hook(GLenum mode); + void glDeleteLists_Hook(GLuint list, GLsizei range); + void glDeleteTextures_Hook(GLsizei n, const GLuint* textures); + void glDepthFunc_Hook(GLenum func); + void glDepthMask_Hook(GLboolean flag); + void glDepthRange_Hook(GLclampd zNear, GLclampd zFar); + void glDisable_Hook(GLenum cap); + void glDisableClientState_Hook(GLenum array); + void glDrawArrays_Hook(GLenum mode, GLint first, GLsizei count); + void glDrawBuffer_Hook(GLenum mode); + void glDrawElements_Hook(GLenum mode, GLsizei count, GLenum type, const void* indices); + void + glDrawPixels_Hook(GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); + void glEdgeFlag_Hook(GLboolean flag); + void glEdgeFlagPointer_Hook(GLsizei stride, const void* pointer); + void glEdgeFlagv_Hook(const GLboolean* flag); + void glEnable_Hook(GLenum cap); + void glEnableClientState_Hook(GLenum array); + void glEnd_Hook(void); + void glEndList_Hook(void); + void glEvalCoord1d_Hook(GLdouble u); + void glEvalCoord1dv_Hook(const GLdouble* u); + void glEvalCoord1f_Hook(GLfloat u); + void glEvalCoord1fv_Hook(const GLfloat* u); + void glEvalCoord2d_Hook(GLdouble u, GLdouble v); + void glEvalCoord2dv_Hook(const GLdouble* u); + void glEvalCoord2f_Hook(GLfloat u, GLfloat v); + void glEvalCoord2fv_Hook(const GLfloat* u); + void glEvalMesh1_Hook(GLenum mode, GLint i1, GLint i2); + void glEvalMesh2_Hook(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); + void glEvalPoint1_Hook(GLint i); + void glEvalPoint2_Hook(GLint i, GLint j); + void glFeedbackBuffer_Hook(GLsizei size, GLenum type, GLfloat* buffer); + void glFinish_Hook(void); + void glFlush_Hook(void); + void glFogf_Hook(GLenum pname, GLfloat param); + void glFogfv_Hook(GLenum pname, const GLfloat* params); + void glFogi_Hook(GLenum pname, GLint param); + void glFogiv_Hook(GLenum pname, const GLint* params); + void glFrontFace_Hook(GLenum mode); + void glFrustum_Hook( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar); + GLuint glGenLists_Hook(GLsizei range); + void glGenTextures_Hook(GLsizei n, GLuint* textures); + void glGetBooleanv_Hook(GLenum pname, GLboolean* params); + void glGetClipPlane_Hook(GLenum plane, GLdouble* equation); + void glGetDoublev_Hook(GLenum pname, GLdouble* params); + GLenum glGetError_Hook(void); + void glGetFloatv_Hook(GLenum pname, GLfloat* params); + void glGetIntegerv_Hook(GLenum pname, GLint* params); + void glGetLightfv_Hook(GLenum light, GLenum pname, GLfloat* params); + void glGetLightiv_Hook(GLenum light, GLenum pname, GLint* params); + void glGetMapdv_Hook(GLenum target, GLenum query, GLdouble* v); + void glGetMapfv_Hook(GLenum target, GLenum query, GLfloat* v); + void glGetMapiv_Hook(GLenum target, GLenum query, GLint* v); + void glGetMaterialfv_Hook(GLenum face, GLenum pname, GLfloat* params); + void glGetMaterialiv_Hook(GLenum face, GLenum pname, GLint* params); + void glGetPixelMapfv_Hook(GLenum map, GLfloat* values); + void glGetPixelMapuiv_Hook(GLenum map, GLuint* values); + void glGetPixelMapusv_Hook(GLenum map, GLushort* values); + void glGetPointerv_Hook(GLenum pname, void** params); + void glGetPolygonStipple_Hook(GLubyte* mask); + const GLubyte* glGetString_Hook(GLenum name); + void glGetTexEnvfv_Hook(GLenum target, GLenum pname, GLfloat* params); + void glGetTexEnviv_Hook(GLenum target, GLenum pname, GLint* params); + void glGetTexGendv_Hook(GLenum coord, GLenum pname, GLdouble* params); + void glGetTexGenfv_Hook(GLenum coord, GLenum pname, GLfloat* params); + void glGetTexGeniv_Hook(GLenum coord, GLenum pname, GLint* params); + void glGetTexImage_Hook(GLenum target, GLint level, GLenum format, GLenum type, void* pixels); + void glGetTexLevelParameterfv_Hook(GLenum target, GLint level, GLenum pname, GLfloat* params); + void glGetTexLevelParameteriv_Hook(GLenum target, GLint level, GLenum pname, GLint* params); + void glGetTexParameterfv_Hook(GLenum target, GLenum pname, GLfloat* params); + void glGetTexParameteriv_Hook(GLenum target, GLenum pname, GLint* params); + void glHint_Hook(GLenum target, GLenum mode); + void glIndexMask_Hook(GLuint mask); + void glIndexPointer_Hook(GLenum type, GLsizei stride, const void* pointer); + void glIndexd_Hook(GLdouble c); + void glIndexdv_Hook(const GLdouble* c); + void glIndexf_Hook(GLfloat c); + void glIndexfv_Hook(const GLfloat* c); + void glIndexi_Hook(GLint c); + void glIndexiv_Hook(const GLint* c); + void glIndexs_Hook(GLshort c); + void glIndexsv_Hook(const GLshort* c); + void glIndexub_Hook(GLubyte c); + void glIndexubv_Hook(const GLubyte* c); + void glInitNames_Hook(void); + void glInterleavedArrays_Hook(GLenum format, GLsizei stride, const void* pointer); + GLboolean glIsEnabled_Hook(GLenum cap); + GLboolean glIsList_Hook(GLuint list); + GLboolean glIsTexture_Hook(GLuint texture); + void glLightModelf_Hook(GLenum pname, GLfloat param); + void glLightModelfv_Hook(GLenum pname, const GLfloat* params); + void glLightModeli_Hook(GLenum pname, GLint param); + void glLightModeliv_Hook(GLenum pname, const GLint* params); + void glLightf_Hook(GLenum light, GLenum pname, GLfloat param); + void glLightfv_Hook(GLenum light, GLenum pname, const GLfloat* params); + void glLighti_Hook(GLenum light, GLenum pname, GLint param); + void glLightiv_Hook(GLenum light, GLenum pname, const GLint* params); + void glLineStipple_Hook(GLint factor, GLushort pattern); + void glLineWidth_Hook(GLfloat width); + void glListBase_Hook(GLuint base); + void glLoadIdentity_Hook(void); + void glLoadMatrixd_Hook(const GLdouble* m); + void glLoadMatrixf_Hook(const GLfloat* m); + void glLoadName_Hook(GLuint name); + void glLogicOp_Hook(GLenum opcode); + void glMap1d_Hook( + GLenum target, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble* points); + void glMap1f_Hook( + GLenum target, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat* points); + void glMap2d_Hook( + GLenum target, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble* points); + void glMap2f_Hook( + GLenum target, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat* points); + void glMapGrid1d_Hook(GLint un, GLdouble u1, GLdouble u2); + void glMapGrid1f_Hook(GLint un, GLfloat u1, GLfloat u2); + void glMapGrid2d_Hook(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); + void glMapGrid2f_Hook(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); + void glMaterialf_Hook(GLenum face, GLenum pname, GLfloat param); + void glMaterialfv_Hook(GLenum face, GLenum pname, const GLfloat* params); + void glMateriali_Hook(GLenum face, GLenum pname, GLint param); + void glMaterialiv_Hook(GLenum face, GLenum pname, const GLint* params); + void glMatrixMode_Hook(GLenum mode); + void glMultMatrixd_Hook(const GLdouble* m); + void glMultMatrixf_Hook(const GLfloat* m); + void glNewList_Hook(GLuint list, GLenum mode); + void glNormal3b_Hook(GLbyte nx, GLbyte ny, GLbyte nz); + void glNormal3bv_Hook(const GLbyte* v); + void glNormal3d_Hook(GLdouble nx, GLdouble ny, GLdouble nz); + void glNormal3dv_Hook(const GLdouble* v); + void glNormal3f_Hook(GLfloat nx, GLfloat ny, GLfloat nz); + void glNormal3fv_Hook(const GLfloat* v); + void glNormal3i_Hook(GLint nx, GLint ny, GLint nz); + void glNormal3iv_Hook(const GLint* v); + void glNormal3s_Hook(GLshort nx, GLshort ny, GLshort nz); + void glNormal3sv_Hook(const GLshort* v); + void glNormalPointer_Hook(GLenum type, GLsizei stride, const void* pointer); + void glOrtho_Hook( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar); + void glPassThrough_Hook(GLfloat token); + void glPixelMapfv_Hook(GLenum map, GLsizei mapsize, const GLfloat* values); + void glPixelMapuiv_Hook(GLenum map, GLsizei mapsize, const GLuint* values); + void glPixelMapusv_Hook(GLenum map, GLsizei mapsize, const GLushort* values); + void glPixelStoref_Hook(GLenum pname, GLfloat param); + void glPixelStorei_Hook(GLenum pname, GLint param); + void glPixelTransferf_Hook(GLenum pname, GLfloat param); + void glPixelTransferi_Hook(GLenum pname, GLint param); + void glPixelZoom_Hook(GLfloat xfactor, GLfloat yfactor); + void glPointSize_Hook(GLfloat size); + void glPolygonMode_Hook(GLenum face, GLenum mode); + void glPolygonOffset_Hook(GLfloat factor, GLfloat units); + void glPolygonStipple_Hook(const GLubyte* mask); + void glPopAttrib_Hook(void); + void glPopClientAttrib_Hook(void); + void glPopMatrix_Hook(void); + void glPopName_Hook(void); + void glPrioritizeTextures_Hook(GLsizei n, const GLuint* textures, const GLclampf* priorities); + void glPushAttrib_Hook(GLbitfield mask); + void glPushClientAttrib_Hook(GLbitfield mask); + void glPushMatrix_Hook(void); + void glPushName_Hook(GLuint name); + void glRasterPos2d_Hook(GLdouble x, GLdouble y); + void glRasterPos2dv_Hook(const GLdouble* v); + void glRasterPos2f_Hook(GLfloat x, GLfloat y); + void glRasterPos2fv_Hook(const GLfloat* v); + void glRasterPos2i_Hook(GLint x, GLint y); + void glRasterPos2iv_Hook(const GLint* v); + void glRasterPos2s_Hook(GLshort x, GLshort y); + void glRasterPos2sv_Hook(const GLshort* v); + void glRasterPos3d_Hook(GLdouble x, GLdouble y, GLdouble z); + void glRasterPos3dv_Hook(const GLdouble* v); + void glRasterPos3f_Hook(GLfloat x, GLfloat y, GLfloat z); + void glRasterPos3fv_Hook(const GLfloat* v); + void glRasterPos3i_Hook(GLint x, GLint y, GLint z); + void glRasterPos3iv_Hook(const GLint* v); + void glRasterPos3s_Hook(GLshort x, GLshort y, GLshort z); + void glRasterPos3sv_Hook(const GLshort* v); + void glRasterPos4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w); + void glRasterPos4dv_Hook(const GLdouble* v); + void glRasterPos4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void glRasterPos4fv_Hook(const GLfloat* v); + void glRasterPos4i_Hook(GLint x, GLint y, GLint z, GLint w); + void glRasterPos4iv_Hook(const GLint* v); + void glRasterPos4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w); + void glRasterPos4sv_Hook(const GLshort* v); + void glReadBuffer_Hook(GLenum mode); + void glReadPixels_Hook( + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void* pixels); + void glRectd_Hook(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); + void glRectdv_Hook(const GLdouble* v1, const GLdouble* v2); + void glRectf_Hook(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); + void glRectfv_Hook(const GLfloat* v1, const GLfloat* v2); + void glRecti_Hook(GLint x1, GLint y1, GLint x2, GLint y2); + void glRectiv_Hook(const GLint* v1, const GLint* v2); + void glRects_Hook(GLshort x1, GLshort y1, GLshort x2, GLshort y2); + void glRectsv_Hook(const GLshort* v1, const GLshort* v2); + GLint glRenderMode_Hook(GLenum mode); + void glRotated_Hook(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); + void glRotatef_Hook(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); + void glScaled_Hook(GLdouble x, GLdouble y, GLdouble z); + void glScalef_Hook(GLfloat x, GLfloat y, GLfloat z); + void glScissor_Hook(GLint x, GLint y, GLsizei width, GLsizei height); + void glSelectBuffer_Hook(GLsizei size, GLuint* buffer); + void glShadeModel_Hook(GLenum mode); + void glStencilFunc_Hook(GLenum func, GLint ref, GLuint mask); + void glStencilMask_Hook(GLuint mask); + void glStencilOp_Hook(GLenum fail, GLenum zfail, GLenum zpass); + void glTexCoord1d_Hook(GLdouble s); + void glTexCoord1dv_Hook(const GLdouble* v); + void glTexCoord1f_Hook(GLfloat s); + void glTexCoord1fv_Hook(const GLfloat* v); + void glTexCoord1i_Hook(GLint s); + void glTexCoord1iv_Hook(const GLint* v); + void glTexCoord1s_Hook(GLshort s); + void glTexCoord1sv_Hook(const GLshort* v); + void glTexCoord2d_Hook(GLdouble s, GLdouble t); + void glTexCoord2dv_Hook(const GLdouble* v); + void glTexCoord2f_Hook(GLfloat s, GLfloat t); + void glTexCoord2fv_Hook(const GLfloat* v); + void glTexCoord2i_Hook(GLint s, GLint t); + void glTexCoord2iv_Hook(const GLint* v); + void glTexCoord2s_Hook(GLshort s, GLshort t); + void glTexCoord2sv_Hook(const GLshort* v); + void glTexCoord3d_Hook(GLdouble s, GLdouble t, GLdouble r); + void glTexCoord3dv_Hook(const GLdouble* v); + void glTexCoord3f_Hook(GLfloat s, GLfloat t, GLfloat r); + void glTexCoord3fv_Hook(const GLfloat* v); + void glTexCoord3i_Hook(GLint s, GLint t, GLint r); + void glTexCoord3iv_Hook(const GLint* v); + void glTexCoord3s_Hook(GLshort s, GLshort t, GLshort r); + void glTexCoord3sv_Hook(const GLshort* v); + void glTexCoord4d_Hook(GLdouble s, GLdouble t, GLdouble r, GLdouble q); + void glTexCoord4dv_Hook(const GLdouble* v); + void glTexCoord4f_Hook(GLfloat s, GLfloat t, GLfloat r, GLfloat q); + void glTexCoord4fv_Hook(const GLfloat* v); + void glTexCoord4i_Hook(GLint s, GLint t, GLint r, GLint q); + void glTexCoord4iv_Hook(const GLint* v); + void glTexCoord4s_Hook(GLshort s, GLshort t, GLshort r, GLshort q); + void glTexCoord4sv_Hook(const GLshort* v); + void glTexCoordPointer_Hook(GLint size, GLenum type, GLsizei stride, const void* pointer); + void glTexEnvf_Hook(GLenum target, GLenum pname, GLfloat param); + void glTexEnvfv_Hook(GLenum target, GLenum pname, const GLfloat* params); + void glTexEnvi_Hook(GLenum target, GLenum pname, GLint param); + void glTexEnviv_Hook(GLenum target, GLenum pname, const GLint* params); + void glTexGend_Hook(GLenum coord, GLenum pname, GLdouble param); + void glTexGendv_Hook(GLenum coord, GLenum pname, const GLdouble* params); + void glTexGenf_Hook(GLenum coord, GLenum pname, GLfloat param); + void glTexGenfv_Hook(GLenum coord, GLenum pname, const GLfloat* params); + void glTexGeni_Hook(GLenum coord, GLenum pname, GLint param); + void glTexGeniv_Hook(GLenum coord, GLenum pname, const GLint* params); + void glTexImage1D_Hook( + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const void* pixels); + void glTexImage2D_Hook( + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void* pixels); + void glTexParameterf_Hook(GLenum target, GLenum pname, GLfloat param); + void glTexParameterfv_Hook(GLenum target, GLenum pname, const GLfloat* params); + void glTexParameteri_Hook(GLenum target, GLenum pname, GLint param); + void glTexParameteriv_Hook(GLenum target, GLenum pname, const GLint* params); + void glTexSubImage1D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void* pixels); + void glTexSubImage2D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void* pixels); + void glTranslated_Hook(GLdouble x, GLdouble y, GLdouble z); + void glTranslatef_Hook(GLfloat x, GLfloat y, GLfloat z); + void glVertex2d_Hook(GLdouble x, GLdouble y); + void glVertex2dv_Hook(const GLdouble* v); + void glVertex2f_Hook(GLfloat x, GLfloat y); + void glVertex2fv_Hook(const GLfloat* v); + void glVertex2i_Hook(GLint x, GLint y); + void glVertex2iv_Hook(const GLint* v); + void glVertex2s_Hook(GLshort x, GLshort y); + void glVertex2sv_Hook(const GLshort* v); + void glVertex3d_Hook(GLdouble x, GLdouble y, GLdouble z); + void glVertex3dv_Hook(const GLdouble* v); + void glVertex3f_Hook(GLfloat x, GLfloat y, GLfloat z); + void glVertex3fv_Hook(const GLfloat* v); + void glVertex3i_Hook(GLint x, GLint y, GLint z); + void glVertex3iv_Hook(const GLint* v); + void glVertex3s_Hook(GLshort x, GLshort y, GLshort z); + void glVertex3sv_Hook(const GLshort* v); + void glVertex4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w); + void glVertex4dv_Hook(const GLdouble* v); + void glVertex4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void glVertex4fv_Hook(const GLfloat* v); + void glVertex4i_Hook(GLint x, GLint y, GLint z, GLint w); + void glVertex4iv_Hook(const GLint* v); + void glVertex4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w); + void glVertex4sv_Hook(const GLshort* v); + void glVertexPointer_Hook(GLint size, GLenum type, GLsizei stride, const void* pointer); + void glViewport_Hook(GLint x, GLint y, GLsizei width, GLsizei height); + + // GL_VERSION_1_2 + void glBlendColor_Hook(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + void glBlendEquation_Hook(GLenum mode); + void glDrawRangeElements_Hook( + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid* indices); + void glTexImage3D_Hook( + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const GLvoid* pixels); + void glTexSubImage3D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const GLvoid* pixels); + void glCopyTexSubImage3D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); + + // GL_VERSION_1_2 deprecated functions + /* Not currently supported + void glColorTable_Hook(GLenum target, GLenum internalformat, GLsizei width, + GLenum format, GLenum type, const GLvoid *table); + void glColorTableParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params); + void glColorTableParameteriv_Hook(GLenum target, GLenum pname, const GLint *params); + void glCopyColorTable_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); + void glGetColorTable_Hook(GLenum target, GLenum format, GLenum type, GLvoid *table); + void glGetColorTableParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); + void glGetColorTableParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + void glColorSubTable_Hook(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, + const GLvoid *data); + void glCopyColorSubTable_Hook(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + void glConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLenum + format, GLenum type, const GLvoid *image); + void glConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei + height, GLenum format, GLenum type, const GLvoid *image); + void glConvolutionParameterf_Hook(GLenum target, GLenum pname, GLfloat params); + void glConvolutionParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params); + void glConvolutionParameteri_Hook(GLenum target, GLenum pname, GLint params); + void glConvolutionParameteriv_Hook(GLenum target, GLenum pname, const GLint *params); + void glCopyConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width); + void glCopyConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height); + void glGetConvolutionFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid *image); + void glGetConvolutionParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); + void glGetConvolutionParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + void glGetSeparableFilter_Hook(GLenum target, GLenum format, GLenum type, + GLvoid *row, GLvoid *column, GLvoid *span); + void glSeparableFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); + void glGetHistogram_Hook(GLenum target, GLboolean reset, GLenum format, + GLenum type, GLvoid *values); + void glGetHistogramParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); + void glGetHistogramParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + void glGetMinmax_Hook(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); + void glGetMinmaxParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); + void glGetMinmaxParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + void glHistogram_Hook(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); + void glMinmax_Hook(GLenum target, GLenum internalformat, GLboolean sink); + void glResetHistogram_Hook(GLenum target); + void glResetMinmax_Hook(GLenum target); + */ + + // GL_VERSION_1_3 + void glActiveTexture_Hook(GLenum texture); + void glSampleCoverage_Hook(GLclampf value, GLboolean invert); + void glCompressedTexImage3D_Hook( + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const GLvoid* data); + void glCompressedTexImage2D_Hook( + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const GLvoid* data); + void glCompressedTexImage1D_Hook( + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLint border, + GLsizei imageSize, + const GLvoid* data); + void glCompressedTexSubImage3D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const GLvoid* data); + void glCompressedTexSubImage2D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const GLvoid* data); + void glCompressedTexSubImage1D_Hook( + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const GLvoid* data); + void glGetCompressedTexImage_Hook(GLenum target, GLint level, GLvoid* img); + + // GL_VERSION_1_3 deprecated functions + void glClientActiveTexture_Hook(GLenum texture); + void glMultiTexCoord1d_Hook(GLenum target, GLdouble s); + void glMultiTexCoord1dv_Hook(GLenum target, const GLdouble* v); + void glMultiTexCoord1f_Hook(GLenum target, GLfloat s); + void glMultiTexCoord1fv_Hook(GLenum target, const GLfloat* v); + void glMultiTexCoord1i_Hook(GLenum target, GLint s); + void glMultiTexCoord1iv_Hook(GLenum target, const GLint* v); + void glMultiTexCoord1s_Hook(GLenum target, GLshort s); + void glMultiTexCoord1sv_Hook(GLenum target, const GLshort* v); + void glMultiTexCoord2d_Hook(GLenum target, GLdouble s, GLdouble t); + void glMultiTexCoord2dv_Hook(GLenum target, const GLdouble* v); + void glMultiTexCoord2f_Hook(GLenum target, GLfloat s, GLfloat t); + void glMultiTexCoord2fv_Hook(GLenum target, const GLfloat* v); + void glMultiTexCoord2i_Hook(GLenum target, GLint s, GLint t); + void glMultiTexCoord2iv_Hook(GLenum target, const GLint* v); + void glMultiTexCoord2s_Hook(GLenum target, GLshort s, GLshort t); + void glMultiTexCoord2sv_Hook(GLenum target, const GLshort* v); + void glMultiTexCoord3d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r); + void glMultiTexCoord3dv_Hook(GLenum target, const GLdouble* v); + void glMultiTexCoord3f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r); + void glMultiTexCoord3fv_Hook(GLenum target, const GLfloat* v); + void glMultiTexCoord3i_Hook(GLenum target, GLint s, GLint t, GLint r); + void glMultiTexCoord3iv_Hook(GLenum target, const GLint* v); + void glMultiTexCoord3s_Hook(GLenum target, GLshort s, GLshort t, GLshort r); + void glMultiTexCoord3sv_Hook(GLenum target, const GLshort* v); + void glMultiTexCoord4d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); + void glMultiTexCoord4dv_Hook(GLenum target, const GLdouble* v); + void glMultiTexCoord4f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); + void glMultiTexCoord4fv_Hook(GLenum target, const GLfloat* v); + void glMultiTexCoord4i_Hook(GLenum target, GLint s, GLint t, GLint r, GLint q); + void glMultiTexCoord4iv_Hook(GLenum target, const GLint* v); + void glMultiTexCoord4s_Hook(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); + void glMultiTexCoord4sv_Hook(GLenum target, const GLshort* v); + void glLoadTransposeMatrixf_Hook(const GLfloat* m); + void glLoadTransposeMatrixd_Hook(const GLdouble* m); + void glMultTransposeMatrixf_Hook(const GLfloat* m); + void glMultTransposeMatrixd_Hook(const GLdouble* m); + + // GL_VERSION_1_4 + void glBlendFuncSeparate_Hook( + GLenum sfactorRGB, + GLenum dfactorRGB, + GLenum sfactorAlpha, + GLenum dfactorAlpha); + void + glMultiDrawArrays_Hook(GLenum mode, const GLint* first, const GLsizei* count, GLsizei primcount); + void glMultiDrawElements_Hook( + GLenum mode, + const GLsizei* count, + GLenum type, + const GLvoid** indices, + GLsizei primcount); + void glPointParameterf_Hook(GLenum pname, GLfloat param); + void glPointParameterfv_Hook(GLenum pname, const GLfloat* params); + void glPointParameteri_Hook(GLenum pname, GLint param); + void glPointParameteriv_Hook(GLenum pname, const GLint* params); + + // GL_VERSION_1_4 deprecated functions + void glFogCoordf_Hook(GLfloat coord); + void glFogCoordfv_Hook(const GLfloat* coord); + void glFogCoordd_Hook(GLdouble coord); + void glFogCoorddv_Hook(const GLdouble* coord); + void glFogCoordPointer_Hook(GLenum type, GLsizei stride, const GLvoid* pointer); + void glSecondaryColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue); + void glSecondaryColor3bv_Hook(const GLbyte* v); + void glSecondaryColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue); + void glSecondaryColor3dv_Hook(const GLdouble* v); + void glSecondaryColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue); + void glSecondaryColor3fv_Hook(const GLfloat* v); + void glSecondaryColor3i_Hook(GLint red, GLint green, GLint blue); + void glSecondaryColor3iv_Hook(const GLint* v); + void glSecondaryColor3s_Hook(GLshort red, GLshort green, GLshort blue); + void glSecondaryColor3sv_Hook(const GLshort* v); + void glSecondaryColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue); + void glSecondaryColor3ubv_Hook(const GLubyte* v); + void glSecondaryColor3ui_Hook(GLuint red, GLuint green, GLuint blue); + void glSecondaryColor3uiv_Hook(const GLuint* v); + void glSecondaryColor3us_Hook(GLushort red, GLushort green, GLushort blue); + void glSecondaryColor3usv_Hook(const GLushort* v); + void glSecondaryColorPointer_Hook(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer); + void glWindowPos2d_Hook(GLdouble x, GLdouble y); + void glWindowPos2dv_Hook(const GLdouble* v); + void glWindowPos2f_Hook(GLfloat x, GLfloat y); + void glWindowPos2fv_Hook(const GLfloat* v); + void glWindowPos2i_Hook(GLint x, GLint y); + void glWindowPos2iv_Hook(const GLint* v); + void glWindowPos2s_Hook(GLshort x, GLshort y); + void glWindowPos2sv_Hook(const GLshort* v); + void glWindowPos3d_Hook(GLdouble x, GLdouble y, GLdouble z); + void glWindowPos3dv_Hook(const GLdouble* v); + void glWindowPos3f_Hook(GLfloat x, GLfloat y, GLfloat z); + void glWindowPos3fv_Hook(const GLfloat* v); + void glWindowPos3i_Hook(GLint x, GLint y, GLint z); + void glWindowPos3iv_Hook(const GLint* v); + void glWindowPos3s_Hook(GLshort x, GLshort y, GLshort z); + void glWindowPos3sv_Hook(const GLshort* v); + + // GL_VERSION_1_5 + void glGenQueries_Hook(GLsizei n, GLuint* ids); + void glDeleteQueries_Hook(GLsizei n, const GLuint* ids); + GLboolean glIsQuery_Hook(GLuint id); + void glBeginQuery_Hook(GLenum target, GLuint id); + void glEndQuery_Hook(GLenum target); + void glGetQueryiv_Hook(GLenum target, GLenum pname, GLint* params); + void glGetQueryObjectiv_Hook(GLuint id, GLenum pname, GLint* params); + void glGetQueryObjectuiv_Hook(GLuint id, GLenum pname, GLuint* params); + void glBindBuffer_Hook(GLenum target, GLuint buffer); + void glDeleteBuffers_Hook(GLsizei n, const GLuint* buffers); + void glGenBuffers_Hook(GLsizei n, GLuint* buffers); + GLboolean glIsBuffer_Hook(GLuint buffer); + void glBufferData_Hook(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); + void glBufferSubData_Hook(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); + void glGetBufferSubData_Hook(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data); + GLvoid* glMapBuffer_Hook(GLenum target, GLenum access); + GLboolean glUnmapBuffer_Hook(GLenum target); + void glGetBufferParameteriv_Hook(GLenum target, GLenum pname, GLint* params); + void glGetBufferPointerv_Hook(GLenum target, GLenum pname, GLvoid** params); + + // GL_VERSION_2_0 + void glBlendEquationSeparate_Hook(GLenum modeRGB, GLenum modeAlpha); + void glDrawBuffers_Hook(GLsizei n, const GLenum* bufs); + void glStencilOpSeparate_Hook(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + void glStencilFuncSeparate_Hook(GLenum face, GLenum func, GLint ref, GLuint mask); + void glStencilMaskSeparate_Hook(GLenum face, GLuint mask); + void glAttachShader_Hook(GLuint program, GLuint shader); + void glBindAttribLocation_Hook(GLuint program, GLuint index, const GLchar* name); + void glCompileShader_Hook(GLuint shader); + GLuint glCreateProgram_Hook(void); + GLuint glCreateShader_Hook(GLenum type); + void glDeleteProgram_Hook(GLuint program); + void glDeleteShader_Hook(GLuint shader); + void glDetachShader_Hook(GLuint program, GLuint shader); + void glDisableVertexAttribArray_Hook(GLuint index); + void glEnableVertexAttribArray_Hook(GLuint index); + void glGetActiveAttrib_Hook( + GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei* length, + GLint* size, + GLenum* type, + GLchar* name); + void glGetActiveUniform_Hook( + GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei* length, + GLint* size, + GLenum* type, + GLchar* name); + void glGetAttachedShaders_Hook(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* obj); + GLint glGetAttribLocation_Hook(GLuint program, const GLchar* name); + void glGetProgramiv_Hook(GLuint program, GLenum pname, GLint* params); + void glGetProgramInfoLog_Hook(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); + void glGetShaderiv_Hook(GLuint shader, GLenum pname, GLint* params); + void glGetShaderInfoLog_Hook(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); + void glGetShaderSource_Hook(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source); + GLint glGetUniformLocation_Hook(GLuint program, const GLchar* name); + void glGetUniformfv_Hook(GLuint program, GLint location, GLfloat* params); + void glGetUniformiv_Hook(GLuint program, GLint location, GLint* params); + void glGetVertexAttribdv_Hook(GLuint index, GLenum pname, GLdouble* params); + void glGetVertexAttribfv_Hook(GLuint index, GLenum pname, GLfloat* params); + void glGetVertexAttribiv_Hook(GLuint index, GLenum pname, GLint* params); + void glGetVertexAttribPointerv_Hook(GLuint index, GLenum pname, GLvoid** pointer); + GLboolean glIsProgram_Hook(GLuint program); + GLboolean glIsShader_Hook(GLuint shader); + void glLinkProgram_Hook(GLuint program); + void + glShaderSource_Hook(GLuint shader, GLsizei count, const GLchar** string, const GLint* length); + void glUseProgram_Hook(GLuint program); + void glUniform1f_Hook(GLint location, GLfloat v0); + void glUniform2f_Hook(GLint location, GLfloat v0, GLfloat v1); + void glUniform3f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void glUniform4f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + void glUniform1i_Hook(GLint location, GLint v0); + void glUniform2i_Hook(GLint location, GLint v0, GLint v1); + void glUniform3i_Hook(GLint location, GLint v0, GLint v1, GLint v2); + void glUniform4i_Hook(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + void glUniform1fv_Hook(GLint location, GLsizei count, const GLfloat* value); + void glUniform2fv_Hook(GLint location, GLsizei count, const GLfloat* value); + void glUniform3fv_Hook(GLint location, GLsizei count, const GLfloat* value); + void glUniform4fv_Hook(GLint location, GLsizei count, const GLfloat* value); + void glUniform1iv_Hook(GLint location, GLsizei count, const GLint* value); + void glUniform2iv_Hook(GLint location, GLsizei count, const GLint* value); + void glUniform3iv_Hook(GLint location, GLsizei count, const GLint* value); + void glUniform4iv_Hook(GLint location, GLsizei count, const GLint* value); + void + glUniformMatrix2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + void + glUniformMatrix3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + void + glUniformMatrix4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + void glValidateProgram_Hook(GLuint program); + void glVertexAttrib1d_Hook(GLuint index, GLdouble x); + void glVertexAttrib1dv_Hook(GLuint index, const GLdouble* v); + void glVertexAttrib1f_Hook(GLuint index, GLfloat x); + void glVertexAttrib1fv_Hook(GLuint index, const GLfloat* v); + void glVertexAttrib1s_Hook(GLuint index, GLshort x); + void glVertexAttrib1sv_Hook(GLuint index, const GLshort* v); + void glVertexAttrib2d_Hook(GLuint index, GLdouble x, GLdouble y); + void glVertexAttrib2dv_Hook(GLuint index, const GLdouble* v); + void glVertexAttrib2f_Hook(GLuint index, GLfloat x, GLfloat y); + void glVertexAttrib2fv_Hook(GLuint index, const GLfloat* v); + void glVertexAttrib2s_Hook(GLuint index, GLshort x, GLshort y); + void glVertexAttrib2sv_Hook(GLuint index, const GLshort* v); + void glVertexAttrib3d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z); + void glVertexAttrib3dv_Hook(GLuint index, const GLdouble* v); + void glVertexAttrib3f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z); + void glVertexAttrib3fv_Hook(GLuint index, const GLfloat* v); + void glVertexAttrib3s_Hook(GLuint index, GLshort x, GLshort y, GLshort z); + void glVertexAttrib3sv_Hook(GLuint index, const GLshort* v); + void glVertexAttrib4Nbv_Hook(GLuint index, const GLbyte* v); + void glVertexAttrib4Niv_Hook(GLuint index, const GLint* v); + void glVertexAttrib4Nsv_Hook(GLuint index, const GLshort* v); + void glVertexAttrib4Nub_Hook(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); + void glVertexAttrib4Nubv_Hook(GLuint index, const GLubyte* v); + void glVertexAttrib4Nuiv_Hook(GLuint index, const GLuint* v); + void glVertexAttrib4Nusv_Hook(GLuint index, const GLushort* v); + void glVertexAttrib4bv_Hook(GLuint index, const GLbyte* v); + void glVertexAttrib4d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + void glVertexAttrib4dv_Hook(GLuint index, const GLdouble* v); + void glVertexAttrib4f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void glVertexAttrib4fv_Hook(GLuint index, const GLfloat* v); + void glVertexAttrib4iv_Hook(GLuint index, const GLint* v); + void glVertexAttrib4s_Hook(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); + void glVertexAttrib4sv_Hook(GLuint index, const GLshort* v); + void glVertexAttrib4ubv_Hook(GLuint index, const GLubyte* v); + void glVertexAttrib4uiv_Hook(GLuint index, const GLuint* v); + void glVertexAttrib4usv_Hook(GLuint index, const GLushort* v); + void glVertexAttribPointer_Hook( + GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const GLvoid* pointer); + + // GL_VERSION_2_1 + void glUniformMatrix2x3fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); + void glUniformMatrix3x2fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); + void glUniformMatrix2x4fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); + void glUniformMatrix4x2fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); + void glUniformMatrix3x4fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); + void glUniformMatrix4x3fv_Hook( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); + + // GL_VERSION_3_0 + void glColorMaski_Hook(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); + void glGetBooleani_v_Hook(GLenum target, GLuint index, GLboolean* data); + void glGetIntegeri_v_Hook(GLenum target, GLuint index, GLint* data); + void glEnablei_Hook(GLenum target, GLuint index); + void glDisablei_Hook(GLenum target, GLuint index); + GLboolean glIsEnabledi_Hook(GLenum target, GLuint index); + void glBeginTransformFeedback_Hook(GLenum primitiveMode); + void glEndTransformFeedback_Hook(void); + void glBindBufferRange_Hook( + GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size); + void glBindBufferBase_Hook(GLenum target, GLuint index, GLuint buffer); + void glTransformFeedbackVaryings_Hook( + GLuint program, + GLsizei count, + const GLchar** varyings, + GLenum bufferMode); + void glGetTransformFeedbackVarying_Hook( + GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei* length, + GLsizei* size, + GLenum* type, + GLchar* name); + void glClampColor_Hook(GLenum target, GLenum clamp); + void glBeginConditionalRender_Hook(GLuint id, GLenum mode); + void glEndConditionalRender_Hook(void); + void glVertexAttribIPointer_Hook( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid* pointer); + void glGetVertexAttribIiv_Hook(GLuint index, GLenum pname, GLint* params); + void glGetVertexAttribIuiv_Hook(GLuint index, GLenum pname, GLuint* params); + void glVertexAttribI1i_Hook(GLuint index, GLint x); + void glVertexAttribI2i_Hook(GLuint index, GLint x, GLint y); + void glVertexAttribI3i_Hook(GLuint index, GLint x, GLint y, GLint z); + void glVertexAttribI4i_Hook(GLuint index, GLint x, GLint y, GLint z, GLint w); + void glVertexAttribI1ui_Hook(GLuint index, GLuint x); + void glVertexAttribI2ui_Hook(GLuint index, GLuint x, GLuint y); + void glVertexAttribI3ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z); + void glVertexAttribI4ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void glVertexAttribI1iv_Hook(GLuint index, const GLint* v); + void glVertexAttribI2iv_Hook(GLuint index, const GLint* v); + void glVertexAttribI3iv_Hook(GLuint index, const GLint* v); + void glVertexAttribI4iv_Hook(GLuint index, const GLint* v); + void glVertexAttribI1uiv_Hook(GLuint index, const GLuint* v); + void glVertexAttribI2uiv_Hook(GLuint index, const GLuint* v); + void glVertexAttribI3uiv_Hook(GLuint index, const GLuint* v); + void glVertexAttribI4uiv_Hook(GLuint index, const GLuint* v); + void glVertexAttribI4bv_Hook(GLuint index, const GLbyte* v); + void glVertexAttribI4sv_Hook(GLuint index, const GLshort* v); + void glVertexAttribI4ubv_Hook(GLuint index, const GLubyte* v); + void glVertexAttribI4usv_Hook(GLuint index, const GLushort* v); + void glGetUniformuiv_Hook(GLuint program, GLint location, GLuint* params); + void glBindFragDataLocation_Hook(GLuint program, GLuint color, const GLchar* name); + GLint glGetFragDataLocation_Hook(GLuint program, const GLchar* name); + void glUniform1ui_Hook(GLint location, GLuint v0); + void glUniform2ui_Hook(GLint location, GLuint v0, GLuint v1); + void glUniform3ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2); + void glUniform4ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void glUniform1uiv_Hook(GLint location, GLsizei count, const GLuint* value); + void glUniform2uiv_Hook(GLint location, GLsizei count, const GLuint* value); + void glUniform3uiv_Hook(GLint location, GLsizei count, const GLuint* value); + void glUniform4uiv_Hook(GLint location, GLsizei count, const GLuint* value); + void glTexParameterIiv_Hook(GLenum target, GLenum pname, const GLint* params); + void glTexParameterIuiv_Hook(GLenum target, GLenum pname, const GLuint* params); + void glGetTexParameterIiv_Hook(GLenum target, GLenum pname, GLint* params); + void glGetTexParameterIuiv_Hook(GLenum target, GLenum pname, GLuint* params); + void glClearBufferiv_Hook(GLenum buffer, GLint drawbuffer, const GLint* value); + void glClearBufferuiv_Hook(GLenum buffer, GLint drawbuffer, const GLuint* value); + void glClearBufferfv_Hook(GLenum buffer, GLint drawbuffer, const GLfloat* value); + void glClearBufferfi_Hook(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + const GLubyte* glGetStringi_Hook(GLenum name, GLuint index); + + // GL_VERSION_3_1 + void glDrawArraysInstanced_Hook(GLenum mode, GLint first, GLsizei count, GLsizei primcount); + void glDrawElementsInstanced_Hook( + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid* indices, + GLsizei primcount); + void glTexBuffer_Hook(GLenum target, GLenum internalformat, GLuint buffer); + void glPrimitiveRestartIndex_Hook(GLuint index); + + // GL_VERSION_3_2 + void glGetInteger64i_v_Hook(GLenum target, GLuint index, GLint64* data); + void glGetBufferParameteri64v_Hook(GLenum target, GLenum pname, GLint64* params); + void glFramebufferTexture_Hook(GLenum target, GLenum attachment, GLuint texture, GLint level); + + // GL_VERSION_3_3 + void glVertexAttribDivisor_Hook(GLuint index, GLuint divisor); + + // GL_VERSION_4_0 + void glMinSampleShading_Hook(GLclampf value); + void glBlendEquationi_Hook(GLuint buf, GLenum mode); + void glBlendEquationSeparatei_Hook(GLuint buf, GLenum modeRGB, GLenum modeAlpha); + void glBlendFunci_Hook(GLuint buf, GLenum src, GLenum dst); + void glBlendFuncSeparatei_Hook( + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha); + + // GL_AMD_debug_output + void glDebugMessageEnableAMD_Hook( + GLenum category, + GLenum severity, + GLsizei count, + const GLuint* ids, + GLboolean enabled); + void glDebugMessageInsertAMD_Hook( + GLenum category, + GLenum severity, + GLuint id, + GLsizei length, + const GLchar* buf); + void glDebugMessageCallbackAMD_Hook(GLDEBUGPROCAMD callback, GLvoid* userParam); + GLuint glGetDebugMessageLogAMD_Hook( + GLuint count, + GLsizei bufsize, + GLenum* categories, + GLuint* severities, + GLuint* ids, + GLsizei* lengths, + GLchar* message); + +#if defined(GLE_CGL_ENABLED) + // GL_APPLE_element_array + void glElementPointerAPPLE_Hook(GLenum type, const GLvoid* pointer); + void glDrawElementArrayAPPLE_Hook(GLenum mode, GLint first, GLsizei count); + void glDrawRangeElementArrayAPPLE_Hook( + GLenum mode, + GLuint start, + GLuint end, + GLint first, + GLsizei count); + void glMultiDrawElementArrayAPPLE_Hook( + GLenum mode, + const GLint* first, + const GLsizei* count, + GLsizei primcount); + void glMultiDrawRangeElementArrayAPPLE_Hook( + GLenum mode, + GLuint start, + GLuint end, + const GLint* first, + const GLsizei* count, + GLsizei primcount); + + // GL_APPLE_fence + void glGenFencesAPPLE_Hook(GLsizei n, GLuint* fences); + void glDeleteFencesAPPLE_Hook(GLsizei n, const GLuint* fences); + void glSetFenceAPPLE_Hook(GLuint fence); + GLboolean glIsFenceAPPLE_Hook(GLuint fence); + GLboolean glTestFenceAPPLE_Hook(GLuint fence); + void glFinishFenceAPPLE_Hook(GLuint fence); + GLboolean glTestObjectAPPLE_Hook(GLenum object, GLuint name); + void glFinishObjectAPPLE_Hook(GLenum object, GLint name); + + // GL_APPLE_flush_buffer_range + void glBufferParameteriAPPLE_Hook(GLenum target, GLenum pname, GLint param); + void glFlushMappedBufferRangeAPPLE_Hook(GLenum target, GLintptr offset, GLsizeiptr size); + + // GL_APPLE_object_purgeable + GLenum glObjectPurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option); + GLenum glObjectUnpurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option); + void + glGetObjectParameterivAPPLE_Hook(GLenum objectType, GLuint name, GLenum pname, GLint* params); + + // GL_APPLE_texture_range + void glTextureRangeAPPLE_Hook(GLenum target, GLsizei length, const GLvoid* pointer); + void glGetTexParameterPointervAPPLE_Hook(GLenum target, GLenum pname, GLvoid** params); + + // GL_APPLE_vertex_array_object + void glBindVertexArrayAPPLE_Hook(GLuint array); + void glDeleteVertexArraysAPPLE_Hook(GLsizei n, const GLuint* arrays); + void glGenVertexArraysAPPLE_Hook(GLsizei n, GLuint* arrays); + GLboolean glIsVertexArrayAPPLE_Hook(GLuint array); + + // GL_APPLE_vertex_array_range + void glVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid* pointer); + void glFlushVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid* pointer); + void glVertexArrayParameteriAPPLE_Hook(GLenum pname, GLint param); + + // GL_APPLE_vertex_program_evaluators + void glEnableVertexAttribAPPLE_Hook(GLuint index, GLenum pname); + void glDisableVertexAttribAPPLE_Hook(GLuint index, GLenum pname); + GLboolean glIsVertexAttribEnabledAPPLE_Hook(GLuint index, GLenum pname); + void glMapVertexAttrib1dAPPLE_Hook( + GLuint index, + GLuint size, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble* points); + void glMapVertexAttrib1fAPPLE_Hook( + GLuint index, + GLuint size, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat* points); + void glMapVertexAttrib2dAPPLE_Hook( + GLuint index, + GLuint size, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble* points); + void glMapVertexAttrib2fAPPLE_Hook( + GLuint index, + GLuint size, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat* points); +#endif // GLE_CGL_ENABLED + + // GL_ARB_copy_buffer + void glCopyBufferSubData_Hook( + GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size); + + // GL_ARB_debug_output + void glDebugMessageControlARB_Hook( + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint* ids, + GLboolean enabled); + void glDebugMessageInsertARB_Hook( + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* buf); + void glDebugMessageCallbackARB_Hook(GLDEBUGPROCARB callback, const GLvoid* userParam); + GLuint glGetDebugMessageLogARB_Hook( + GLuint count, + GLsizei bufsize, + GLenum* sources, + GLenum* types, + GLuint* ids, + GLenum* severities, + GLsizei* lengths, + GLchar* messageLog); + + // GL_ARB_ES2_compatibility + void glReleaseShaderCompiler_Hook(); + void glShaderBinary_Hook( + GLsizei count, + const GLuint* shaders, + GLenum binaryformat, + const GLvoid* binary, + GLsizei length); + void glGetShaderPrecisionFormat_Hook( + GLenum shadertype, + GLenum precisiontype, + GLint* range, + GLint* precision); + void glDepthRangef_Hook(GLclampf n, GLclampf f); + void glClearDepthf_Hook(GLclampf d); + + // GL_ARB_framebuffer_object + GLboolean glIsRenderbuffer_Hook(GLuint renderbuffer); + void glBindRenderbuffer_Hook(GLenum target, GLuint renderbuffer); + void glDeleteRenderbuffers_Hook(GLsizei n, const GLuint* renderbuffers); + void glGenRenderbuffers_Hook(GLsizei n, GLuint* renderbuffers); + void + glRenderbufferStorage_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + void glGetRenderbufferParameteriv_Hook(GLenum target, GLenum pname, GLint* params); + GLboolean glIsFramebuffer_Hook(GLuint framebuffer); + void glBindFramebuffer_Hook(GLenum target, GLuint framebuffer); + void glDeleteFramebuffers_Hook(GLsizei n, const GLuint* framebuffers); + void glGenFramebuffers_Hook(GLsizei n, GLuint* framebuffers); + GLenum glCheckFramebufferStatus_Hook(GLenum target); + void glFramebufferTexture1D_Hook( + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level); + void glFramebufferTexture2D_Hook( + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level); + void glFramebufferTexture3D_Hook( + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level, + GLint zoffset); + void glFramebufferRenderbuffer_Hook( + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer); + void glGetFramebufferAttachmentParameteriv_Hook( + GLenum target, + GLenum attachment, + GLenum pname, + GLint* params); + void glGenerateMipmap_Hook(GLenum target); + void glBlitFramebuffer_Hook( + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); + void glRenderbufferStorageMultisample_Hook( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + void glFramebufferTextureLayer_Hook( + GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer); + + // GL_ARB_texture_multisample + void glTexImage2DMultisample_Hook( + GLenum target, + GLsizei samples, + GLint internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); + void glTexImage3DMultisample_Hook( + GLenum target, + GLsizei samples, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + void glGetMultisamplefv_Hook(GLenum pname, GLuint index, GLfloat* val); + void glSampleMaski_Hook(GLuint index, GLbitfield mask); + + // GL_ARB_texture_storage + void glTexStorage1D_Hook(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); + void glTexStorage2D_Hook( + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); + void glTexStorage3D_Hook( + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + void glTextureStorage1DEXT_Hook( + GLuint texture, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width); + void glTextureStorage2DEXT_Hook( + GLuint texture, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); + void glTextureStorage3DEXT_Hook( + GLuint texture, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + + // GL_ARB_texture_storage_multisample + void glTexStorage2DMultisample_Hook( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); + void glTexStorage3DMultisample_Hook( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + void glTextureStorage2DMultisampleEXT_Hook( + GLuint texture, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); + void glTextureStorage3DMultisampleEXT_Hook( + GLuint texture, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + + // GL_ARB_timer_query + void glQueryCounter_Hook(GLuint id, GLenum target); + void glGetQueryObjecti64v_Hook(GLuint id, GLenum pname, GLint64* params); + void glGetQueryObjectui64v_Hook(GLuint id, GLenum pname, GLuint64* params); + + // GL_ARB_vertex_array_object + void glBindVertexArray_Hook(GLuint array); + void glDeleteVertexArrays_Hook(GLsizei n, const GLuint* arrays); + void glGenVertexArrays_Hook(GLsizei n, GLuint* arrays); + GLboolean glIsVertexArray_Hook(GLuint array); + + // GL_EXT_draw_buffers2 + void glColorMaskIndexedEXT_Hook(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); + void glGetBooleanIndexedvEXT_Hook(GLenum target, GLuint index, GLboolean* data); + void glGetIntegerIndexedvEXT_Hook(GLenum target, GLuint index, GLint* data); + void glEnableIndexedEXT_Hook(GLenum target, GLuint index); + void glDisableIndexedEXT_Hook(GLenum target, GLuint index); + GLboolean glIsEnabledIndexedEXT_Hook(GLenum target, GLuint index); + + // GL_KHR_debug + void glDebugMessageControl_Hook( + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint* ids, + GLboolean enabled); + void glDebugMessageInsert_Hook( + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const char* buf); + void glDebugMessageCallback_Hook(GLDEBUGPROC callback, const void* userParam); + GLuint glGetDebugMessageLog_Hook( + GLuint count, + GLsizei bufSize, + GLenum* sources, + GLenum* types, + GLuint* ids, + GLenum* severities, + GLsizei* lengths, + char* messageLog); + void glPushDebugGroup_Hook(GLenum source, GLuint id, GLsizei length, const char* message); + void glPopDebugGroup_Hook(void); + void glObjectLabel_Hook(GLenum identifier, GLuint name, GLsizei length, const char* label); + void glGetObjectLabel_Hook( + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei* length, + char* label); + void glObjectPtrLabel_Hook(void* ptr, GLsizei length, const char* label); + void glGetObjectPtrLabel_Hook(void* ptr, GLsizei bufSize, GLsizei* length, char* label); + + // GL_WIN_swap_hint + void glAddSwapHintRectWIN_Hook(GLint x, GLint y, GLsizei width, GLsizei height); + +#if defined(GLE_WGL_ENABLED) + void PostWGLHook(const char* functionName); + + // WGL + /* Hooking of these is currently disabled. + BOOL wglCopyContext_Hook(HGLRC, HGLRC, UINT); + HGLRC wglCreateContext_Hook(HDC); + HGLRC wglCreateLayerContext_Hook(HDC, int); + BOOL wglDeleteContext_Hook(HGLRC); + HGLRC wglGetCurrentContext_Hook(VOID); + HDC wglGetCurrentDC_Hook(VOID); + PROC wglGetProcAddress_Hook(LPCSTR); + BOOL wglMakeCurrent_Hook(HDC, HGLRC); + BOOL wglShareLists_Hook(HGLRC, HGLRC); + BOOL wglUseFontBitmapsA_Hook(HDC, DWORD, DWORD, DWORD); + BOOL wglUseFontBitmapsW_Hook(HDC, DWORD, DWORD, DWORD); + BOOL wglUseFontOutlinesA_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); + BOOL wglUseFontOutlinesW_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); + BOOL wglDescribeLayerPlane_Hook(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR); + int wglSetLayerPaletteEntries_Hook(HDC, int, int, int, CONST COLORREF *); + int wglGetLayerPaletteEntries_Hook(HDC, int, int, int, COLORREF *); + BOOL wglRealizeLayerPalette_Hook(HDC, int, BOOL); + BOOL wglSwapLayerBuffers_Hook(HDC, UINT); + DWORD wglSwapMultipleBuffers_Hook(UINT, CONST WGLSWAP *); + */ + + // WGL_ARB_buffer_region + HANDLE wglCreateBufferRegionARB_Hook(HDC hDC, int iLayerPlane, UINT uType); + VOID wglDeleteBufferRegionARB_Hook(HANDLE hRegion); + BOOL wglSaveBufferRegionARB_Hook(HANDLE hRegion, int x, int y, int width, int height); + BOOL wglRestoreBufferRegionARB_Hook( + HANDLE hRegion, + int x, + int y, + int width, + int height, + int xSrc, + int ySrc); + + // WGL_ARB_extensions_string + const char* wglGetExtensionsStringARB_Hook(HDC hdc); + + // WGL_ARB_pixel_format + BOOL wglGetPixelFormatAttribivARB_Hook( + HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int* piAttributes, + int* piValues); + BOOL wglGetPixelFormatAttribfvARB_Hook( + HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int* piAttributes, + FLOAT* pfValues); + BOOL wglChoosePixelFormatARB_Hook( + HDC hdc, + const int* piAttribIList, + const FLOAT* pfAttribFList, + UINT nMaxFormats, + int* piFormats, + UINT* nNumFormats); + + // WGL_ARB_make_current_read + BOOL wglMakeContextCurrentARB_Hook(HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + HDC wglGetCurrentReadDCARB_Hook(void); + + // WGL_ARB_pbuffer + HPBUFFERARB wglCreatePbufferARB_Hook( + HDC hDC, + int iPixelFormat, + int iWidth, + int iHeight, + const int* piAttribList); + HDC wglGetPbufferDCARB_Hook(HPBUFFERARB hPbuffer); + int wglReleasePbufferDCARB_Hook(HPBUFFERARB hPbuffer, HDC hDC); + BOOL wglDestroyPbufferARB_Hook(HPBUFFERARB hPbuffer); + BOOL wglQueryPbufferARB_Hook(HPBUFFERARB hPbuffer, int iAttribute, int* piValue); + + // WGL_ARB_render_texture + BOOL wglBindTexImageARB_Hook(HPBUFFERARB hPbuffer, int iBuffer); + BOOL wglReleaseTexImageARB_Hook(HPBUFFERARB hPbuffer, int iBuffer); + BOOL wglSetPbufferAttribARB_Hook(HPBUFFERARB hPbuffer, const int* piAttribList); + + // WGL_NV_present_video + int wglEnumerateVideoDevicesNV_Hook(HDC hDC, HVIDEOOUTPUTDEVICENV* phDeviceList); + BOOL wglBindVideoDeviceNV_Hook( + HDC hDC, + unsigned int uVideoSlot, + HVIDEOOUTPUTDEVICENV hVideoDevice, + const int* piAttribList); + BOOL wglQueryCurrentContextNV_Hook(int iAttribute, int* piValue); + + // WGL_ARB_create_context + HGLRC wglCreateContextAttribsARB_Hook(HDC hDC, HGLRC hShareContext, const int* attribList); + + // WGL_EXT_extensions_string + const char* wglGetExtensionsStringEXT_Hook(); + + // WGL_EXT_swap_control + BOOL wglSwapIntervalEXT_Hook(int interval); + int wglGetSwapIntervalEXT_Hook(); + + // WGL_OML_sync_control + BOOL wglGetSyncValuesOML_Hook(HDC hdc, INT64* ust, INT64* msc, INT64* sbc); + BOOL wglGetMscRateOML_Hook(HDC hdc, INT32* numerator, INT32* denominator); + INT64 wglSwapBuffersMscOML_Hook(HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); + INT64 wglSwapLayerBuffersMscOML_Hook( + HDC hdc, + int fuPlanes, + INT64 target_msc, + INT64 divisor, + INT64 remainder); + BOOL wglWaitForMscOML_Hook( + HDC hdc, + INT64 target_msc, + INT64 divisor, + INT64 remainder, + INT64* ust, + INT64* msc, + INT64* sbc); + BOOL wglWaitForSbcOML_Hook(HDC hdc, INT64 target_sbc, INT64* ust, INT64* msc, INT64* sbc); + + // WGL_NV_video_output + BOOL wglGetVideoDeviceNV_Hook(HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice); + BOOL wglReleaseVideoDeviceNV_Hook(HPVIDEODEV hVideoDevice); + BOOL wglBindVideoImageNV_Hook(HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); + BOOL wglReleaseVideoImageNV_Hook(HPBUFFERARB hPbuffer, int iVideoBuffer); + BOOL wglSendPbufferToVideoNV_Hook( + HPBUFFERARB hPbuffer, + int iBufferType, + unsigned long* pulCounterPbuffer, + BOOL bBlock); + BOOL wglGetVideoInfoNV_Hook( + HPVIDEODEV hpVideoDevice, + unsigned long* pulCounterOutputPbuffer, + unsigned long* pulCounterOutputVideo); + + // WGL_NV_swap_group + BOOL wglJoinSwapGroupNV_Hook(HDC hDC, GLuint group); + BOOL wglBindSwapBarrierNV_Hook(GLuint group, GLuint barrier); + BOOL wglQuerySwapGroupNV_Hook(HDC hDC, GLuint* group, GLuint* barrier); + BOOL wglQueryMaxSwapGroupsNV_Hook(HDC hDC, GLuint* maxGroups, GLuint* maxBarriers); + BOOL wglQueryFrameCountNV_Hook(HDC hDC, GLuint* count); + BOOL wglResetFrameCountNV_Hook(HDC hDC); + + // WGL_NV_video_capture + BOOL wglBindVideoCaptureDeviceNV_Hook(UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); + UINT wglEnumerateVideoCaptureDevicesNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV* phDeviceList); + BOOL wglLockVideoCaptureDeviceNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV hDevice); + BOOL wglQueryVideoCaptureDeviceNV_Hook( + HDC hDc, + HVIDEOINPUTDEVICENV hDevice, + int iAttribute, + int* piValue); + BOOL wglReleaseVideoCaptureDeviceNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV hDevice); + + // WGL_NV_copy_image + BOOL wglCopyImageSubDataNV_Hook( + HGLRC hSrcRC, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + HGLRC hDstRC, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei width, + GLsizei height, + GLsizei depth); + + // WGL_NV_DX_interop + BOOL wglDXSetResourceShareHandleNV_Hook(void* dxObject, HANDLE shareHandle); + HANDLE wglDXOpenDeviceNV_Hook(void* dxDevice); + BOOL wglDXCloseDeviceNV_Hook(HANDLE hDevice); + HANDLE wglDXRegisterObjectNV_Hook( + HANDLE hDevice, + void* dxObject, + GLuint name, + GLenum type, + GLenum access); + BOOL wglDXUnregisterObjectNV_Hook(HANDLE hDevice, HANDLE hObject); + BOOL wglDXObjectAccessNV_Hook(HANDLE hObject, GLenum access); + BOOL wglDXLockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE* hObjects); + BOOL wglDXUnlockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE* hObjects); +#endif // GLE_WGL_ENABLED + +#if defined(GLE_GLX_ENABLED) + void PostGLXHook(const char* functionName); + + // GLX_VERSION_1_0 + // GLX_VERSION_1_1 + // We don't currently do hooking of these. + + // GLX_VERSION_1_2 + ::Display* glXGetCurrentDisplay_Hook(void); + + // GLX_VERSION_1_3 + GLXFBConfig* + glXChooseFBConfig_Hook(::Display* dpy, int screen, const int* attrib_list, int* nelements); + GLXContext glXCreateNewContext_Hook( + ::Display* dpy, + GLXFBConfig config, + int render_type, + GLXContext share_list, + Bool direct); + GLXPbuffer glXCreatePbuffer_Hook(::Display* dpy, GLXFBConfig config, const int* attrib_list); + GLXPixmap + glXCreatePixmap_Hook(::Display* dpy, GLXFBConfig config, Pixmap pixmap, const int* attrib_list); + GLXWindow + glXCreateWindow_Hook(::Display* dpy, GLXFBConfig config, Window win, const int* attrib_list); + void glXDestroyPbuffer_Hook(::Display* dpy, GLXPbuffer pbuf); + void glXDestroyPixmap_Hook(::Display* dpy, GLXPixmap pixmap); + void glXDestroyWindow_Hook(::Display* dpy, GLXWindow win); + GLXDrawable glXGetCurrentReadDrawable_Hook(void); + int glXGetFBConfigAttrib_Hook(::Display* dpy, GLXFBConfig config, int attribute, int* value); + GLXFBConfig* glXGetFBConfigs_Hook(::Display* dpy, int screen, int* nelements); + void glXGetSelectedEvent_Hook(::Display* dpy, GLXDrawable draw, unsigned long* event_mask); + XVisualInfo* glXGetVisualFromFBConfig_Hook(::Display* dpy, GLXFBConfig config); + Bool glXMakeContextCurrent_Hook( + ::Display* display, + GLXDrawable draw, + GLXDrawable read, + GLXContext ctx); + int glXQueryContext_Hook(::Display* dpy, GLXContext ctx, int attribute, int* value); + void glXQueryDrawable_Hook(::Display* dpy, GLXDrawable draw, int attribute, unsigned int* value); + void glXSelectEvent_Hook(::Display* dpy, GLXDrawable draw, unsigned long event_mask); + + // GLX_VERSION_1_4 + // We don't do hooking of this. + + // GLX_ARB_create_context + GLXContext glXCreateContextAttribsARB_Hook( + Display* dpy, + GLXFBConfig config, + GLXContext share_context, + Bool direct, + const int* attrib_list); + + // GLX_EXT_swap_control + void glXSwapIntervalEXT_Hook(::Display* dpy, GLXDrawable drawable, int interval); + + // GLX_OML_sync_control + Bool glXGetMscRateOML_Hook( + ::Display* dpy, + GLXDrawable drawable, + int32_t* numerator, + int32_t* denominator); + Bool glXGetSyncValuesOML_Hook( + ::Display* dpy, + GLXDrawable drawable, + int64_t* ust, + int64_t* msc, + int64_t* sbc); + int64_t glXSwapBuffersMscOML_Hook( + ::Display* dpy, + GLXDrawable drawable, + int64_t target_msc, + int64_t divisor, + int64_t remainder); + Bool glXWaitForMscOML_Hook( + ::Display* dpy, + GLXDrawable drawable, + int64_t target_msc, + int64_t divisor, + int64_t remainder, + int64_t* ust, + int64_t* msc, + int64_t* sbc); + Bool glXWaitForSbcOML_Hook( + ::Display* dpy, + GLXDrawable drawable, + int64_t target_sbc, + int64_t* ust, + int64_t* msc, + int64_t* sbc); + + // GLX_MESA_swap_control + int glXGetSwapIntervalMESA_Hook(); + int glXSwapIntervalMESA_Hook(unsigned int interval); + +#endif // GLE_GLX_ENABLED + +#endif // #if defined(GLE_HOOKING_ENABLED) + + // GL_VERSION_1_1 + // These are not represented by function pointers. + + // GL_VERSION_1_2 + PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D_Impl; + PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements_Impl; + PFNGLTEXIMAGE3DPROC glTexImage3D_Impl; + PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D_Impl; + + // GL_VERSION_1_2 deprecated functions + /* Not currently supported + PFNGLCOLORTABLEPROC glColorTable_Impl; + PFNGLCOLORTABLEPARAMETERFVPROC glColorTableParameterfv_Impl; + PFNGLCOLORTABLEPARAMETERIVPROC glColorTableParameteriv_Impl; + PFNGLCOPYCOLORTABLEPROC glCopyColorTable_Impl; + PFNGLGETCOLORTABLEPROC glGetColorTable_Impl; + PFNGLGETCOLORTABLEPARAMETERFVPROC glGetColorTableParameterfv_Impl; + PFNGLGETCOLORTABLEPARAMETERIVPROC glGetColorTableParameteriv_Impl; + PFNGLCOLORSUBTABLEPROC glColorSubTable_Impl; + PFNGLCOPYCOLORSUBTABLEPROC glCopyColorSubTable_Impl; + PFNGLCONVOLUTIONFILTER1DPROC glConvolutionFilter1D_Impl; + PFNGLCONVOLUTIONFILTER2DPROC glConvolutionFilter2D_Impl; + PFNGLCONVOLUTIONPARAMETERFPROC glConvolutionParameterf_Impl; + PFNGLCONVOLUTIONPARAMETERFVPROC glConvolutionParameterfv_Impl; + PFNGLCONVOLUTIONPARAMETERIPROC glConvolutionParameteri_Impl; + PFNGLCONVOLUTIONPARAMETERIVPROC glConvolutionParameteriv_Impl; + PFNGLCOPYCONVOLUTIONFILTER1DPROC glCopyConvolutionFilter1D_Impl; + PFNGLCOPYCONVOLUTIONFILTER2DPROC glCopyConvolutionFilter2D_Impl; + PFNGLGETCONVOLUTIONFILTERPROC glGetConvolutionFilter_Impl; + PFNGLGETCONVOLUTIONPARAMETERFVPROC glGetConvolutionParameterfv_Impl; + PFNGLGETCONVOLUTIONPARAMETERIVPROC glGetConvolutionParameteriv_Impl; + PFNGLGETSEPARABLEFILTERPROC glGetSeparableFilter_Impl; + PFNGLSEPARABLEFILTER2DPROC glSeparableFilter2D_Impl; + PFNGLGETHISTOGRAMPROC glGetHistogram_Impl; + PFNGLGETHISTOGRAMPARAMETERFVPROC glGetHistogramParameterfv_Impl; + PFNGLGETHISTOGRAMPARAMETERIVPROC glGetHistogramParameteriv_Impl; + PFNGLGETMINMAXPROC glGetMinmax_Impl; + PFNGLGETMINMAXPARAMETERFVPROC glGetMinmaxParameterfv_Impl; + PFNGLGETMINMAXPARAMETERIVPROC glGetMinmaxParameteriv_Impl; + PFNGLHISTOGRAMPROC glHistogram_Impl; + PFNGLMINMAXPROC glMinmax_Impl; + PFNGLRESETHISTOGRAMPROC glResetHistogram_Impl; + PFNGLRESETMINMAXPROC glResetMinmax_Impl; + */ + + // GL_VERSION_1_3 + PFNGLACTIVETEXTUREPROC glActiveTexture_Impl; + PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture_Impl; + PFNGLCOMPRESSEDTEXIMAGE1DPROC glCompressedTexImage1D_Impl; + PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D_Impl; + PFNGLCOMPRESSEDTEXIMAGE3DPROC glCompressedTexImage3D_Impl; + PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glCompressedTexSubImage1D_Impl; + PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D_Impl; + PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D_Impl; + PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage_Impl; + PFNGLLOADTRANSPOSEMATRIXDPROC glLoadTransposeMatrixd_Impl; + PFNGLLOADTRANSPOSEMATRIXFPROC glLoadTransposeMatrixf_Impl; + PFNGLMULTTRANSPOSEMATRIXDPROC glMultTransposeMatrixd_Impl; + PFNGLMULTTRANSPOSEMATRIXFPROC glMultTransposeMatrixf_Impl; + PFNGLMULTITEXCOORD1DPROC glMultiTexCoord1d_Impl; + PFNGLMULTITEXCOORD1DVPROC glMultiTexCoord1dv_Impl; + PFNGLMULTITEXCOORD1FPROC glMultiTexCoord1f_Impl; + PFNGLMULTITEXCOORD1FVPROC glMultiTexCoord1fv_Impl; + PFNGLMULTITEXCOORD1IPROC glMultiTexCoord1i_Impl; + PFNGLMULTITEXCOORD1IVPROC glMultiTexCoord1iv_Impl; + PFNGLMULTITEXCOORD1SPROC glMultiTexCoord1s_Impl; + PFNGLMULTITEXCOORD1SVPROC glMultiTexCoord1sv_Impl; + PFNGLMULTITEXCOORD2DPROC glMultiTexCoord2d_Impl; + PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv_Impl; + PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f_Impl; + PFNGLMULTITEXCOORD2FVPROC glMultiTexCoord2fv_Impl; + PFNGLMULTITEXCOORD2IPROC glMultiTexCoord2i_Impl; + PFNGLMULTITEXCOORD2IVPROC glMultiTexCoord2iv_Impl; + PFNGLMULTITEXCOORD2SPROC glMultiTexCoord2s_Impl; + PFNGLMULTITEXCOORD2SVPROC glMultiTexCoord2sv_Impl; + PFNGLMULTITEXCOORD3DPROC glMultiTexCoord3d_Impl; + PFNGLMULTITEXCOORD3DVPROC glMultiTexCoord3dv_Impl; + PFNGLMULTITEXCOORD3FPROC glMultiTexCoord3f_Impl; + PFNGLMULTITEXCOORD3FVPROC glMultiTexCoord3fv_Impl; + PFNGLMULTITEXCOORD3IPROC glMultiTexCoord3i_Impl; + PFNGLMULTITEXCOORD3IVPROC glMultiTexCoord3iv_Impl; + PFNGLMULTITEXCOORD3SPROC glMultiTexCoord3s_Impl; + PFNGLMULTITEXCOORD3SVPROC glMultiTexCoord3sv_Impl; + PFNGLMULTITEXCOORD4DPROC glMultiTexCoord4d_Impl; + PFNGLMULTITEXCOORD4DVPROC glMultiTexCoord4dv_Impl; + PFNGLMULTITEXCOORD4FPROC glMultiTexCoord4f_Impl; + PFNGLMULTITEXCOORD4FVPROC glMultiTexCoord4fv_Impl; + PFNGLMULTITEXCOORD4IPROC glMultiTexCoord4i_Impl; + PFNGLMULTITEXCOORD4IVPROC glMultiTexCoord4iv_Impl; + PFNGLMULTITEXCOORD4SPROC glMultiTexCoord4s_Impl; + PFNGLMULTITEXCOORD4SVPROC glMultiTexCoord4sv_Impl; + PFNGLSAMPLECOVERAGEPROC glSampleCoverage_Impl; + + // GL_VERSION_1_4 + PFNGLBLENDCOLORPROC glBlendColor_Impl; + PFNGLBLENDEQUATIONPROC glBlendEquation_Impl; + PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate_Impl; + PFNGLFOGCOORDPOINTERPROC glFogCoordPointer_Impl; + PFNGLFOGCOORDDPROC glFogCoordd_Impl; + PFNGLFOGCOORDDVPROC glFogCoorddv_Impl; + PFNGLFOGCOORDFPROC glFogCoordf_Impl; + PFNGLFOGCOORDFVPROC glFogCoordfv_Impl; + PFNGLMULTIDRAWARRAYSPROC glMultiDrawArrays_Impl; + PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements_Impl; + PFNGLPOINTPARAMETERFPROC glPointParameterf_Impl; + PFNGLPOINTPARAMETERFVPROC glPointParameterfv_Impl; + PFNGLPOINTPARAMETERIPROC glPointParameteri_Impl; + PFNGLPOINTPARAMETERIVPROC glPointParameteriv_Impl; + PFNGLSECONDARYCOLOR3BPROC glSecondaryColor3b_Impl; + PFNGLSECONDARYCOLOR3BVPROC glSecondaryColor3bv_Impl; + PFNGLSECONDARYCOLOR3DPROC glSecondaryColor3d_Impl; + PFNGLSECONDARYCOLOR3DVPROC glSecondaryColor3dv_Impl; + PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f_Impl; + PFNGLSECONDARYCOLOR3FVPROC glSecondaryColor3fv_Impl; + PFNGLSECONDARYCOLOR3IPROC glSecondaryColor3i_Impl; + PFNGLSECONDARYCOLOR3IVPROC glSecondaryColor3iv_Impl; + PFNGLSECONDARYCOLOR3SPROC glSecondaryColor3s_Impl; + PFNGLSECONDARYCOLOR3SVPROC glSecondaryColor3sv_Impl; + PFNGLSECONDARYCOLOR3UBPROC glSecondaryColor3ub_Impl; + PFNGLSECONDARYCOLOR3UBVPROC glSecondaryColor3ubv_Impl; + PFNGLSECONDARYCOLOR3UIPROC glSecondaryColor3ui_Impl; + PFNGLSECONDARYCOLOR3UIVPROC glSecondaryColor3uiv_Impl; + PFNGLSECONDARYCOLOR3USPROC glSecondaryColor3us_Impl; + PFNGLSECONDARYCOLOR3USVPROC glSecondaryColor3usv_Impl; + PFNGLSECONDARYCOLORPOINTERPROC glSecondaryColorPointer_Impl; + PFNGLWINDOWPOS2DPROC glWindowPos2d_Impl; + PFNGLWINDOWPOS2DVPROC glWindowPos2dv_Impl; + PFNGLWINDOWPOS2FPROC glWindowPos2f_Impl; + PFNGLWINDOWPOS2FVPROC glWindowPos2fv_Impl; + PFNGLWINDOWPOS2IPROC glWindowPos2i_Impl; + PFNGLWINDOWPOS2IVPROC glWindowPos2iv_Impl; + PFNGLWINDOWPOS2SPROC glWindowPos2s_Impl; + PFNGLWINDOWPOS2SVPROC glWindowPos2sv_Impl; + PFNGLWINDOWPOS3DPROC glWindowPos3d_Impl; + PFNGLWINDOWPOS3DVPROC glWindowPos3dv_Impl; + PFNGLWINDOWPOS3FPROC glWindowPos3f_Impl; + PFNGLWINDOWPOS3FVPROC glWindowPos3fv_Impl; + PFNGLWINDOWPOS3IPROC glWindowPos3i_Impl; + PFNGLWINDOWPOS3IVPROC glWindowPos3iv_Impl; + PFNGLWINDOWPOS3SPROC glWindowPos3s_Impl; + PFNGLWINDOWPOS3SVPROC glWindowPos3sv_Impl; + + // GL_VERSION_1_5 + PFNGLBEGINQUERYPROC glBeginQuery_Impl; + PFNGLBINDBUFFERPROC glBindBuffer_Impl; + PFNGLBUFFERDATAPROC glBufferData_Impl; + PFNGLBUFFERSUBDATAPROC glBufferSubData_Impl; + PFNGLDELETEBUFFERSPROC glDeleteBuffers_Impl; + PFNGLDELETEQUERIESPROC glDeleteQueries_Impl; + PFNGLENDQUERYPROC glEndQuery_Impl; + PFNGLGENBUFFERSPROC glGenBuffers_Impl; + PFNGLGENQUERIESPROC glGenQueries_Impl; + PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv_Impl; + PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv_Impl; + PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData_Impl; + PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv_Impl; + PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv_Impl; + PFNGLGETQUERYIVPROC glGetQueryiv_Impl; + PFNGLISBUFFERPROC glIsBuffer_Impl; + PFNGLISQUERYPROC glIsQuery_Impl; + PFNGLMAPBUFFERPROC glMapBuffer_Impl; + PFNGLUNMAPBUFFERPROC glUnmapBuffer_Impl; + + // GL_VERSION_2_0 + PFNGLATTACHSHADERPROC glAttachShader_Impl; + PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation_Impl; + PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate_Impl; + PFNGLCOMPILESHADERPROC glCompileShader_Impl; + PFNGLCREATEPROGRAMPROC glCreateProgram_Impl; + PFNGLCREATESHADERPROC glCreateShader_Impl; + PFNGLDELETEPROGRAMPROC glDeleteProgram_Impl; + PFNGLDELETESHADERPROC glDeleteShader_Impl; + PFNGLDETACHSHADERPROC glDetachShader_Impl; + PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray_Impl; + PFNGLDRAWBUFFERSPROC glDrawBuffers_Impl; + PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray_Impl; + PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib_Impl; + PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform_Impl; + PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders_Impl; + PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation_Impl; + PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog_Impl; + PFNGLGETPROGRAMIVPROC glGetProgramiv_Impl; + PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog_Impl; + PFNGLGETSHADERSOURCEPROC glGetShaderSource_Impl; + PFNGLGETSHADERIVPROC glGetShaderiv_Impl; + PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_Impl; + PFNGLGETUNIFORMFVPROC glGetUniformfv_Impl; + PFNGLGETUNIFORMIVPROC glGetUniformiv_Impl; + PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv_Impl; + PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv_Impl; + PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv_Impl; + PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv_Impl; + PFNGLISPROGRAMPROC glIsProgram_Impl; + PFNGLISSHADERPROC glIsShader_Impl; + PFNGLLINKPROGRAMPROC glLinkProgram_Impl; + PFNGLSHADERSOURCEPROC glShaderSource_Impl; + PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate_Impl; + PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate_Impl; + PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate_Impl; + PFNGLUNIFORM1FPROC glUniform1f_Impl; + PFNGLUNIFORM1FVPROC glUniform1fv_Impl; + PFNGLUNIFORM1IPROC glUniform1i_Impl; + PFNGLUNIFORM1IVPROC glUniform1iv_Impl; + PFNGLUNIFORM2FPROC glUniform2f_Impl; + PFNGLUNIFORM2FVPROC glUniform2fv_Impl; + PFNGLUNIFORM2IPROC glUniform2i_Impl; + PFNGLUNIFORM2IVPROC glUniform2iv_Impl; + PFNGLUNIFORM3FPROC glUniform3f_Impl; + PFNGLUNIFORM3FVPROC glUniform3fv_Impl; + PFNGLUNIFORM3IPROC glUniform3i_Impl; + PFNGLUNIFORM3IVPROC glUniform3iv_Impl; + PFNGLUNIFORM4FPROC glUniform4f_Impl; + PFNGLUNIFORM4FVPROC glUniform4fv_Impl; + PFNGLUNIFORM4IPROC glUniform4i_Impl; + PFNGLUNIFORM4IVPROC glUniform4iv_Impl; + PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv_Impl; + PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv_Impl; + PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv_Impl; + PFNGLUSEPROGRAMPROC glUseProgram_Impl; + PFNGLVALIDATEPROGRAMPROC glValidateProgram_Impl; + PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d_Impl; + PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv_Impl; + PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_Impl; + PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv_Impl; + PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s_Impl; + PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv_Impl; + PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d_Impl; + PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv_Impl; + PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_Impl; + PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv_Impl; + PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s_Impl; + PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv_Impl; + PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d_Impl; + PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv_Impl; + PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_Impl; + PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv_Impl; + PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s_Impl; + PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv_Impl; + PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv_Impl; + PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv_Impl; + PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4Nsv_Impl; + PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub_Impl; + PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv_Impl; + PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv_Impl; + PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv_Impl; + PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv_Impl; + PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d_Impl; + PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv_Impl; + PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_Impl; + PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv_Impl; + PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv_Impl; + PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s_Impl; + PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv_Impl; + PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv_Impl; + PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv_Impl; + PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv_Impl; + PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer_Impl; + + // GL_VERSION_2_1 + PFNGLUNIFORMMATRIX2X3FVPROC glUniformMatrix2x3fv_Impl; + PFNGLUNIFORMMATRIX2X4FVPROC glUniformMatrix2x4fv_Impl; + PFNGLUNIFORMMATRIX3X2FVPROC glUniformMatrix3x2fv_Impl; + PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv_Impl; + PFNGLUNIFORMMATRIX4X2FVPROC glUniformMatrix4x2fv_Impl; + PFNGLUNIFORMMATRIX4X3FVPROC glUniformMatrix4x3fv_Impl; + + // GL_VERSION_3_0 + PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender_Impl; + PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback_Impl; + PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation_Impl; + PFNGLCLAMPCOLORPROC glClampColor_Impl; + PFNGLCLEARBUFFERFIPROC glClearBufferfi_Impl; + PFNGLCLEARBUFFERFVPROC glClearBufferfv_Impl; + PFNGLCLEARBUFFERIVPROC glClearBufferiv_Impl; + PFNGLCLEARBUFFERUIVPROC glClearBufferuiv_Impl; + PFNGLCOLORMASKIPROC glColorMaski_Impl; + PFNGLDISABLEIPROC glDisablei_Impl; + PFNGLENABLEIPROC glEnablei_Impl; + PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender_Impl; + PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback_Impl; + PFNGLBINDBUFFERRANGEPROC glBindBufferRange_Impl; + PFNGLBINDBUFFERBASEPROC glBindBufferBase_Impl; + PFNGLGETBOOLEANI_VPROC glGetBooleani_v_Impl; + PFNGLGETINTEGERI_VPROC glGetIntegeri_v_Impl; + PFNGLGETFRAGDATALOCATIONPROC glGetFragDataLocation_Impl; + PFNGLGETSTRINGIPROC glGetStringi_Impl; + PFNGLGETTEXPARAMETERIIVPROC glGetTexParameterIiv_Impl; + PFNGLGETTEXPARAMETERIUIVPROC glGetTexParameterIuiv_Impl; + PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glGetTransformFeedbackVarying_Impl; + PFNGLGETUNIFORMUIVPROC glGetUniformuiv_Impl; + PFNGLGETVERTEXATTRIBIIVPROC glGetVertexAttribIiv_Impl; + PFNGLGETVERTEXATTRIBIUIVPROC glGetVertexAttribIuiv_Impl; + PFNGLISENABLEDIPROC glIsEnabledi_Impl; + PFNGLTEXPARAMETERIIVPROC glTexParameterIiv_Impl; + PFNGLTEXPARAMETERIUIVPROC glTexParameterIuiv_Impl; + PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings_Impl; + PFNGLUNIFORM1UIPROC glUniform1ui_Impl; + PFNGLUNIFORM1UIVPROC glUniform1uiv_Impl; + PFNGLUNIFORM2UIPROC glUniform2ui_Impl; + PFNGLUNIFORM2UIVPROC glUniform2uiv_Impl; + PFNGLUNIFORM3UIPROC glUniform3ui_Impl; + PFNGLUNIFORM3UIVPROC glUniform3uiv_Impl; + PFNGLUNIFORM4UIPROC glUniform4ui_Impl; + PFNGLUNIFORM4UIVPROC glUniform4uiv_Impl; + PFNGLVERTEXATTRIBI1IPROC glVertexAttribI1i_Impl; + PFNGLVERTEXATTRIBI1IVPROC glVertexAttribI1iv_Impl; + PFNGLVERTEXATTRIBI1UIPROC glVertexAttribI1ui_Impl; + PFNGLVERTEXATTRIBI1UIVPROC glVertexAttribI1uiv_Impl; + PFNGLVERTEXATTRIBI2IPROC glVertexAttribI2i_Impl; + PFNGLVERTEXATTRIBI2IVPROC glVertexAttribI2iv_Impl; + PFNGLVERTEXATTRIBI2UIPROC glVertexAttribI2ui_Impl; + PFNGLVERTEXATTRIBI2UIVPROC glVertexAttribI2uiv_Impl; + PFNGLVERTEXATTRIBI3IPROC glVertexAttribI3i_Impl; + PFNGLVERTEXATTRIBI3IVPROC glVertexAttribI3iv_Impl; + PFNGLVERTEXATTRIBI3UIPROC glVertexAttribI3ui_Impl; + PFNGLVERTEXATTRIBI3UIVPROC glVertexAttribI3uiv_Impl; + PFNGLVERTEXATTRIBI4BVPROC glVertexAttribI4bv_Impl; + PFNGLVERTEXATTRIBI4IPROC glVertexAttribI4i_Impl; + PFNGLVERTEXATTRIBI4IVPROC glVertexAttribI4iv_Impl; + PFNGLVERTEXATTRIBI4SVPROC glVertexAttribI4sv_Impl; + PFNGLVERTEXATTRIBI4UBVPROC glVertexAttribI4ubv_Impl; + PFNGLVERTEXATTRIBI4UIPROC glVertexAttribI4ui_Impl; + PFNGLVERTEXATTRIBI4UIVPROC glVertexAttribI4uiv_Impl; + PFNGLVERTEXATTRIBI4USVPROC glVertexAttribI4usv_Impl; + PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer_Impl; + + // GL_VERSION_3_1 + PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced_Impl; + PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced_Impl; + PFNGLPRIMITIVERESTARTINDEXPROC glPrimitiveRestartIndex_Impl; + PFNGLTEXBUFFERPROC glTexBuffer_Impl; + + // GL_VERSION_3_2 + PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture_Impl; + PFNGLGETBUFFERPARAMETERI64VPROC glGetBufferParameteri64v_Impl; + PFNGLGETINTEGER64I_VPROC glGetInteger64i_v_Impl; + + // GL_VERSION_3_3 + PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor_Impl; + + // GL_VERSION_4_0 + PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei_Impl; + PFNGLBLENDEQUATIONIPROC glBlendEquationi_Impl; + PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei_Impl; + PFNGLBLENDFUNCIPROC glBlendFunci_Impl; + PFNGLMINSAMPLESHADINGPROC glMinSampleShading_Impl; + + // GL_VERSION_4_2 + PFNGLMEMORYBARRIER glMemoryBarrier_Impl; + + // GL_VERSION_4_3 + PFNGLDISPATCHCOMPUTEPROC glDispatchCompute_Impl; + PFNGLBINDIMAGETEXTUREPROC glBindImageTexture_Impl; + + // GL_AMD_debug_output + PFNGLDEBUGMESSAGECALLBACKAMDPROC glDebugMessageCallbackAMD_Impl; + PFNGLDEBUGMESSAGEENABLEAMDPROC glDebugMessageEnableAMD_Impl; + PFNGLDEBUGMESSAGEINSERTAMDPROC glDebugMessageInsertAMD_Impl; + PFNGLGETDEBUGMESSAGELOGAMDPROC glGetDebugMessageLogAMD_Impl; + +#if defined(GLE_CGL_ENABLED) + // GL_APPLE_aux_depth_stencil + // (no functions) + + // GL_APPLE_client_storage + // (no functions) + + // GL_APPLE_element_array + PFNGLDRAWELEMENTARRAYAPPLEPROC glDrawElementArrayAPPLE_Impl; + PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glDrawRangeElementArrayAPPLE_Impl; + PFNGLELEMENTPOINTERAPPLEPROC glElementPointerAPPLE_Impl; + PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glMultiDrawElementArrayAPPLE_Impl; + PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glMultiDrawRangeElementArrayAPPLE_Impl; + + // GL_APPLE_fence + PFNGLDELETEFENCESAPPLEPROC glDeleteFencesAPPLE_Impl; + PFNGLFINISHFENCEAPPLEPROC glFinishFenceAPPLE_Impl; + PFNGLFINISHOBJECTAPPLEPROC glFinishObjectAPPLE_Impl; + PFNGLGENFENCESAPPLEPROC glGenFencesAPPLE_Impl; + PFNGLISFENCEAPPLEPROC glIsFenceAPPLE_Impl; + PFNGLSETFENCEAPPLEPROC glSetFenceAPPLE_Impl; + PFNGLTESTFENCEAPPLEPROC glTestFenceAPPLE_Impl; + PFNGLTESTOBJECTAPPLEPROC glTestObjectAPPLE_Impl; + + // GL_APPLE_float_pixels + // (no functions) + + // GL_APPLE_flush_buffer_range + PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE_Impl; + PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE_Impl; + + // GL_APPLE_object_purgeable + PFNGLGETOBJECTPARAMETERIVAPPLEPROC glGetObjectParameterivAPPLE_Impl; + PFNGLOBJECTPURGEABLEAPPLEPROC glObjectPurgeableAPPLE_Impl; + PFNGLOBJECTUNPURGEABLEAPPLEPROC glObjectUnpurgeableAPPLE_Impl; + + // GL_APPLE_pixel_buffer + // (no functions) + + // GL_APPLE_rgb_422 + // (no functions) + + // GL_APPLE_row_bytes + // (no functions) + + // GL_APPLE_specular_vector + // (no functions) + + // GL_APPLE_texture_range + PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glGetTexParameterPointervAPPLE_Impl; + PFNGLTEXTURERANGEAPPLEPROC glTextureRangeAPPLE_Impl; + + // GL_APPLE_transform_hint + // (no functions) + + // GL_APPLE_vertex_array_object + PFNGLBINDVERTEXARRAYAPPLEPROC glBindVertexArrayAPPLE_Impl; + PFNGLDELETEVERTEXARRAYSAPPLEPROC glDeleteVertexArraysAPPLE_Impl; + PFNGLGENVERTEXARRAYSAPPLEPROC glGenVertexArraysAPPLE_Impl; + PFNGLISVERTEXARRAYAPPLEPROC glIsVertexArrayAPPLE_Impl; + + // GL_APPLE_vertex_array_range + PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glFlushVertexArrayRangeAPPLE_Impl; + PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glVertexArrayParameteriAPPLE_Impl; + PFNGLVERTEXARRAYRANGEAPPLEPROC glVertexArrayRangeAPPLE_Impl; + + // GL_APPLE_vertex_program_evaluators + PFNGLDISABLEVERTEXATTRIBAPPLEPROC glDisableVertexAttribAPPLE_Impl; + PFNGLENABLEVERTEXATTRIBAPPLEPROC glEnableVertexAttribAPPLE_Impl; + PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glIsVertexAttribEnabledAPPLE_Impl; + PFNGLMAPVERTEXATTRIB1DAPPLEPROC glMapVertexAttrib1dAPPLE_Impl; + PFNGLMAPVERTEXATTRIB1FAPPLEPROC glMapVertexAttrib1fAPPLE_Impl; + PFNGLMAPVERTEXATTRIB2DAPPLEPROC glMapVertexAttrib2dAPPLE_Impl; + PFNGLMAPVERTEXATTRIB2FAPPLEPROC glMapVertexAttrib2fAPPLE_Impl; +#endif // GLE_CGL_ENABLED + + // GL_ARB_copy_buffer + PFNGLCOPYBUFFERSUBDATAPROC glCopyBufferSubData_Impl; + + // GL_ARB_debug_output + PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB_Impl; + PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB_Impl; + PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB_Impl; + PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB_Impl; + + // GL_ARB_ES2_compatibility + PFNGLCLEARDEPTHFPROC glClearDepthf_Impl; + PFNGLDEPTHRANGEFPROC glDepthRangef_Impl; + PFNGLGETSHADERPRECISIONFORMATPROC glGetShaderPrecisionFormat_Impl; + PFNGLRELEASESHADERCOMPILERPROC glReleaseShaderCompiler_Impl; + PFNGLSHADERBINARYPROC glShaderBinary_Impl; + + // GL_ARB_framebuffer_object + PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer_Impl; + PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer_Impl; + PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer_Impl; + PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus_Impl; + PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers_Impl; + PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers_Impl; + PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer_Impl; + PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D_Impl; + PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D_Impl; + PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D_Impl; + PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer_Impl; + PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers_Impl; + PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers_Impl; + PFNGLGENERATEMIPMAPPROC glGenerateMipmap_Impl; + PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv_Impl; + PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv_Impl; + PFNGLISFRAMEBUFFERPROC glIsFramebuffer_Impl; + PFNGLISRENDERBUFFERPROC glIsRenderbuffer_Impl; + PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage_Impl; + PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample_Impl; + + // GL_ARB_framebuffer_sRGB + // (no functions) + + // GL_ARB_texture_multisample + PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv_Impl; + PFNGLSAMPLEMASKIPROC glSampleMaski_Impl; + PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample_Impl; + PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample_Impl; + + // GL_ARB_texture_non_power_of_two + // (no functions) + + // GL_ARB_texture_rectangle + // (no functions) + + // GL_ARB_texture_storage + PFNGLTEXSTORAGE1DPROC glTexStorage1D_Impl; + PFNGLTEXSTORAGE2DPROC glTexStorage2D_Impl; + PFNGLTEXSTORAGE3DPROC glTexStorage3D_Impl; + PFNGLTEXTURESTORAGE1DEXTPROC glTextureStorage1DEXT_Impl; + PFNGLTEXTURESTORAGE2DEXTPROC glTextureStorage2DEXT_Impl; + PFNGLTEXTURESTORAGE3DEXTPROC glTextureStorage3DEXT_Impl; + + // GL_ARB_texture_storage_multisample + PFNGLTEXSTORAGE2DMULTISAMPLEPROC glTexStorage2DMultisample_Impl; + PFNGLTEXSTORAGE3DMULTISAMPLEPROC glTexStorage3DMultisample_Impl; + PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glTextureStorage2DMultisampleEXT_Impl; + PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glTextureStorage3DMultisampleEXT_Impl; + + // GL_ARB_timer_query + PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v_Impl; + PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v_Impl; + PFNGLQUERYCOUNTERPROC glQueryCounter_Impl; + + // GL_ARB_vertex_array_object + PFNGLBINDVERTEXARRAYPROC glBindVertexArray_Impl; + PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays_Impl; + PFNGLGENVERTEXARRAYSPROC glGenVertexArrays_Impl; + PFNGLISVERTEXARRAYPROC glIsVertexArray_Impl; + + // GL_EXT_draw_buffers2 + PFNGLCOLORMASKINDEXEDEXTPROC glColorMaskIndexedEXT_Impl; + PFNGLDISABLEINDEXEDEXTPROC glDisableIndexedEXT_Impl; + PFNGLENABLEINDEXEDEXTPROC glEnableIndexedEXT_Impl; + PFNGLGETBOOLEANINDEXEDVEXTPROC glGetBooleanIndexedvEXT_Impl; + PFNGLGETINTEGERINDEXEDVEXTPROC glGetIntegerIndexedvEXT_Impl; + PFNGLISENABLEDINDEXEDEXTPROC glIsEnabledIndexedEXT_Impl; + + // GL_EXT_texture_filter_anisotropic + // (no functions) + + // GL_KHR_debug + PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback_Impl; + PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl_Impl; + PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert_Impl; + PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog_Impl; + PFNGLGETOBJECTLABELPROC glGetObjectLabel_Impl; + PFNGLGETOBJECTPTRLABELPROC glGetObjectPtrLabel_Impl; + PFNGLOBJECTLABELPROC glObjectLabel_Impl; + PFNGLOBJECTPTRLABELPROC glObjectPtrLabel_Impl; + PFNGLPOPDEBUGGROUPPROC glPopDebugGroup_Impl; + PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup_Impl; + + // GL_KHR_robust_buffer_access_behavior + + // GL_WIN_swap_hint + PFNGLADDSWAPHINTRECTWINPROC glAddSwapHintRectWIN_Impl; + +#if defined(GLE_WGL_ENABLED) + // WGL + // We don't declare pointers for these because we statically link to the implementations, same as + // with the OpenGL 1.1 functions. + // BOOL wglCopyContext_Hook(HGLRC, HGLRC, UINT); + // HGLRC wglCreateContext_Hook(HDC); + // HGLRC wglCreateLayerContext_Hook(HDC, int); + // BOOL wglDeleteContext_Hook(HGLRC); + // HGLRC wglGetCurrentContext_Hook(VOID); + // HDC wglGetCurrentDC_Hook(VOID); + // PROC wglGetProcAddress_Hook(LPCSTR); + // BOOL wglMakeCurrent_Hook(HDC, HGLRC); + // BOOL wglShareLists_Hook(HGLRC, HGLRC); + // BOOL wglUseFontBitmapsA_Hook(HDC, DWORD, DWORD, DWORD); + // BOOL wglUseFontBitmapsW_Hook(HDC, DWORD, DWORD, DWORD); + // BOOL wglUseFontOutlinesA_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, + // LPGLYPHMETRICSFLOAT); BOOL wglUseFontOutlinesW_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, + // int, LPGLYPHMETRICSFLOAT); BOOL wglDescribeLayerPlane_Hook(HDC, int, int, UINT, + // LPLAYERPLANEDESCRIPTOR); int wglSetLayerPaletteEntries_Hook(HDC, int, int, int, CONST + // COLORREF *); int wglGetLayerPaletteEntries_Hook(HDC, int, int, int, COLORREF *); BOOL + // wglRealizeLayerPalette_Hook(HDC, int, BOOL); BOOL wglSwapLayerBuffers_Hook(HDC, UINT); DWORD + // wglSwapMultipleBuffers_Hook(UINT, CONST WGLSWAP *); + +#if 0 + PFNWGLCOPYCONTEXTPROC wglCopyContext_Impl; + PFNWGLCREATECONTEXTPROC wglCreateContext_Impl; + PFNWGLCREATELAYERCONTEXTPROC wglCreateLayerContext_Impl; + PFNWGLDELETECONTEXTPROC wglDeleteContext_Impl; + PFNWGLGETCURRENTCONTEXTPROC wglGetCurrentContext_Impl; + PFNWGLGETCURRENTDCPROC wglGetCurrentDC_Impl; + PFNWGLGETPROCADDRESSPROC wglGetProcAddress_Impl; + PFNWGLMAKECURRENTPROC wglMakeCurrent_Impl; + PFNWGLSHARELISTSPROC wglShareLists_Impl; + PFNWGLUSEFONTBITMAPSAPROC wglUseFontBitmapsA_Impl; + PFNWGLUSEFONTBITMAPSWPROC wglUseFontBitmapsW_Impl; + PFNWGLUSEFONTOUTLINESAPROC wglUseFontOutlinesA_Impl; + PFNWGLUSEFONTOUTLINESWPROC wglUseFontOutlinesW_Impl; + PFNWGLDESCRIBELAYERPLANEPROC wglDescribeLayerPlane_Impl; + PFNWGLSETLAYERPALETTEENTRIESPROC wglSetLayerPaletteEntries_Impl; + PFNWGLGETLAYERPALETTEENTRIESPROC wglGetLayerPaletteEntries_Impl; + PFNWGLREALIZELAYERPALETTEPROC wglRealizeLayerPalette_Impl; + PFNWGLSWAPLAYERBUFFERSPROC wglSwapLayerBuffers_Impl; + PFNWGLSWAPMULTIPLEBUFFERSPROC wglSwapMultipleBuffers_Impl; +#endif + + // WGL_ARB_buffer_region + PFNWGLCREATEBUFFERREGIONARBPROC wglCreateBufferRegionARB_Impl; + PFNWGLDELETEBUFFERREGIONARBPROC wglDeleteBufferRegionARB_Impl; + PFNWGLSAVEBUFFERREGIONARBPROC wglSaveBufferRegionARB_Impl; + PFNWGLRESTOREBUFFERREGIONARBPROC wglRestoreBufferRegionARB_Impl; + + // WGL_ARB_extensions_string + PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB_Impl; + + // WGL_ARB_pixel_format + PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB_Impl; + PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB_Impl; + PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB_Impl; + + // WGL_ARB_make_current_read + PFNWGLMAKECONTEXTCURRENTARBPROC wglMakeContextCurrentARB_Impl; + PFNWGLGETCURRENTREADDCARBPROC wglGetCurrentReadDCARB_Impl; + + // WGL_ARB_pbuffer + PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB_Impl; + PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB_Impl; + PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB_Impl; + PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB_Impl; + PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB_Impl; + + // WGL_ARB_render_texture + PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB_Impl; + PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB_Impl; + PFNWGLSETPBUFFERATTRIBARBPROC wglSetPbufferAttribARB_Impl; + + // WGL_ARB_pixel_format_float + // (no functions) + + // WGL_ARB_framebuffer_sRGB + // (no functions) + + // WGL_NV_present_video + PFNWGLENUMERATEVIDEODEVICESNVPROC wglEnumerateVideoDevicesNV_Impl; + PFNWGLBINDVIDEODEVICENVPROC wglBindVideoDeviceNV_Impl; + PFNWGLQUERYCURRENTCONTEXTNVPROC wglQueryCurrentContextNV_Impl; + + // WGL_ARB_create_context + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB_Impl; + + // WGL_ARB_create_context_profile + // (no functions) + + // WGL_ARB_create_context_robustness + // (no functions) + + // WGL_EXT_extensions_string + PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT_Impl; + + // WGL_EXT_swap_control + PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT_Impl; + PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT_Impl; + + // WGL_OML_sync_control + PFNWGLGETSYNCVALUESOMLPROC wglGetSyncValuesOML_Impl; + PFNWGLGETMSCRATEOMLPROC wglGetMscRateOML_Impl; + PFNWGLSWAPBUFFERSMSCOMLPROC wglSwapBuffersMscOML_Impl; + PFNWGLSWAPLAYERBUFFERSMSCOMLPROC wglSwapLayerBuffersMscOML_Impl; + PFNWGLWAITFORMSCOMLPROC wglWaitForMscOML_Impl; + PFNWGLWAITFORSBCOMLPROC wglWaitForSbcOML_Impl; + + // WGL_NV_video_output + PFNWGLGETVIDEODEVICENVPROC wglGetVideoDeviceNV_Impl; + PFNWGLRELEASEVIDEODEVICENVPROC wglReleaseVideoDeviceNV_Impl; + PFNWGLBINDVIDEOIMAGENVPROC wglBindVideoImageNV_Impl; + PFNWGLRELEASEVIDEOIMAGENVPROC wglReleaseVideoImageNV_Impl; + PFNWGLSENDPBUFFERTOVIDEONVPROC wglSendPbufferToVideoNV_Impl; + PFNWGLGETVIDEOINFONVPROC wglGetVideoInfoNV_Impl; + + // WGL_NV_swap_group + PFNWGLJOINSWAPGROUPNVPROC wglJoinSwapGroupNV_Impl; + PFNWGLBINDSWAPBARRIERNVPROC wglBindSwapBarrierNV_Impl; + PFNWGLQUERYSWAPGROUPNVPROC wglQuerySwapGroupNV_Impl; + PFNWGLQUERYMAXSWAPGROUPSNVPROC wglQueryMaxSwapGroupsNV_Impl; + PFNWGLQUERYFRAMECOUNTNVPROC wglQueryFrameCountNV_Impl; + PFNWGLRESETFRAMECOUNTNVPROC wglResetFrameCountNV_Impl; + + // WGL_NV_video_capture + PFNWGLBINDVIDEOCAPTUREDEVICENVPROC wglBindVideoCaptureDeviceNV_Impl; + PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC wglEnumerateVideoCaptureDevicesNV_Impl; + PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC wglLockVideoCaptureDeviceNV_Impl; + PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC wglQueryVideoCaptureDeviceNV_Impl; + PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC wglReleaseVideoCaptureDeviceNV_Impl; + + // WGL_NV_copy_image + PFNWGLCOPYIMAGESUBDATANVPROC wglCopyImageSubDataNV_Impl; + + // WGL_NV_DX_interop + PFNWGLDXCLOSEDEVICENVPROC wglDXCloseDeviceNV_Impl; + PFNWGLDXLOCKOBJECTSNVPROC wglDXLockObjectsNV_Impl; + PFNWGLDXOBJECTACCESSNVPROC wglDXObjectAccessNV_Impl; + PFNWGLDXOPENDEVICENVPROC wglDXOpenDeviceNV_Impl; + PFNWGLDXREGISTEROBJECTNVPROC wglDXRegisterObjectNV_Impl; + PFNWGLDXSETRESOURCESHAREHANDLENVPROC wglDXSetResourceShareHandleNV_Impl; + PFNWGLDXUNLOCKOBJECTSNVPROC wglDXUnlockObjectsNV_Impl; + PFNWGLDXUNREGISTEROBJECTNVPROC wglDXUnregisterObjectNV_Impl; + +#endif // GLE_WGL_ENABLED + +#if defined(GLE_GLX_ENABLED) + // GLX_VERSION_1_1 + // We don't create any pointers, because we assume these functions are always present. + + // GLX_VERSION_1_2 + PFNGLXGETCURRENTDISPLAYPROC glXGetCurrentDisplay_Impl; + + // GLX_VERSION_1_3 + PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig_Impl; + PFNGLXCREATENEWCONTEXTPROC glXCreateNewContext_Impl; + PFNGLXCREATEPBUFFERPROC glXCreatePbuffer_Impl; + PFNGLXCREATEPIXMAPPROC glXCreatePixmap_Impl; + PFNGLXCREATEWINDOWPROC glXCreateWindow_Impl; + PFNGLXDESTROYPBUFFERPROC glXDestroyPbuffer_Impl; + PFNGLXDESTROYPIXMAPPROC glXDestroyPixmap_Impl; + PFNGLXDESTROYWINDOWPROC glXDestroyWindow_Impl; + PFNGLXGETCURRENTREADDRAWABLEPROC glXGetCurrentReadDrawable_Impl; + PFNGLXGETFBCONFIGATTRIBPROC glXGetFBConfigAttrib_Impl; + PFNGLXGETFBCONFIGSPROC glXGetFBConfigs_Impl; + PFNGLXGETSELECTEDEVENTPROC glXGetSelectedEvent_Impl; + PFNGLXGETVISUALFROMFBCONFIGPROC glXGetVisualFromFBConfig_Impl; + PFNGLXMAKECONTEXTCURRENTPROC glXMakeContextCurrent_Impl; + PFNGLXQUERYCONTEXTPROC glXQueryContext_Impl; + PFNGLXQUERYDRAWABLEPROC glXQueryDrawable_Impl; + PFNGLXSELECTEVENTPROC glXSelectEvent_Impl; + + // GLX_VERSION_1_4 + // Nothing to declare + + // GLX_ARB_create_context + PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB_Impl; + + // GLX_EXT_swap_control + PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT_Impl; + + // GLX_OML_sync_control + PFNGLXGETMSCRATEOMLPROC glXGetMscRateOML_Impl; + PFNGLXGETSYNCVALUESOMLPROC glXGetSyncValuesOML_Impl; + PFNGLXSWAPBUFFERSMSCOMLPROC glXSwapBuffersMscOML_Impl; + PFNGLXWAITFORMSCOMLPROC glXWaitForMscOML_Impl; + PFNGLXWAITFORSBCOMLPROC glXWaitForSbcOML_Impl; + + // GLX_MESA_swap_control + PFNGLXGETSWAPINTERVALMESAPROC glXGetSwapIntervalMESA_Impl; + PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA_Impl; + +#endif // GLE_GLX_ENABLED + + // Boolean extension support indicators. Each of these identifies the + // presence or absence of the given extension. A better solution here + // might be to use an STL map. + bool gle_AMD_debug_output; + // bool gle_AMD_performance_monitor; + bool gle_APPLE_aux_depth_stencil; + bool gle_APPLE_client_storage; + bool gle_APPLE_element_array; + bool gle_APPLE_fence; + bool gle_APPLE_float_pixels; + bool gle_APPLE_flush_buffer_range; + bool gle_APPLE_object_purgeable; + bool gle_APPLE_pixel_buffer; + bool gle_APPLE_rgb_422; + bool gle_APPLE_row_bytes; + bool gle_APPLE_specular_vector; + bool gle_APPLE_texture_range; + bool gle_APPLE_transform_hint; + bool gle_APPLE_vertex_array_object; + bool gle_APPLE_vertex_array_range; + bool gle_APPLE_vertex_program_evaluators; + bool gle_APPLE_ycbcr_422; + bool gle_ARB_copy_buffer; + bool gle_ARB_debug_output; + bool gle_ARB_depth_buffer_float; + // bool gle_ARB_direct_state_access; + bool gle_ARB_ES2_compatibility; + bool gle_ARB_framebuffer_object; + bool gle_ARB_framebuffer_sRGB; + bool gle_ARB_texture_multisample; + bool gle_ARB_texture_non_power_of_two; + bool gle_ARB_texture_rectangle; + bool gle_ARB_texture_storage; + bool gle_ARB_texture_storage_multisample; + bool gle_ARB_timer_query; + bool gle_ARB_vertex_array_object; + // bool gle_ARB_vertex_attrib_binding; + bool gle_EXT_draw_buffers2; + bool gle_EXT_texture_compression_s3tc; + bool gle_EXT_texture_filter_anisotropic; + bool gle_EXT_texture_sRGB; + // bool gle_KHR_context_flush_control; + bool gle_KHR_debug; + // bool gle_KHR_robust_buffer_access_behavior; + // bool gle_KHR_robustness; + bool gle_WIN_swap_hint; + +#if defined(GLE_WGL_ENABLED) + bool gle_WGL_ARB_buffer_region; + bool gle_WGL_ARB_create_context; + bool gle_WGL_ARB_create_context_profile; + bool gle_WGL_ARB_create_context_robustness; + bool gle_WGL_ARB_extensions_string; + bool gle_WGL_ARB_framebuffer_sRGB; + bool gle_WGL_ARB_make_current_read; + bool gle_WGL_ARB_pbuffer; + bool gle_WGL_ARB_pixel_format; + bool gle_WGL_ARB_pixel_format_float; + bool gle_WGL_ARB_render_texture; + bool gle_WGL_ATI_render_texture_rectangle; + bool gle_WGL_EXT_extensions_string; + bool gle_WGL_EXT_swap_control; + bool gle_WGL_NV_copy_image; + bool gle_WGL_NV_DX_interop; + bool gle_WGL_NV_DX_interop2; + bool gle_WGL_NV_present_video; + bool gle_WGL_NV_render_texture_rectangle; + bool gle_WGL_NV_swap_group; + bool gle_WGL_NV_video_capture; + bool gle_WGL_NV_video_output; + bool gle_WGL_OML_sync_control; +#elif defined(GLE_GLX_ENABLED) + bool gle_GLX_ARB_create_context; + bool gle_GLX_ARB_create_context_profile; + bool gle_GLX_ARB_create_context_robustness; + bool gle_GLX_EXT_swap_control; + bool gle_GLX_OML_sync_control; + bool gle_MESA_swap_control; +#endif + +}; // class GLEContext + +} // namespace OVR + +#endif // OVR_CAPI_GLE_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE_GL.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE_GL.h new file mode 100644 index 0000000..39db134 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/GL/CAPI_GLE_GL.h @@ -0,0 +1,5776 @@ +/************************************************************************************ + +Filename : CAPI_GLE_GL.h +Content : GL extensions declarations. +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_GLE_GL_h +#define OVR_CAPI_GLE_GL_h + +#include + +// Windows headers +// Windows-specific OpenGL 1.1 interfaces. Long ago this was . +// OpenGL 1.1 interface. +// OpenGL 1.2+ compatibility profile and extension interfaces. Not +// provided by Microsoft. +// Windows-specific extension interfaces. Not provided by Microsoft. +// OpenGL core profile and ARB extension interfaces. Doesn't include +// interfaces found only in the compatibility profile. Overlaps with gl.h and glext.h. +// +// Mac headers +// OpenGL 1.1 interface. +// OpenGL 1.2+ compatibility profile and extension interfaces. +// Includes only interfaces supported in a core OpenGL 3.1 implementations +// plus a few related extensions. +// Includes extensions supported in a core OpenGL 3.1 implementation. +// Apple-specific OpenGL interfaces. +// Apple-specific OpenGL interfaces. +// +// Linux headers +// OpenGL 1.1 interface. +// OpenGL 1.2+ compatibility profile and extension interfaces. +// X Windows-specific OpenGL interfaces. +// X Windows 1.3+ API and GLX extension interfaces. +// OpenGL core profile and ARB extension interfaces. Doesn't include +// interfaces found only in the compatibility profile. Overlaps with gl.h and glext.h. + +#if defined(__gl_h_) || defined(__GL_H__) || defined(__X_GL_H) +#error gl.h should be included after this, not before. +#endif +#if defined(__gl2_h_) +#error gl2.h should be included after this, not before. +#endif +#if defined(__gltypes_h_) +#error gltypes.h should be included after this, not before. +#endif +#if defined(__glext_h_) || defined(__GLEXT_H_) +#error glext.h should be included after this, not before. +#endif + +// Prevent other GL versions from being included in the future. +// We do not disable Microsoft's wingdi.h and redeclare its functions. That's a big header that +// includes many other things. +// We do not currently disable Apple's OpenGL/OpenGL.h, though we could if we replicated its +// declarations in this header file. +#define __gl_h_ // Disable future #includes of Apple's +#define __GL_H__ // Disable future #includes of Microsoft's +#define __X_GL_H // etc. +#define __gl2_h_ +#define __gltypes_h_ +#define __glext_h_ +#define __GLEXT_H_ + +// GLE platform identification +#if defined(_WIN32) +#define GLE_WGL_ENABLED 1 // WGL interface +#elif defined(__ANDROID__) +#define GLE_EGL_ENABLED 1 // EGL interface +#elif defined(__IPHONE__) +#define GLE_EAGL_ENABLED 1 // EAGL interface +#elif defined(__APPLE__) +#define GLE_CGL_ENABLED 1 // CGL interface +#else +#define GLE_GLX_ENABLED 1 // GLX interface +#endif + +// GLAPI / GLAPIENTRY +// +// GLAPI is a wrapper for Microsoft __declspec(dllimport). +// GLAPIENTRY is the calling convention (__stdcall under Microsoft). +// +#if defined(GLE_WGL_ENABLED) +#include "Kernel/OVR_Win32_IncludeWindows.h" + +#ifndef WINGDIAPI // Normally defined via windows.h +#define WINGDIAPI __declspec(dllimport) +#define GLE_WINGDIAPI_DEFINED // We define this so that we can know to undefine WINGDIAPI at the end +// of this file. +#endif + +#if !defined(GLAPI) +#if defined(__MINGW32__) || defined(__CYGWIN__) +#define GLAPI extern +#else +#define GLAPI WINGDIAPI +#endif +#endif +#if !defined(GLAPIENTRY) +#define GLAPIENTRY __stdcall +#endif +#else +#include + +#define GLAPI extern +#define GLAPIENTRY /* empty */ +#endif + +// GLE_CLASS_EXPORT +// Possibly maps to Microsoft __declspec(dllexport) or nothing on other platforms. +#define GLE_CLASS_EXPORT // Currently defined to nothing. Could be defined to a dll export type. + +// GLE_HOOKING_ENABLED +// When enabled, we intercept all OpenGL calls and do any useful internal processing before or after +// the call. +// An example use case for this is to intercept OpenGL errors on platforms that don't support the +// OpenGL +// debug functionality (e.g. KHR_Debug). +#if !defined(GLE_WGL_ENABLED) && !defined(GLE_GLX_ENABLED) && \ + defined(OVR_BUILD_DEBUG) // Windows and Unix don't need it because they have OpenGL debug +// extension support (e.g. KHR_Debug). +#define GLE_HOOKING_ENABLED 1 +#endif + +// When using hooking, we map all OpenGL function usage to our member functions that end with _Hook. +// These member hook functions will internally call the actual OpenGL functions after doing some +// internal processing. +#if defined(GLE_HOOKING_ENABLED) +#define GLEGetCurrentFunction(x) OVR::GLEContext::GetCurrentContext()->x##_Hook +#define GLEGetCurrentVariable(x) OVR::GLEContext::GetCurrentContext()->x +#else +#define GLEGetCurrentFunction(x) OVR::GLEContext::GetCurrentContext()->x##_Impl +#define GLEGetCurrentVariable(x) OVR::GLEContext::GetCurrentContext()->x +#endif + +// GLE_CURRENT_FUNCTION +// Used by hooking in debug builds. +#if defined(OVR_BUILD_DEBUG) +#define GLE_CURRENT_FUNCTION __FUNCTION__ +#else +#define GLE_CURRENT_FUNCTION NULL +#endif + +// GLE_WHOLE_VERSION +// Returns the major+minor version of the current GLEContext. +// Example usage: +// if(GLE_WHOLE_VERSION() >= 302) // If OpenGL 3.2 or later... +// ... +#define GLE_WHOLE_VERSION() OVR::GLEContext::GetCurrentContext()->WholeVersion() + +#ifdef __cplusplus +extern "C" { +#endif + +// OpenGL 1.1 declarations are present in all versions of gl.h, including Microsoft's. +// You don't need to dynamically link to these functions on any platform and can just assume +// they are present. A number of these functions have been deprecated by OpenGL v3+, and +// if an OpenGL v3+ core profile is enabled then usage of the deprecated functions is an error. + +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 + +typedef unsigned int GLenum; +typedef unsigned int GLbitfield; +typedef unsigned int GLuint; +typedef int GLint; +typedef int GLsizei; +typedef unsigned char GLboolean; +typedef signed char GLbyte; +typedef short GLshort; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned long GLulong; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void GLvoid; +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +typedef GLint64EXT GLint64; +typedef GLuint64EXT GLuint64; +typedef struct __GLsync* GLsync; +typedef char GLchar; + +#define GL_ZERO 0 +#define GL_FALSE 0 +#define GL_LOGIC_OP 0x0BF1 +#define GL_NONE 0 +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_NO_ERROR 0 +#define GL_POINTS 0x0000 +#define GL_CURRENT_BIT 0x00000001 +#define GL_TRUE 1 +#define GL_ONE 1 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_POINT_BIT 0x00000002 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_BIT 0x00000004 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON 0x0009 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_NEVER 0x0200 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_EXP 0x0800 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_EXP2 0x0801 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_VIEWPORT 0x0BA2 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_INDEX_BITS 0x0D51 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +#define GL_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_COLOR_INDEX 0x1900 +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_BITMAP 0x1A00 +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_S 0x2000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_CLAMP 0x2900 +#define GL_REPEAT 0x2901 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_R3_G3_B2 0x2A10 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_LIGHT0 0x4000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_HINT_BIT 0x00008000 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000fffff +#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff + +#if defined(GLE_HOOKING_ENABLED) +// In this case we map these functions to internal versions instead of the standard versions. +#define glAccum(...) GLEGetCurrentFunction(glAccum)(__VA_ARGS__) +#define glAlphaFunc(...) GLEGetCurrentFunction(glAlphaFunc)(__VA_ARGS__) +#define glAreTexturesResident(...) GLEGetCurrentFunction(glAreTexturesResident)(__VA_ARGS__) +#define glArrayElement(...) GLEGetCurrentFunction(glArrayElement)(__VA_ARGS__) +#define glBegin(...) GLEGetCurrentFunction(glBegin)(__VA_ARGS__) +#define glBindTexture(...) GLEGetCurrentFunction(glBindTexture)(__VA_ARGS__) +#define glBitmap(...) GLEGetCurrentFunction(glBitmap)(__VA_ARGS__) +#define glBlendFunc(...) GLEGetCurrentFunction(glBlendFunc)(__VA_ARGS__) +#define glCallList(...) GLEGetCurrentFunction(glCallList)(__VA_ARGS__) +#define glCallLists(...) GLEGetCurrentFunction(glCallLists)(__VA_ARGS__) +#define glClear(...) GLEGetCurrentFunction(glClear)(__VA_ARGS__) +#define glClearAccum(...) GLEGetCurrentFunction(glClearAccum)(__VA_ARGS__) +#define glClearColor(...) GLEGetCurrentFunction(glClearColor)(__VA_ARGS__) +#define glClearDepth(...) GLEGetCurrentFunction(glClearDepth)(__VA_ARGS__) +#define glClearIndex(...) GLEGetCurrentFunction(glClearIndex)(__VA_ARGS__) +#define glClearStencil(...) GLEGetCurrentFunction(glClearStencil)(__VA_ARGS__) +#define glClipPlane(...) GLEGetCurrentFunction(glClipPlane)(__VA_ARGS__) +#define glColor3b(...) GLEGetCurrentFunction(glColor3b)(__VA_ARGS__) +#define glColor3bv(...) GLEGetCurrentFunction(glColor3bv)(__VA_ARGS__) +#define glColor3d(...) GLEGetCurrentFunction(glColor3d)(__VA_ARGS__) +#define glColor3dv(...) GLEGetCurrentFunction(glColor3dv)(__VA_ARGS__) +#define glColor3f(...) GLEGetCurrentFunction(glColor3f)(__VA_ARGS__) +#define glColor3fv(...) GLEGetCurrentFunction(glColor3fv)(__VA_ARGS__) +#define glColor3i(...) GLEGetCurrentFunction(glColor3i)(__VA_ARGS__) +#define glColor3iv(...) GLEGetCurrentFunction(glColor3iv)(__VA_ARGS__) +#define glColor3s(...) GLEGetCurrentFunction(glColor3s)(__VA_ARGS__) +#define glColor3sv(...) GLEGetCurrentFunction(glColor3sv)(__VA_ARGS__) +#define glColor3ub(...) GLEGetCurrentFunction(glColor3ub)(__VA_ARGS__) +#define glColor3ubv(...) GLEGetCurrentFunction(glColor3ubv)(__VA_ARGS__) +#define glColor3ui(...) GLEGetCurrentFunction(glColor3ui)(__VA_ARGS__) +#define glColor3uiv(...) GLEGetCurrentFunction(glColor3uiv)(__VA_ARGS__) +#define glColor3us(...) GLEGetCurrentFunction(glColor3us)(__VA_ARGS__) +#define glColor3usv(...) GLEGetCurrentFunction(glColor3usv)(__VA_ARGS__) +#define glColor4b(...) GLEGetCurrentFunction(glColor4b)(__VA_ARGS__) +#define glColor4bv(...) GLEGetCurrentFunction(glColor4bv)(__VA_ARGS__) +#define glColor4d(...) GLEGetCurrentFunction(glColor4d)(__VA_ARGS__) +#define glColor4dv(...) GLEGetCurrentFunction(glColor4dv)(__VA_ARGS__) +#define glColor4f(...) GLEGetCurrentFunction(glColor4f)(__VA_ARGS__) +#define glColor4fv(...) GLEGetCurrentFunction(glColor4fv)(__VA_ARGS__) +#define glColor4i(...) GLEGetCurrentFunction(glColor4i)(__VA_ARGS__) +#define glColor4iv(...) GLEGetCurrentFunction(glColor4iv)(__VA_ARGS__) +#define glColor4s(...) GLEGetCurrentFunction(glColor4s)(__VA_ARGS__) +#define glColor4sv(...) GLEGetCurrentFunction(glColor4sv)(__VA_ARGS__) +#define glColor4ub(...) GLEGetCurrentFunction(glColor4ub)(__VA_ARGS__) +#define glColor4ubv(...) GLEGetCurrentFunction(glColor4ubv)(__VA_ARGS__) +#define glColor4ui(...) GLEGetCurrentFunction(glColor4ui)(__VA_ARGS__) +#define glColor4uiv(...) GLEGetCurrentFunction(glColor4uiv)(__VA_ARGS__) +#define glColor4us(...) GLEGetCurrentFunction(glColor4us)(__VA_ARGS__) +#define glColor4usv(...) GLEGetCurrentFunction(glColor4usv)(__VA_ARGS__) +#define glColorMask(...) GLEGetCurrentFunction(glColorMask)(__VA_ARGS__) +#define glColorMaterial(...) GLEGetCurrentFunction(glColorMaterial)(__VA_ARGS__) +#define glColorPointer(...) GLEGetCurrentFunction(glColorPointer)(__VA_ARGS__) +#define glCopyPixels(...) GLEGetCurrentFunction(glCopyPixels)(__VA_ARGS__) +#define glCopyTexImage1D(...) GLEGetCurrentFunction(glCopyTexImage1D)(__VA_ARGS__) +#define glCopyTexImage2D(...) GLEGetCurrentFunction(glCopyTexImage2D)(__VA_ARGS__) +#define glCopyTexSubImage1D(...) GLEGetCurrentFunction(glCopyTexSubImage1D)(__VA_ARGS__) +#define glCopyTexSubImage2D(...) GLEGetCurrentFunction(glCopyTexSubImage2D)(__VA_ARGS__) +#define glCullFace(...) GLEGetCurrentFunction(glCullFace)(__VA_ARGS__) +#define glDeleteLists(...) GLEGetCurrentFunction(glDeleteLists)(__VA_ARGS__) +#define glDeleteTextures(...) GLEGetCurrentFunction(glDeleteTextures)(__VA_ARGS__) +#define glDepthFunc(...) GLEGetCurrentFunction(glDepthFunc)(__VA_ARGS__) +#define glDepthMask(...) GLEGetCurrentFunction(glDepthMask)(__VA_ARGS__) +#define glDepthRange(...) GLEGetCurrentFunction(glDepthRange)(__VA_ARGS__) +#define glDisable(...) GLEGetCurrentFunction(glDisable)(__VA_ARGS__) +#define glDisableClientState(...) GLEGetCurrentFunction(glDisableClientState)(__VA_ARGS__) +#define glDrawArrays(...) GLEGetCurrentFunction(glDrawArrays)(__VA_ARGS__) +#define glDrawBuffer(...) GLEGetCurrentFunction(glDrawBuffer)(__VA_ARGS__) +#define glDrawElements(...) GLEGetCurrentFunction(glDrawElements)(__VA_ARGS__) +#define glDrawPixels(...) GLEGetCurrentFunction(glDrawPixels)(__VA_ARGS__) +#define glEdgeFlag(...) GLEGetCurrentFunction(glEdgeFlag)(__VA_ARGS__) +#define glEdgeFlagPointer(...) GLEGetCurrentFunction(glEdgeFlagPointer)(__VA_ARGS__) +#define glEdgeFlagv(...) GLEGetCurrentFunction(glEdgeFlagv)(__VA_ARGS__) +#define glEnable(...) GLEGetCurrentFunction(glEnable)(__VA_ARGS__) +#define glEnableClientState(...) GLEGetCurrentFunction(glEnableClientState)(__VA_ARGS__) +#define glEnd() GLEGetCurrentFunction(glEnd)() +#define glEndList() GLEGetCurrentFunction(glEndList)(_) +#define glEvalCoord1d(...) GLEGetCurrentFunction(glEvalCoord1d)(__VA_ARGS__) +#define glEvalCoord1dv(...) GLEGetCurrentFunction(glEvalCoord1dv)(__VA_ARGS__) +#define glEvalCoord1f(...) GLEGetCurrentFunction(glEvalCoord1f)(__VA_ARGS__) +#define glEvalCoord1fv(...) GLEGetCurrentFunction(glEvalCoord1fv)(__VA_ARGS__) +#define glEvalCoord2d(...) GLEGetCurrentFunction(glEvalCoord2d)(__VA_ARGS__) +#define glEvalCoord2dv(...) GLEGetCurrentFunction(glEvalCoord2dv)(__VA_ARGS__) +#define glEvalCoord2f(...) GLEGetCurrentFunction(glEvalCoord2f)(__VA_ARGS__) +#define glEvalCoord2fv(...) GLEGetCurrentFunction(glEvalCoord2fv)(__VA_ARGS__) +#define glEvalMesh1(...) GLEGetCurrentFunction(glEvalMesh1)(__VA_ARGS__) +#define glEvalMesh2(...) GLEGetCurrentFunction(glEvalMesh2)(__VA_ARGS__) +#define glEvalPoint1(...) GLEGetCurrentFunction(glEvalPoint1)(__VA_ARGS__) +#define glEvalPoint2(...) GLEGetCurrentFunction(glEvalPoint2)(__VA_ARGS__) +#define glFeedbackBuffer(...) GLEGetCurrentFunction(glFeedbackBuffer)(__VA_ARGS__) +#define glFinish() GLEGetCurrentFunction(glFinish)() +#define glFlush() GLEGetCurrentFunction(glFlush)() +#define glFogf(...) GLEGetCurrentFunction(glFogf)(__VA_ARGS__) +#define glFogfv(...) GLEGetCurrentFunction(glFogfv)(__VA_ARGS__) +#define glFogi(...) GLEGetCurrentFunction(glFogi)(__VA_ARGS__) +#define glFogiv(...) GLEGetCurrentFunction(glFogiv)(__VA_ARGS__) +#define glFrontFace(...) GLEGetCurrentFunction(glFrontFace)(__VA_ARGS__) +#define glFrustum(...) GLEGetCurrentFunction(glFrustum)(__VA_ARGS__) +#define glGenLists(...) GLEGetCurrentFunction(glGenLists)(__VA_ARGS__) +#define glGenTextures(...) GLEGetCurrentFunction(glGenTextures)(__VA_ARGS__) +#define glGetBooleanv(...) GLEGetCurrentFunction(glGetBooleanv)(__VA_ARGS__) +#define glGetClipPlane(...) GLEGetCurrentFunction(glGetClipPlane)(__VA_ARGS__) +#define glGetDoublev(...) GLEGetCurrentFunction(glGetDoublev)(__VA_ARGS__) +#define glGetError() GLEGetCurrentFunction(glGetError)() +#define glGetFloatv(...) GLEGetCurrentFunction(glGetFloatv)(__VA_ARGS__) +#define glGetIntegerv(...) GLEGetCurrentFunction(glGetIntegerv)(__VA_ARGS__) +#define glGetLightfv(...) GLEGetCurrentFunction(glGetLightfv)(__VA_ARGS__) +#define glGetLightiv(...) GLEGetCurrentFunction(glGetLightiv)(__VA_ARGS__) +#define glGetMapdv(...) GLEGetCurrentFunction(glGetMapdv)(__VA_ARGS__) +#define glGetMapfv(...) GLEGetCurrentFunction(glGetMapfv)(__VA_ARGS__) +#define glGetMapiv(...) GLEGetCurrentFunction(glGetMapiv)(__VA_ARGS__) +#define glGetMaterialfv(...) GLEGetCurrentFunction(glGetMaterialfv)(__VA_ARGS__) +#define glGetMaterialiv(...) GLEGetCurrentFunction(glGetMaterialiv)(__VA_ARGS__) +#define glGetPixelMapfv(...) GLEGetCurrentFunction(glGetPixelMapfv)(__VA_ARGS__) +#define glGetPixelMapuiv(...) GLEGetCurrentFunction(glGetPixelMapuiv)(__VA_ARGS__) +#define glGetPixelMapusv(...) GLEGetCurrentFunction(glGetPixelMapusv)(__VA_ARGS__) +#define glGetPointerv(...) GLEGetCurrentFunction(glGetPointerv)(__VA_ARGS__) +#define glGetPolygonStipple(...) GLEGetCurrentFunction(glGetPolygonStipple)(__VA_ARGS__) +#define glGetString(...) GLEGetCurrentFunction(glGetString)(__VA_ARGS__) +#define glGetTexEnvfv(...) GLEGetCurrentFunction(glGetTexEnvfv)(__VA_ARGS__) +#define glGetTexEnviv(...) GLEGetCurrentFunction(glGetTexEnviv)(__VA_ARGS__) +#define glGetTexGendv(...) GLEGetCurrentFunction(glGetTexGendv)(__VA_ARGS__) +#define glGetTexGenfv(...) GLEGetCurrentFunction(glGetTexGenfv)(__VA_ARGS__) +#define glGetTexGeniv(...) GLEGetCurrentFunction(glGetTexGeniv)(__VA_ARGS__) +#define glGetTexImage(...) GLEGetCurrentFunction(glGetTexImage)(__VA_ARGS__) +#define glGetTexLevelParameterfv(...) GLEGetCurrentFunction(glGetTexLevelParameterfv)(__VA_ARGS__) +#define glGetTexLevelParameteriv(...) GLEGetCurrentFunction(glGetTexLevelParameteriv)(__VA_ARGS__) +#define glGetTexParameterfv(...) GLEGetCurrentFunction(glGetTexParameterfv)(__VA_ARGS__) +#define glGetTexParameteriv(...) GLEGetCurrentFunction(glGetTexParameteriv)(__VA_ARGS__) +#define glHint(...) GLEGetCurrentFunction(glHint)(__VA_ARGS__) +#define glIndexMask(...) GLEGetCurrentFunction(glIndexMask)(__VA_ARGS__) +#define glIndexPointer(...) GLEGetCurrentFunction(glIndexPointer)(__VA_ARGS__) +#define glIndexd(...) GLEGetCurrentFunction(glIndexd)(__VA_ARGS__) +#define glIndexdv(...) GLEGetCurrentFunction(glIndexdv)(__VA_ARGS__) +#define glIndexf(...) GLEGetCurrentFunction(glIndexf)(__VA_ARGS__) +#define glIndexfv(...) GLEGetCurrentFunction(glIndexfv)(__VA_ARGS__) +#define glIndexi(...) GLEGetCurrentFunction(glIndexi)(__VA_ARGS__) +#define glIndexiv(...) GLEGetCurrentFunction(glIndexiv)(__VA_ARGS__) +#define glIndexs(...) GLEGetCurrentFunction(glIndexs)(__VA_ARGS__) +#define glIndexsv(...) GLEGetCurrentFunction(glIndexsv)(__VA_ARGS__) +#define glIndexub(...) GLEGetCurrentFunction(glIndexub)(__VA_ARGS__) +#define glIndexubv(...) GLEGetCurrentFunction(glIndexubv)(__VA_ARGS__) +#define glInitNames() GLEGetCurrentFunction(glInitNames)() +#define glInterleavedArrays(...) GLEGetCurrentFunction(glInterleavedArrays)(__VA_ARGS__) +#define glIsEnabled(...) GLEGetCurrentFunction(glIsEnabled)(__VA_ARGS__) +#define glIsList(...) GLEGetCurrentFunction(glIsList)(__VA_ARGS__) +#define glIsTexture(...) GLEGetCurrentFunction(glIsTexture)(__VA_ARGS__) +#define glLightModelf(...) GLEGetCurrentFunction(glLightModelf)(__VA_ARGS__) +#define glLightModelfv(...) GLEGetCurrentFunction(glLightModelfv)(__VA_ARGS__) +#define glLightModeli(...) GLEGetCurrentFunction(glLightModeli)(__VA_ARGS__) +#define glLightModeliv(...) GLEGetCurrentFunction(glLightModeliv)(__VA_ARGS__) +#define glLightf(...) GLEGetCurrentFunction(glLightf)(__VA_ARGS__) +#define glLightfv(...) GLEGetCurrentFunction(glLightfv)(__VA_ARGS__) +#define glLighti(...) GLEGetCurrentFunction(glLighti)(__VA_ARGS__) +#define glLightiv(...) GLEGetCurrentFunction(glLightiv)(__VA_ARGS__) +#define glLineStipple(...) GLEGetCurrentFunction(glLineStipple)(__VA_ARGS__) +#define glLineWidth(...) GLEGetCurrentFunction(glLineWidth)(__VA_ARGS__) +#define glListBase(...) GLEGetCurrentFunction(glListBase)(__VA_ARGS__) +#define glLoadIdentity() GLEGetCurrentFunction(glLoadIdentity)() +#define glLoadMatrixd(...) GLEGetCurrentFunction(glLoadMatrixd)(__VA_ARGS__) +#define glLoadMatrixf(...) GLEGetCurrentFunction(glLoadMatrixf)(__VA_ARGS__) +#define glLoadName(...) GLEGetCurrentFunction(glLoadName)(__VA_ARGS__) +#define glLogicOp(...) GLEGetCurrentFunction(glLogicOp)(__VA_ARGS__) +#define glMap1d(...) GLEGetCurrentFunction(glMap1d)(__VA_ARGS__) +#define glMap1f(...) GLEGetCurrentFunction(glMap1f)(__VA_ARGS__) +#define glMap2d(...) GLEGetCurrentFunction(glMap2d)(__VA_ARGS__) +#define glMap2f(...) GLEGetCurrentFunction(glMap2f)(__VA_ARGS__) +#define glMapGrid1d(...) GLEGetCurrentFunction(glMapGrid1d)(__VA_ARGS__) +#define glMapGrid1f(...) GLEGetCurrentFunction(glMapGrid1f)(__VA_ARGS__) +#define glMapGrid2d(...) GLEGetCurrentFunction(glMapGrid2d)(__VA_ARGS__) +#define glMapGrid2f(...) GLEGetCurrentFunction(glMapGrid2f)(__VA_ARGS__) +#define glMaterialf(...) GLEGetCurrentFunction(glMaterialf)(__VA_ARGS__) +#define glMaterialfv(...) GLEGetCurrentFunction(glMaterialfv)(__VA_ARGS__) +#define glMateriali(...) GLEGetCurrentFunction(glMateriali)(__VA_ARGS__) +#define glMaterialiv(...) GLEGetCurrentFunction(glMaterialiv)(__VA_ARGS__) +#define glMatrixMode(...) GLEGetCurrentFunction(glMatrixMode)(__VA_ARGS__) +#define glMultMatrixd(...) GLEGetCurrentFunction(glMultMatrixd)(__VA_ARGS__) +#define glMultMatrixf(...) GLEGetCurrentFunction(glMultMatrixf)(__VA_ARGS__) +#define glNewList(...) GLEGetCurrentFunction(glNewList)(__VA_ARGS__) +#define glNormal3b(...) GLEGetCurrentFunction(glNormal3b)(__VA_ARGS__) +#define glNormal3bv(...) GLEGetCurrentFunction(glNormal3bv)(__VA_ARGS__) +#define glNormal3d(...) GLEGetCurrentFunction(glNormal3d)(__VA_ARGS__) +#define glNormal3dv(...) GLEGetCurrentFunction(glNormal3dv)(__VA_ARGS__) +#define glNormal3f(...) GLEGetCurrentFunction(glNormal3f)(__VA_ARGS__) +#define glNormal3fv(...) GLEGetCurrentFunction(glNormal3fv)(__VA_ARGS__) +#define glNormal3i(...) GLEGetCurrentFunction(glNormal3i)(__VA_ARGS__) +#define glNormal3iv(...) GLEGetCurrentFunction(glNormal3iv)(__VA_ARGS__) +#define glNormal3s(...) GLEGetCurrentFunction(glNormal3s)(__VA_ARGS__) +#define glNormal3sv(...) GLEGetCurrentFunction(glNormal3sv)(__VA_ARGS__) +#define glNormalPointer(...) GLEGetCurrentFunction(glNormalPointer)(__VA_ARGS__) +#define glOrtho(...) GLEGetCurrentFunction(glOrtho)(__VA_ARGS__) +#define glPassThrough(...) GLEGetCurrentFunction(glPassThrough)(__VA_ARGS__) +#define glPixelMapfv(...) GLEGetCurrentFunction(glPixelMapfv)(__VA_ARGS__) +#define glPixelMapuiv(...) GLEGetCurrentFunction(glPixelMapuiv)(__VA_ARGS__) +#define glPixelMapusv(...) GLEGetCurrentFunction(glPixelMapusv)(__VA_ARGS__) +#define glPixelStoref(...) GLEGetCurrentFunction(glPixelStoref)(__VA_ARGS__) +#define glPixelStorei(...) GLEGetCurrentFunction(glPixelStorei)(__VA_ARGS__) +#define glPixelTransferf(...) GLEGetCurrentFunction(glPixelTransferf)(__VA_ARGS__) +#define glPixelTransferi(...) GLEGetCurrentFunction(glPixelTransferi)(__VA_ARGS__) +#define glPixelZoom(...) GLEGetCurrentFunction(glPixelZoom)(__VA_ARGS__) +#define glPointSize(...) GLEGetCurrentFunction(glPointSize)(__VA_ARGS__) +#define glPolygonMode(...) GLEGetCurrentFunction(glPolygonMode)(__VA_ARGS__) +#define glPolygonOffset(...) GLEGetCurrentFunction(glPolygonOffset)(__VA_ARGS__) +#define glPolygonStipple(...) GLEGetCurrentFunction(glPolygonStipple)(__VA_ARGS__) +#define glPopAttrib() GLEGetCurrentFunction(glPopAttrib)() +#define glPopClientAttrib() GLEGetCurrentFunction(glPopClientAttrib)() +#define glPopMatrix() GLEGetCurrentFunction(glPopMatrix)() +#define glPopName() GLEGetCurrentFunction(glPopName)() +#define glPrioritizeTextures(...) GLEGetCurrentFunction(glPrioritizeTextures)(__VA_ARGS__) +#define glPushAttrib(...) GLEGetCurrentFunction(glPushAttrib)(__VA_ARGS__) +#define glPushClientAttrib(...) GLEGetCurrentFunction(glPushClientAttrib)(__VA_ARGS__) +#define glPushMatrix() GLEGetCurrentFunction(glPushMatrix)() +#define glPushName(...) GLEGetCurrentFunction(glPushName)(__VA_ARGS__) +#define glRasterPos2d(...) GLEGetCurrentFunction(glRasterPos2d)(__VA_ARGS__) +#define glRasterPos2dv(...) GLEGetCurrentFunction(glRasterPos2dv)(__VA_ARGS__) +#define glRasterPos2f(...) GLEGetCurrentFunction(glRasterPos2f)(__VA_ARGS__) +#define glRasterPos2fv(...) GLEGetCurrentFunction(glRasterPos2fv)(__VA_ARGS__) +#define glRasterPos2i(...) GLEGetCurrentFunction(glRasterPos2i)(__VA_ARGS__) +#define glRasterPos2iv(...) GLEGetCurrentFunction(glRasterPos2iv)(__VA_ARGS__) +#define glRasterPos2s(...) GLEGetCurrentFunction(glRasterPos2s)(__VA_ARGS__) +#define glRasterPos2sv(...) GLEGetCurrentFunction(glRasterPos2sv)(__VA_ARGS__) +#define glRasterPos3d(...) GLEGetCurrentFunction(glRasterPos3d)(__VA_ARGS__) +#define glRasterPos3dv(...) GLEGetCurrentFunction(glRasterPos3dv)(__VA_ARGS__) +#define glRasterPos3f(...) GLEGetCurrentFunction(glRasterPos3f)(__VA_ARGS__) +#define glRasterPos3fv(...) GLEGetCurrentFunction(glRasterPos3fv)(__VA_ARGS__) +#define glRasterPos3i(...) GLEGetCurrentFunction(glRasterPos3i)(__VA_ARGS__) +#define glRasterPos3iv(...) GLEGetCurrentFunction(glRasterPos3iv)(__VA_ARGS__) +#define glRasterPos3s(...) GLEGetCurrentFunction(glRasterPos3s)(__VA_ARGS__) +#define glRasterPos3sv(...) GLEGetCurrentFunction(glRasterPos3sv)(__VA_ARGS__) +#define glRasterPos4d(...) GLEGetCurrentFunction(glRasterPos4d)(__VA_ARGS__) +#define glRasterPos4dv(...) GLEGetCurrentFunction(glRasterPos4dv)(__VA_ARGS__) +#define glRasterPos4f(...) GLEGetCurrentFunction(glRasterPos4f)(__VA_ARGS__) +#define glRasterPos4fv(...) GLEGetCurrentFunction(glRasterPos4fv)(__VA_ARGS__) +#define glRasterPos4i(...) GLEGetCurrentFunction(glRasterPos4i)(__VA_ARGS__) +#define glRasterPos4iv(...) GLEGetCurrentFunction(glRasterPos4iv)(__VA_ARGS__) +#define glRasterPos4s(...) GLEGetCurrentFunction(glRasterPos4s)(__VA_ARGS__) +#define glRasterPos4sv(...) GLEGetCurrentFunction(glRasterPos4sv)(__VA_ARGS__) +#define glReadBuffer(...) GLEGetCurrentFunction(glReadBuffer)(__VA_ARGS__) +#define glReadPixels(...) GLEGetCurrentFunction(glReadPixels)(__VA_ARGS__) +#define glRectd(...) GLEGetCurrentFunction(glRectd)(__VA_ARGS__) +#define glRectdv(...) GLEGetCurrentFunction(glRectdv)(__VA_ARGS__) +#define glRectf(...) GLEGetCurrentFunction(glRectf)(__VA_ARGS__) +#define glRectfv(...) GLEGetCurrentFunction(glRectfv)(__VA_ARGS__) +#define glRecti(...) GLEGetCurrentFunction(glRecti)(__VA_ARGS__) +#define glRectiv(...) GLEGetCurrentFunction(glRectiv)(__VA_ARGS__) +#define glRects(...) GLEGetCurrentFunction(glRects)(__VA_ARGS__) +#define glRectsv(...) GLEGetCurrentFunction(glRectsv)(__VA_ARGS__) +#define glRenderMode(...) GLEGetCurrentFunction(glRenderMode)(__VA_ARGS__) +#define glRotated(...) GLEGetCurrentFunction(glRotated)(__VA_ARGS__) +#define glRotatef(...) GLEGetCurrentFunction(glRotatef)(__VA_ARGS__) +#define glScaled(...) GLEGetCurrentFunction(glScaled)(__VA_ARGS__) +#define glScalef(...) GLEGetCurrentFunction(glScalef)(__VA_ARGS__) +#define glScissor(...) GLEGetCurrentFunction(glScissor)(__VA_ARGS__) +#define glSelectBuffer(...) GLEGetCurrentFunction(glSelectBuffer)(__VA_ARGS__) +#define glShadeModel(...) GLEGetCurrentFunction(glShadeModel)(__VA_ARGS__) +#define glStencilFunc(...) GLEGetCurrentFunction(glStencilFunc)(__VA_ARGS__) +#define glStencilMask(...) GLEGetCurrentFunction(glStencilMask)(__VA_ARGS__) +#define glStencilOp(...) GLEGetCurrentFunction(glStencilOp)(__VA_ARGS__) +#define glTexCoord1d(...) GLEGetCurrentFunction(glTexCoord1d)(__VA_ARGS__) +#define glTexCoord1dv(...) GLEGetCurrentFunction(glTexCoord1dv)(__VA_ARGS__) +#define glTexCoord1f(...) GLEGetCurrentFunction(glTexCoord1f)(__VA_ARGS__) +#define glTexCoord1fv(...) GLEGetCurrentFunction(glTexCoord1fv)(__VA_ARGS__) +#define glTexCoord1i(...) GLEGetCurrentFunction(glTexCoord1i)(__VA_ARGS__) +#define glTexCoord1iv(...) GLEGetCurrentFunction(glTexCoord1iv)(__VA_ARGS__) +#define glTexCoord1s(...) GLEGetCurrentFunction(glTexCoord1s)(__VA_ARGS__) +#define glTexCoord1sv(...) GLEGetCurrentFunction(glTexCoord1sv)(__VA_ARGS__) +#define glTexCoord2d(...) GLEGetCurrentFunction(glTexCoord2d)(__VA_ARGS__) +#define glTexCoord2dv(...) GLEGetCurrentFunction(glTexCoord2dv)(__VA_ARGS__) +#define glTexCoord2f(...) GLEGetCurrentFunction(glTexCoord2f)(__VA_ARGS__) +#define glTexCoord2fv(...) GLEGetCurrentFunction(glTexCoord2fv)(__VA_ARGS__) +#define glTexCoord2i(...) GLEGetCurrentFunction(glTexCoord2i)(__VA_ARGS__) +#define glTexCoord2iv(...) GLEGetCurrentFunction(glTexCoord2iv)(__VA_ARGS__) +#define glTexCoord2s(...) GLEGetCurrentFunction(glTexCoord2s)(__VA_ARGS__) +#define glTexCoord2sv(...) GLEGetCurrentFunction(glTexCoord2sv)(__VA_ARGS__) +#define glTexCoord3d(...) GLEGetCurrentFunction(glTexCoord3d)(__VA_ARGS__) +#define glTexCoord3dv(...) GLEGetCurrentFunction(glTexCoord3dv)(__VA_ARGS__) +#define glTexCoord3f(...) GLEGetCurrentFunction(glTexCoord3f)(__VA_ARGS__) +#define glTexCoord3fv(...) GLEGetCurrentFunction(glTexCoord3fv)(__VA_ARGS__) +#define glTexCoord3i(...) GLEGetCurrentFunction(glTexCoord3i)(__VA_ARGS__) +#define glTexCoord3iv(...) GLEGetCurrentFunction(glTexCoord3iv)(__VA_ARGS__) +#define glTexCoord3s(...) GLEGetCurrentFunction(glTexCoord3s)(__VA_ARGS__) +#define glTexCoord3sv(...) GLEGetCurrentFunction(glTexCoord3sv)(__VA_ARGS__) +#define glTexCoord4d(...) GLEGetCurrentFunction(glTexCoord4d)(__VA_ARGS__) +#define glTexCoord4dv(...) GLEGetCurrentFunction(glTexCoord4dv)(__VA_ARGS__) +#define glTexCoord4f(...) GLEGetCurrentFunction(glTexCoord4f)(__VA_ARGS__) +#define glTexCoord4fv(...) GLEGetCurrentFunction(glTexCoord4fv)(__VA_ARGS__) +#define glTexCoord4i(...) GLEGetCurrentFunction(glTexCoord4i)(__VA_ARGS__) +#define glTexCoord4iv(...) GLEGetCurrentFunction(glTexCoord4iv)(__VA_ARGS__) +#define glTexCoord4s(...) GLEGetCurrentFunction(glTexCoord4s)(__VA_ARGS__) +#define glTexCoord4sv(...) GLEGetCurrentFunction(glTexCoord4sv)(__VA_ARGS__) +#define glTexCoordPointer(...) GLEGetCurrentFunction(glTexCoordPointer)(__VA_ARGS__) +#define glTexEnvf(...) GLEGetCurrentFunction(glTexEnvf)(__VA_ARGS__) +#define glTexEnvfv(...) GLEGetCurrentFunction(glTexEnvfv)(__VA_ARGS__) +#define glTexEnvi(...) GLEGetCurrentFunction(glTexEnvi)(__VA_ARGS__) +#define glTexEnviv(...) GLEGetCurrentFunction(glTexEnviv)(__VA_ARGS__) +#define glTexGend(...) GLEGetCurrentFunction(glTexGend)(__VA_ARGS__) +#define glTexGendv(...) GLEGetCurrentFunction(glTexGendv)(__VA_ARGS__) +#define glTexGenf(...) GLEGetCurrentFunction(glTexGenf)(__VA_ARGS__) +#define glTexGenfv(...) GLEGetCurrentFunction(glTexGenfv)(__VA_ARGS__) +#define glTexGeni(...) GLEGetCurrentFunction(glTexGeni)(__VA_ARGS__) +#define glTexGeniv(...) GLEGetCurrentFunction(glTexGeniv)(__VA_ARGS__) +#define glTexImage1D(...) GLEGetCurrentFunction(glTexImage1D)(__VA_ARGS__) +#define glTexImage2D(...) GLEGetCurrentFunction(glTexImage2D)(__VA_ARGS__) +#define glTexParameterf(...) GLEGetCurrentFunction(glTexParameterf)(__VA_ARGS__) +#define glTexParameterfv(...) GLEGetCurrentFunction(glTexParameterfv)(__VA_ARGS__) +#define glTexParameteri(...) GLEGetCurrentFunction(glTexParameteri)(__VA_ARGS__) +#define glTexParameteriv(...) GLEGetCurrentFunction(glTexParameteriv)(__VA_ARGS__) +#define glTexSubImage1D(...) GLEGetCurrentFunction(glTexSubImage1D)(__VA_ARGS__) +#define glTexSubImage2D(...) GLEGetCurrentFunction(glTexSubImage2D)(__VA_ARGS__) +#define glTranslated(...) GLEGetCurrentFunction(glTranslated)(__VA_ARGS__) +#define glTranslatef(...) GLEGetCurrentFunction(glTranslatef)(__VA_ARGS__) +#define glVertex2d(...) GLEGetCurrentFunction(glVertex2d)(__VA_ARGS__) +#define glVertex2dv(...) GLEGetCurrentFunction(glVertex2dv)(__VA_ARGS__) +#define glVertex2f(...) GLEGetCurrentFunction(glVertex2f)(__VA_ARGS__) +#define glVertex2fv(...) GLEGetCurrentFunction(glVertex2fv)(__VA_ARGS__) +#define glVertex2i(...) GLEGetCurrentFunction(glVertex2i)(__VA_ARGS__) +#define glVertex2iv(...) GLEGetCurrentFunction(glVertex2iv)(__VA_ARGS__) +#define glVertex2s(...) GLEGetCurrentFunction(glVertex2s)(__VA_ARGS__) +#define glVertex2sv(...) GLEGetCurrentFunction(glVertex2sv)(__VA_ARGS__) +#define glVertex3d(...) GLEGetCurrentFunction(glVertex3d)(__VA_ARGS__) +#define glVertex3dv(...) GLEGetCurrentFunction(glVertex3dv)(__VA_ARGS__) +#define glVertex3f(...) GLEGetCurrentFunction(glVertex3f)(__VA_ARGS__) +#define glVertex3fv(...) GLEGetCurrentFunction(glVertex3fv)(__VA_ARGS__) +#define glVertex3i(...) GLEGetCurrentFunction(glVertex3i)(__VA_ARGS__) +#define glVertex3iv(...) GLEGetCurrentFunction(glVertex3iv)(__VA_ARGS__) +#define glVertex3s(...) GLEGetCurrentFunction(glVertex3s)(__VA_ARGS__) +#define glVertex3sv(...) GLEGetCurrentFunction(glVertex3sv)(__VA_ARGS__) +#define glVertex4d(...) GLEGetCurrentFunction(glVertex4d)(__VA_ARGS__) +#define glVertex4dv(...) GLEGetCurrentFunction(glVertex4dv)(__VA_ARGS__) +#define glVertex4f(...) GLEGetCurrentFunction(glVertex4f)(__VA_ARGS__) +#define glVertex4fv(...) GLEGetCurrentFunction(glVertex4fv)(__VA_ARGS__) +#define glVertex4i(...) GLEGetCurrentFunction(glVertex4i)(__VA_ARGS__) +#define glVertex4iv(...) GLEGetCurrentFunction(glVertex4iv)(__VA_ARGS__) +#define glVertex4s(...) GLEGetCurrentFunction(glVertex4s)(__VA_ARGS__) +#define glVertex4sv(...) GLEGetCurrentFunction(glVertex4sv)(__VA_ARGS__) +#define glVertexPointer(...) GLEGetCurrentFunction(glVertexPointer)(__VA_ARGS__) +#define glViewport(...) GLEGetCurrentFunction(glViewport)(__VA_ARGS__) +#else +// There is no need to typedef OpenGL 1.1 function types because they are present in all +// OpenGL implementations and don't need to be treated dynamically like extensions. +GLAPI void GLAPIENTRY glAccum(GLenum op, GLfloat value); +GLAPI void GLAPIENTRY glAlphaFunc(GLenum func, GLclampf ref); +GLAPI GLboolean GLAPIENTRY +glAreTexturesResident(GLsizei n, const GLuint* textures, GLboolean* residences); +GLAPI void GLAPIENTRY glArrayElement(GLint i); +GLAPI void GLAPIENTRY glBegin(GLenum mode); +GLAPI void GLAPIENTRY glBindTexture(GLenum target, GLuint texture); +GLAPI void GLAPIENTRY glBitmap( + GLsizei width, + GLsizei height, + GLfloat xorig, + GLfloat yorig, + GLfloat xmove, + GLfloat ymove, + const GLubyte* bitmap); +GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor); +GLAPI void GLAPIENTRY glCallList(GLuint list); +GLAPI void GLAPIENTRY glCallLists(GLsizei n, GLenum type, const void* lists); +GLAPI void GLAPIENTRY glClear(GLbitfield mask); +GLAPI void GLAPIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GLAPI void GLAPIENTRY glClearDepth(GLclampd depth); +GLAPI void GLAPIENTRY glClearIndex(GLfloat c); +GLAPI void GLAPIENTRY glClearStencil(GLint s); +GLAPI void GLAPIENTRY glClipPlane(GLenum plane, const GLdouble* equation); +GLAPI void GLAPIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue); +GLAPI void GLAPIENTRY glColor3bv(const GLbyte* v); +GLAPI void GLAPIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue); +GLAPI void GLAPIENTRY glColor3dv(const GLdouble* v); +GLAPI void GLAPIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue); +GLAPI void GLAPIENTRY glColor3fv(const GLfloat* v); +GLAPI void GLAPIENTRY glColor3i(GLint red, GLint green, GLint blue); +GLAPI void GLAPIENTRY glColor3iv(const GLint* v); +GLAPI void GLAPIENTRY glColor3s(GLshort red, GLshort green, GLshort blue); +GLAPI void GLAPIENTRY glColor3sv(const GLshort* v); +GLAPI void GLAPIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue); +GLAPI void GLAPIENTRY glColor3ubv(const GLubyte* v); +GLAPI void GLAPIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue); +GLAPI void GLAPIENTRY glColor3uiv(const GLuint* v); +GLAPI void GLAPIENTRY glColor3us(GLushort red, GLushort green, GLushort blue); +GLAPI void GLAPIENTRY glColor3usv(const GLushort* v); +GLAPI void GLAPIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +GLAPI void GLAPIENTRY glColor4bv(const GLbyte* v); +GLAPI void GLAPIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +GLAPI void GLAPIENTRY glColor4dv(const GLdouble* v); +GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glColor4fv(const GLfloat* v); +GLAPI void GLAPIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void GLAPIENTRY glColor4iv(const GLint* v); +GLAPI void GLAPIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha); +GLAPI void GLAPIENTRY glColor4sv(const GLshort* v); +GLAPI void GLAPIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +GLAPI void GLAPIENTRY glColor4ubv(const GLubyte* v); +GLAPI void GLAPIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha); +GLAPI void GLAPIENTRY glColor4uiv(const GLuint* v); +GLAPI void GLAPIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha); +GLAPI void GLAPIENTRY glColor4usv(const GLushort* v); +GLAPI void GLAPIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI void GLAPIENTRY glColorMaterial(GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const void* pointer); +GLAPI void GLAPIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +GLAPI void GLAPIENTRY glCopyTexImage1D( + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLint border); +GLAPI void GLAPIENTRY glCopyTexImage2D( + GLenum target, + GLint level, + GLenum internalFormat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); +GLAPI void GLAPIENTRY +glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void GLAPIENTRY glCopyTexSubImage2D( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +GLAPI void GLAPIENTRY glCullFace(GLenum mode); +GLAPI void GLAPIENTRY glDeleteLists(GLuint list, GLsizei range); +GLAPI void GLAPIENTRY glDeleteTextures(GLsizei n, const GLuint* textures); +GLAPI void GLAPIENTRY glDepthFunc(GLenum func); +GLAPI void GLAPIENTRY glDepthMask(GLboolean flag); +GLAPI void GLAPIENTRY glDepthRange(GLclampd zNear, GLclampd zFar); +GLAPI void GLAPIENTRY glDisable(GLenum cap); +GLAPI void GLAPIENTRY glDisableClientState(GLenum array); +GLAPI void GLAPIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count); +GLAPI void GLAPIENTRY glDrawBuffer(GLenum mode); +GLAPI void GLAPIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices); +GLAPI void GLAPIENTRY +glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +GLAPI void GLAPIENTRY glEdgeFlag(GLboolean flag); +GLAPI void GLAPIENTRY glEdgeFlagPointer(GLsizei stride, const void* pointer); +GLAPI void GLAPIENTRY glEdgeFlagv(const GLboolean* flag); +GLAPI void GLAPIENTRY glEnable(GLenum cap); +GLAPI void GLAPIENTRY glEnableClientState(GLenum array); +GLAPI void GLAPIENTRY glEnd(void); +GLAPI void GLAPIENTRY glEndList(void); +GLAPI void GLAPIENTRY glEvalCoord1d(GLdouble u); +GLAPI void GLAPIENTRY glEvalCoord1dv(const GLdouble* u); +GLAPI void GLAPIENTRY glEvalCoord1f(GLfloat u); +GLAPI void GLAPIENTRY glEvalCoord1fv(const GLfloat* u); +GLAPI void GLAPIENTRY glEvalCoord2d(GLdouble u, GLdouble v); +GLAPI void GLAPIENTRY glEvalCoord2dv(const GLdouble* u); +GLAPI void GLAPIENTRY glEvalCoord2f(GLfloat u, GLfloat v); +GLAPI void GLAPIENTRY glEvalCoord2fv(const GLfloat* u); +GLAPI void GLAPIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2); +GLAPI void GLAPIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +GLAPI void GLAPIENTRY glEvalPoint1(GLint i); +GLAPI void GLAPIENTRY glEvalPoint2(GLint i, GLint j); +GLAPI void GLAPIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat* buffer); +GLAPI void GLAPIENTRY glFinish(void); +GLAPI void GLAPIENTRY glFlush(void); +GLAPI void GLAPIENTRY glFogf(GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glFogfv(GLenum pname, const GLfloat* params); +GLAPI void GLAPIENTRY glFogi(GLenum pname, GLint param); +GLAPI void GLAPIENTRY glFogiv(GLenum pname, const GLint* params); +GLAPI void GLAPIENTRY glFrontFace(GLenum mode); +GLAPI void GLAPIENTRY glFrustum( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar); +GLAPI GLuint GLAPIENTRY glGenLists(GLsizei range); +GLAPI void GLAPIENTRY glGenTextures(GLsizei n, GLuint* textures); +GLAPI void GLAPIENTRY glGetBooleanv(GLenum pname, GLboolean* params); +GLAPI void GLAPIENTRY glGetClipPlane(GLenum plane, GLdouble* equation); +GLAPI void GLAPIENTRY glGetDoublev(GLenum pname, GLdouble* params); +GLAPI GLenum GLAPIENTRY glGetError(void); +GLAPI void GLAPIENTRY glGetFloatv(GLenum pname, GLfloat* params); +GLAPI void GLAPIENTRY glGetIntegerv(GLenum pname, GLint* params); +GLAPI void GLAPIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat* params); +GLAPI void GLAPIENTRY glGetLightiv(GLenum light, GLenum pname, GLint* params); +GLAPI void GLAPIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble* v); +GLAPI void GLAPIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat* v); +GLAPI void GLAPIENTRY glGetMapiv(GLenum target, GLenum query, GLint* v); +GLAPI void GLAPIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat* params); +GLAPI void GLAPIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint* params); +GLAPI void GLAPIENTRY glGetPixelMapfv(GLenum map, GLfloat* values); +GLAPI void GLAPIENTRY glGetPixelMapuiv(GLenum map, GLuint* values); +GLAPI void GLAPIENTRY glGetPixelMapusv(GLenum map, GLushort* values); +GLAPI void GLAPIENTRY glGetPointerv(GLenum pname, void** params); +GLAPI void GLAPIENTRY glGetPolygonStipple(GLubyte* mask); +GLAPI const GLubyte* GLAPIENTRY glGetString(GLenum name); +GLAPI void GLAPIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat* params); +GLAPI void GLAPIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint* params); +GLAPI void GLAPIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble* params); +GLAPI void GLAPIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat* params); +GLAPI void GLAPIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint* params); +GLAPI void GLAPIENTRY +glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +GLAPI void GLAPIENTRY +glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params); +GLAPI void GLAPIENTRY +glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params); +GLAPI void GLAPIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params); +GLAPI void GLAPIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params); +GLAPI void GLAPIENTRY glHint(GLenum target, GLenum mode); +GLAPI void GLAPIENTRY glIndexMask(GLuint mask); +GLAPI void GLAPIENTRY glIndexPointer(GLenum type, GLsizei stride, const void* pointer); +GLAPI void GLAPIENTRY glIndexd(GLdouble c); +GLAPI void GLAPIENTRY glIndexdv(const GLdouble* c); +GLAPI void GLAPIENTRY glIndexf(GLfloat c); +GLAPI void GLAPIENTRY glIndexfv(const GLfloat* c); +GLAPI void GLAPIENTRY glIndexi(GLint c); +GLAPI void GLAPIENTRY glIndexiv(const GLint* c); +GLAPI void GLAPIENTRY glIndexs(GLshort c); +GLAPI void GLAPIENTRY glIndexsv(const GLshort* c); +GLAPI void GLAPIENTRY glIndexub(GLubyte c); +GLAPI void GLAPIENTRY glIndexubv(const GLubyte* c); +GLAPI void GLAPIENTRY glInitNames(void); +GLAPI void GLAPIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const void* pointer); +GLAPI GLboolean GLAPIENTRY glIsEnabled(GLenum cap); +GLAPI GLboolean GLAPIENTRY glIsList(GLuint list); +GLAPI GLboolean GLAPIENTRY glIsTexture(GLuint texture); +GLAPI void GLAPIENTRY glLightModelf(GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightModelfv(GLenum pname, const GLfloat* params); +GLAPI void GLAPIENTRY glLightModeli(GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightModeliv(GLenum pname, const GLint* params); +GLAPI void GLAPIENTRY glLightf(GLenum light, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat* params); +GLAPI void GLAPIENTRY glLighti(GLenum light, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightiv(GLenum light, GLenum pname, const GLint* params); +GLAPI void GLAPIENTRY glLineStipple(GLint factor, GLushort pattern); +GLAPI void GLAPIENTRY glLineWidth(GLfloat width); +GLAPI void GLAPIENTRY glListBase(GLuint base); +GLAPI void GLAPIENTRY glLoadIdentity(void); +GLAPI void GLAPIENTRY glLoadMatrixd(const GLdouble* m); +GLAPI void GLAPIENTRY glLoadMatrixf(const GLfloat* m); +GLAPI void GLAPIENTRY glLoadName(GLuint name); +GLAPI void GLAPIENTRY glLogicOp(GLenum opcode); +GLAPI void GLAPIENTRY +glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points); +GLAPI void GLAPIENTRY +glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points); +GLAPI void GLAPIENTRY glMap2d( + GLenum target, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble* points); +GLAPI void GLAPIENTRY glMap2f( + GLenum target, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat* points); +GLAPI void GLAPIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2); +GLAPI void GLAPIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2); +GLAPI void GLAPIENTRY +glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +GLAPI void GLAPIENTRY +glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +GLAPI void GLAPIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat* params); +GLAPI void GLAPIENTRY glMateriali(GLenum face, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint* params); +GLAPI void GLAPIENTRY glMatrixMode(GLenum mode); +GLAPI void GLAPIENTRY glMultMatrixd(const GLdouble* m); +GLAPI void GLAPIENTRY glMultMatrixf(const GLfloat* m); +GLAPI void GLAPIENTRY glNewList(GLuint list, GLenum mode); +GLAPI void GLAPIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI void GLAPIENTRY glNormal3bv(const GLbyte* v); +GLAPI void GLAPIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI void GLAPIENTRY glNormal3dv(const GLdouble* v); +GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI void GLAPIENTRY glNormal3fv(const GLfloat* v); +GLAPI void GLAPIENTRY glNormal3i(GLint nx, GLint ny, GLint nz); +GLAPI void GLAPIENTRY glNormal3iv(const GLint* v); +GLAPI void GLAPIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz); +GLAPI void GLAPIENTRY glNormal3sv(const GLshort* v); +GLAPI void GLAPIENTRY glNormalPointer(GLenum type, GLsizei stride, const void* pointer); +GLAPI void GLAPIENTRY glOrtho( + GLdouble left, + GLdouble right, + GLdouble bottom, + GLdouble top, + GLdouble zNear, + GLdouble zFar); +GLAPI void GLAPIENTRY glPassThrough(GLfloat token); +GLAPI void GLAPIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat* values); +GLAPI void GLAPIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint* values); +GLAPI void GLAPIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort* values); +GLAPI void GLAPIENTRY glPixelStoref(GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelTransferf(GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelTransferi(GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor); +GLAPI void GLAPIENTRY glPointSize(GLfloat size); +GLAPI void GLAPIENTRY glPolygonMode(GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glPolygonOffset(GLfloat factor, GLfloat units); +GLAPI void GLAPIENTRY glPolygonStipple(const GLubyte* mask); +GLAPI void GLAPIENTRY glPopAttrib(void); +GLAPI void GLAPIENTRY glPopClientAttrib(void); +GLAPI void GLAPIENTRY glPopMatrix(void); +GLAPI void GLAPIENTRY glPopName(void); +GLAPI void GLAPIENTRY +glPrioritizeTextures(GLsizei n, const GLuint* textures, const GLclampf* priorities); +GLAPI void GLAPIENTRY glPushAttrib(GLbitfield mask); +GLAPI void GLAPIENTRY glPushClientAttrib(GLbitfield mask); +GLAPI void GLAPIENTRY glPushMatrix(void); +GLAPI void GLAPIENTRY glPushName(GLuint name); +GLAPI void GLAPIENTRY glRasterPos2d(GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glRasterPos2dv(const GLdouble* v); +GLAPI void GLAPIENTRY glRasterPos2f(GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glRasterPos2fv(const GLfloat* v); +GLAPI void GLAPIENTRY glRasterPos2i(GLint x, GLint y); +GLAPI void GLAPIENTRY glRasterPos2iv(const GLint* v); +GLAPI void GLAPIENTRY glRasterPos2s(GLshort x, GLshort y); +GLAPI void GLAPIENTRY glRasterPos2sv(const GLshort* v); +GLAPI void GLAPIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRasterPos3dv(const GLdouble* v); +GLAPI void GLAPIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glRasterPos3fv(const GLfloat* v); +GLAPI void GLAPIENTRY glRasterPos3i(GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glRasterPos3iv(const GLint* v); +GLAPI void GLAPIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glRasterPos3sv(const GLshort* v); +GLAPI void GLAPIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glRasterPos4dv(const GLdouble* v); +GLAPI void GLAPIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glRasterPos4fv(const GLfloat* v); +GLAPI void GLAPIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glRasterPos4iv(const GLint* v); +GLAPI void GLAPIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glRasterPos4sv(const GLshort* v); +GLAPI void GLAPIENTRY glReadBuffer(GLenum mode); +GLAPI void GLAPIENTRY glReadPixels( + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void* pixels); +GLAPI void GLAPIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +GLAPI void GLAPIENTRY glRectdv(const GLdouble* v1, const GLdouble* v2); +GLAPI void GLAPIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +GLAPI void GLAPIENTRY glRectfv(const GLfloat* v1, const GLfloat* v2); +GLAPI void GLAPIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2); +GLAPI void GLAPIENTRY glRectiv(const GLint* v1, const GLint* v2); +GLAPI void GLAPIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +GLAPI void GLAPIENTRY glRectsv(const GLshort* v1, const GLshort* v2); +GLAPI GLint GLAPIENTRY glRenderMode(GLenum mode); +GLAPI void GLAPIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glSelectBuffer(GLsizei size, GLuint* buffer); +GLAPI void GLAPIENTRY glShadeModel(GLenum mode); +GLAPI void GLAPIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask); +GLAPI void GLAPIENTRY glStencilMask(GLuint mask); +GLAPI void GLAPIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass); +GLAPI void GLAPIENTRY glTexCoord1d(GLdouble s); +GLAPI void GLAPIENTRY glTexCoord1dv(const GLdouble* v); +GLAPI void GLAPIENTRY glTexCoord1f(GLfloat s); +GLAPI void GLAPIENTRY glTexCoord1fv(const GLfloat* v); +GLAPI void GLAPIENTRY glTexCoord1i(GLint s); +GLAPI void GLAPIENTRY glTexCoord1iv(const GLint* v); +GLAPI void GLAPIENTRY glTexCoord1s(GLshort s); +GLAPI void GLAPIENTRY glTexCoord1sv(const GLshort* v); +GLAPI void GLAPIENTRY glTexCoord2d(GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glTexCoord2dv(const GLdouble* v); +GLAPI void GLAPIENTRY glTexCoord2f(GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glTexCoord2fv(const GLfloat* v); +GLAPI void GLAPIENTRY glTexCoord2i(GLint s, GLint t); +GLAPI void GLAPIENTRY glTexCoord2iv(const GLint* v); +GLAPI void GLAPIENTRY glTexCoord2s(GLshort s, GLshort t); +GLAPI void GLAPIENTRY glTexCoord2sv(const GLshort* v); +GLAPI void GLAPIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glTexCoord3dv(const GLdouble* v); +GLAPI void GLAPIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glTexCoord3fv(const GLfloat* v); +GLAPI void GLAPIENTRY glTexCoord3i(GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glTexCoord3iv(const GLint* v); +GLAPI void GLAPIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glTexCoord3sv(const GLshort* v); +GLAPI void GLAPIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glTexCoord4dv(const GLdouble* v); +GLAPI void GLAPIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glTexCoord4fv(const GLfloat* v); +GLAPI void GLAPIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glTexCoord4iv(const GLint* v); +GLAPI void GLAPIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glTexCoord4sv(const GLshort* v); +GLAPI void GLAPIENTRY +glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void* pointer); +GLAPI void GLAPIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat* params); +GLAPI void GLAPIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint* params); +GLAPI void GLAPIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param); +GLAPI void GLAPIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble* params); +GLAPI void GLAPIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat* params); +GLAPI void GLAPIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint* params); +GLAPI void GLAPIENTRY glTexImage1D( + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const void* pixels); +GLAPI void GLAPIENTRY glTexImage2D( + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void* pixels); +GLAPI void GLAPIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params); +GLAPI void GLAPIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params); +GLAPI void GLAPIENTRY glTexSubImage1D( + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLenum type, + const void* pixels); +GLAPI void GLAPIENTRY glTexSubImage2D( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void* pixels); +GLAPI void GLAPIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex2d(GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glVertex2dv(const GLdouble* v); +GLAPI void GLAPIENTRY glVertex2f(GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glVertex2fv(const GLfloat* v); +GLAPI void GLAPIENTRY glVertex2i(GLint x, GLint y); +GLAPI void GLAPIENTRY glVertex2iv(const GLint* v); +GLAPI void GLAPIENTRY glVertex2s(GLshort x, GLshort y); +GLAPI void GLAPIENTRY glVertex2sv(const GLshort* v); +GLAPI void GLAPIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glVertex3dv(const GLdouble* v); +GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex3fv(const GLfloat* v); +GLAPI void GLAPIENTRY glVertex3i(GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glVertex3iv(const GLint* v); +GLAPI void GLAPIENTRY glVertex3s(GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glVertex3sv(const GLshort* v); +GLAPI void GLAPIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glVertex4dv(const GLdouble* v); +GLAPI void GLAPIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glVertex4fv(const GLfloat* v); +GLAPI void GLAPIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glVertex4iv(const GLint* v); +GLAPI void GLAPIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glVertex4sv(const GLshort* v); +GLAPI void GLAPIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const void* pointer); +GLAPI void GLAPIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height); + +#endif // GLE_HOOKING_ENABLED + +#endif // GL_VERSION_1_1 + +// OpenGL 1.2+ functions are not declared in Microsoft's gl.h + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 + +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E + +typedef void(GLAPIENTRY* PFNGLCOPYTEXSUBIMAGE3DPROC)( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +typedef void(GLAPIENTRY* PFNGLDRAWRANGEELEMENTSPROC)( + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void* indices); +typedef void(GLAPIENTRY* PFNGLTEXIMAGE3DPROC)( + GLenum target, + GLint level, + GLint internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void* pixels); +typedef void(GLAPIENTRY* PFNGLTEXSUBIMAGE3DPROC)( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void* pixels); + +#define glCopyTexSubImage3D GLEGetCurrentFunction(glCopyTexSubImage3D) +#define glDrawRangeElements GLEGetCurrentFunction(glDrawRangeElements) +#define glTexImage3D GLEGetCurrentFunction(glTexImage3D) +#define glTexSubImage3D GLEGetCurrentFunction(glTexSubImage3D) + +// OpenGL 2.1 deprecated functions +/* +typedef void (GLAPIENTRY PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf +alpha); +typedef void (GLAPIENTRY PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GLAPIENTRY PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, +GLenum format, GLenum type, const GLvoid *table); +typedef void (GLAPIENTRY PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat +*params); +typedef void (GLAPIENTRY PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint +*params); +typedef void (GLAPIENTRY PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, +GLint y, GLsizei width); +typedef void (GLAPIENTRY PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid +*table); +typedef void (GLAPIENTRY PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat +*params); +typedef void (GLAPIENTRY PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint +*params); +typedef void (GLAPIENTRY PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, +GLenum format, GLenum type, const GLvoid *data); +typedef void (GLAPIENTRY PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint +y, GLsizei width); +typedef void (GLAPIENTRY PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, +GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, +GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat +params); +typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const +GLfloat *params); +typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint +params); +typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint +*params); +typedef void (GLAPIENTRY PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, +GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, +GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, +GLvoid *image); +typedef void (GLAPIENTRY PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat +*params); +typedef void (GLAPIENTRY PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint +*params); +typedef void (GLAPIENTRY PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, +GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (GLAPIENTRY PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei +width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +typedef void (GLAPIENTRY PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, +GLenum type, GLvoid *values); +typedef void (GLAPIENTRY PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat +*params); +typedef void (GLAPIENTRY PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint +*params); +typedef void (GLAPIENTRY PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum +type, GLvoid *values); +typedef void (GLAPIENTRY PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat +*params); +typedef void (GLAPIENTRY PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint +*params); +typedef void (GLAPIENTRY PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, +GLboolean sink); +typedef void (GLAPIENTRY PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (GLAPIENTRY PFNGLRESETMINMAXPROC) (GLenum target); +*/ +#endif // GL_VERSION_1_2 + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 + +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_SUBTRACT 0x84E7 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_MULTISAMPLE_BIT 0x20000000 + +typedef void(GLAPIENTRY* PFNGLACTIVETEXTUREPROC)(GLenum texture); +typedef void(GLAPIENTRY* PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); +typedef void(GLAPIENTRY* PFNGLCOMPRESSEDTEXIMAGE1DPROC)( + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLint border, + GLsizei imageSize, + const void* data); +typedef void(GLAPIENTRY* PFNGLCOMPRESSEDTEXIMAGE2DPROC)( + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void* data); +typedef void(GLAPIENTRY* PFNGLCOMPRESSEDTEXIMAGE3DPROC)( + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void* data); +typedef void(GLAPIENTRY* PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)( + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, + GLsizei imageSize, + const void* data); +typedef void(GLAPIENTRY* PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void* data); +typedef void(GLAPIENTRY* PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)( + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void* data); +typedef void(GLAPIENTRY* PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint lod, void* img); +typedef void(GLAPIENTRY* PFNGLLOADTRANSPOSEMATRIXDPROC)(const GLdouble m[16]); +typedef void(GLAPIENTRY* PFNGLLOADTRANSPOSEMATRIXFPROC)(const GLfloat m[16]); +typedef void(GLAPIENTRY* PFNGLMULTTRANSPOSEMATRIXDPROC)(const GLdouble m[16]); +typedef void(GLAPIENTRY* PFNGLMULTTRANSPOSEMATRIXFPROC)(const GLfloat m[16]); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD1DPROC)(GLenum target, GLdouble s); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD1DVPROC)(GLenum target, const GLdouble* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD1FPROC)(GLenum target, GLfloat s); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD1FVPROC)(GLenum target, const GLfloat* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD1IPROC)(GLenum target, GLint s); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD1IVPROC)(GLenum target, const GLint* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD1SPROC)(GLenum target, GLshort s); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD1SVPROC)(GLenum target, const GLshort* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD2DPROC)(GLenum target, GLdouble s, GLdouble t); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD2DVPROC)(GLenum target, const GLdouble* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD2FVPROC)(GLenum target, const GLfloat* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD2IPROC)(GLenum target, GLint s, GLint t); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD2IVPROC)(GLenum target, const GLint* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD2SPROC)(GLenum target, GLshort s, GLshort t); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD2SVPROC)(GLenum target, const GLshort* v); +typedef void( + GLAPIENTRY* PFNGLMULTITEXCOORD3DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD3DVPROC)(GLenum target, const GLdouble* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD3FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD3FVPROC)(GLenum target, const GLfloat* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD3IPROC)(GLenum target, GLint s, GLint t, GLint r); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD3IVPROC)(GLenum target, const GLint* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD3SPROC)(GLenum target, GLshort s, GLshort t, GLshort r); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD3SVPROC)(GLenum target, const GLshort* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD4DPROC)( + GLenum target, + GLdouble s, + GLdouble t, + GLdouble r, + GLdouble q); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD4DVPROC)(GLenum target, const GLdouble* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD4FPROC)( + GLenum target, + GLfloat s, + GLfloat t, + GLfloat r, + GLfloat q); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD4FVPROC)(GLenum target, const GLfloat* v); +typedef void( + GLAPIENTRY* PFNGLMULTITEXCOORD4IPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD4IVPROC)(GLenum target, const GLint* v); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD4SPROC)( + GLenum target, + GLshort s, + GLshort t, + GLshort r, + GLshort q); +typedef void(GLAPIENTRY* PFNGLMULTITEXCOORD4SVPROC)(GLenum target, const GLshort* v); +typedef void(GLAPIENTRY* PFNGLSAMPLECOVERAGEPROC)(GLclampf value, GLboolean invert); + +#define glActiveTexture GLEGetCurrentFunction(glActiveTexture) +#define glClientActiveTexture GLEGetCurrentFunction(glClientActiveTexture) +#define glCompressedTexImage1D GLEGetCurrentFunction(glCompressedTexImage1D) +#define glCompressedTexImage2D GLEGetCurrentFunction(glCompressedTexImage2D) +#define glCompressedTexImage3D GLEGetCurrentFunction(glCompressedTexImage3D) +#define glCompressedTexSubImage1D GLEGetCurrentFunction(glCompressedTexSubImage1D) +#define glCompressedTexSubImage2D GLEGetCurrentFunction(glCompressedTexSubImage2D) +#define glCompressedTexSubImage3D GLEGetCurrentFunction(glCompressedTexSubImage3D) +#define glGetCompressedTexImage GLEGetCurrentFunction(glGetCompressedTexImage) +#define glLoadTransposeMatrixd GLEGetCurrentFunction(glLoadTransposeMatrixd) +#define glLoadTransposeMatrixf GLEGetCurrentFunction(glLoadTransposeMatrixf) +#define glMultTransposeMatrixd GLEGetCurrentFunction(glMultTransposeMatrixd) +#define glMultTransposeMatrixf GLEGetCurrentFunction(glMultTransposeMatrixf) +#define glMultiTexCoord1d GLEGetCurrentFunction(glMultiTexCoord1d) +#define glMultiTexCoord1dv GLEGetCurrentFunction(glMultiTexCoord1dv) +#define glMultiTexCoord1f GLEGetCurrentFunction(glMultiTexCoord1f) +#define glMultiTexCoord1fv GLEGetCurrentFunction(glMultiTexCoord1fv) +#define glMultiTexCoord1i GLEGetCurrentFunction(glMultiTexCoord1i) +#define glMultiTexCoord1iv GLEGetCurrentFunction(glMultiTexCoord1iv) +#define glMultiTexCoord1s GLEGetCurrentFunction(glMultiTexCoord1s) +#define glMultiTexCoord1sv GLEGetCurrentFunction(glMultiTexCoord1sv) +#define glMultiTexCoord2d GLEGetCurrentFunction(glMultiTexCoord2d) +#define glMultiTexCoord2dv GLEGetCurrentFunction(glMultiTexCoord2dv) +#define glMultiTexCoord2f GLEGetCurrentFunction(glMultiTexCoord2f) +#define glMultiTexCoord2fv GLEGetCurrentFunction(glMultiTexCoord2fv) +#define glMultiTexCoord2i GLEGetCurrentFunction(glMultiTexCoord2i) +#define glMultiTexCoord2iv GLEGetCurrentFunction(glMultiTexCoord2iv) +#define glMultiTexCoord2s GLEGetCurrentFunction(glMultiTexCoord2s) +#define glMultiTexCoord2sv GLEGetCurrentFunction(glMultiTexCoord2sv) +#define glMultiTexCoord3d GLEGetCurrentFunction(glMultiTexCoord3d) +#define glMultiTexCoord3dv GLEGetCurrentFunction(glMultiTexCoord3dv) +#define glMultiTexCoord3f GLEGetCurrentFunction(glMultiTexCoord3f) +#define glMultiTexCoord3fv GLEGetCurrentFunction(glMultiTexCoord3fv) +#define glMultiTexCoord3i GLEGetCurrentFunction(glMultiTexCoord3i) +#define glMultiTexCoord3iv GLEGetCurrentFunction(glMultiTexCoord3iv) +#define glMultiTexCoord3s GLEGetCurrentFunction(glMultiTexCoord3s) +#define glMultiTexCoord3sv GLEGetCurrentFunction(glMultiTexCoord3sv) +#define glMultiTexCoord4d GLEGetCurrentFunction(glMultiTexCoord4d) +#define glMultiTexCoord4dv GLEGetCurrentFunction(glMultiTexCoord4dv) +#define glMultiTexCoord4f GLEGetCurrentFunction(glMultiTexCoord4f) +#define glMultiTexCoord4fv GLEGetCurrentFunction(glMultiTexCoord4fv) +#define glMultiTexCoord4i GLEGetCurrentFunction(glMultiTexCoord4i) +#define glMultiTexCoord4iv GLEGetCurrentFunction(glMultiTexCoord4iv) +#define glMultiTexCoord4s GLEGetCurrentFunction(glMultiTexCoord4s) +#define glMultiTexCoord4sv GLEGetCurrentFunction(glMultiTexCoord4sv) +#define glSampleCoverage GLEGetCurrentFunction(glSampleCoverage) + +#endif // GL_VERSION_1_3 + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 + +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E + +typedef void( + GLAPIENTRY* PFNGLBLENDCOLORPROC)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void(GLAPIENTRY* PFNGLBLENDEQUATIONPROC)(GLenum mode); +typedef void(GLAPIENTRY* PFNGLBLENDFUNCSEPARATEPROC)( + GLenum sfactorRGB, + GLenum dfactorRGB, + GLenum sfactorAlpha, + GLenum dfactorAlpha); +typedef void( + GLAPIENTRY* PFNGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void* pointer); +typedef void(GLAPIENTRY* PFNGLFOGCOORDDPROC)(GLdouble coord); +typedef void(GLAPIENTRY* PFNGLFOGCOORDDVPROC)(const GLdouble* coord); +typedef void(GLAPIENTRY* PFNGLFOGCOORDFPROC)(GLfloat coord); +typedef void(GLAPIENTRY* PFNGLFOGCOORDFVPROC)(const GLfloat* coord); +typedef void(GLAPIENTRY* PFNGLMULTIDRAWARRAYSPROC)( + GLenum mode, + const GLint* first, + const GLsizei* count, + GLsizei drawcount); +typedef void(GLAPIENTRY* PFNGLMULTIDRAWELEMENTSPROC)( + GLenum mode, + const GLsizei* count, + GLenum type, + const void* const* indices, + GLsizei drawcount); +typedef void(GLAPIENTRY* PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); +typedef void(GLAPIENTRY* PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat* params); +typedef void(GLAPIENTRY* PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); +typedef void(GLAPIENTRY* PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint* params); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3BVPROC)(const GLbyte* v); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3DVPROC)(const GLdouble* v); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3FVPROC)(const GLfloat* v); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3IPROC)(GLint red, GLint green, GLint blue); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3IVPROC)(const GLint* v); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3SVPROC)(const GLshort* v); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3UBVPROC)(const GLubyte* v); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3UIVPROC)(const GLuint* v); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLOR3USVPROC)(const GLushort* v); +typedef void(GLAPIENTRY* PFNGLSECONDARYCOLORPOINTERPROC)( + GLint size, + GLenum type, + GLsizei stride, + const void* pointer); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS2DPROC)(GLdouble x, GLdouble y); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS2DVPROC)(const GLdouble* p); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS2FPROC)(GLfloat x, GLfloat y); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS2FVPROC)(const GLfloat* p); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS2IPROC)(GLint x, GLint y); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS2IVPROC)(const GLint* p); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS2SPROC)(GLshort x, GLshort y); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS2SVPROC)(const GLshort* p); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS3DVPROC)(const GLdouble* p); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS3FVPROC)(const GLfloat* p); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS3IPROC)(GLint x, GLint y, GLint z); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS3IVPROC)(const GLint* p); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); +typedef void(GLAPIENTRY* PFNGLWINDOWPOS3SVPROC)(const GLshort* p); + +#define glBlendColor GLEGetCurrentFunction(glBlendColor) +#define glBlendEquation GLEGetCurrentFunction(glBlendEquation) +#define glBlendFuncSeparate GLEGetCurrentFunction(glBlendFuncSeparate) +#define glFogCoordPointer GLEGetCurrentFunction(glFogCoordPointer) +#define glFogCoordd GLEGetCurrentFunction(glFogCoordd) +#define glFogCoorddv GLEGetCurrentFunction(glFogCoorddv) +#define glFogCoordf GLEGetCurrentFunction(glFogCoordf) +#define glFogCoordfv GLEGetCurrentFunction(glFogCoordfv) +#define glMultiDrawArrays GLEGetCurrentFunction(glMultiDrawArrays) +#define glMultiDrawElements GLEGetCurrentFunction(glMultiDrawElements) +#define glPointParameterf GLEGetCurrentFunction(glPointParameterf) +#define glPointParameterfv GLEGetCurrentFunction(glPointParameterfv) +#define glPointParameteri GLEGetCurrentFunction(glPointParameteri) +#define glPointParameteriv GLEGetCurrentFunction(glPointParameteriv) +#define glSecondaryColor3b GLEGetCurrentFunction(glSecondaryColor3b) +#define glSecondaryColor3bv GLEGetCurrentFunction(glSecondaryColor3bv) +#define glSecondaryColor3d GLEGetCurrentFunction(glSecondaryColor3d) +#define glSecondaryColor3dv GLEGetCurrentFunction(glSecondaryColor3dv) +#define glSecondaryColor3f GLEGetCurrentFunction(glSecondaryColor3f) +#define glSecondaryColor3fv GLEGetCurrentFunction(glSecondaryColor3fv) +#define glSecondaryColor3i GLEGetCurrentFunction(glSecondaryColor3i) +#define glSecondaryColor3iv GLEGetCurrentFunction(glSecondaryColor3iv) +#define glSecondaryColor3s GLEGetCurrentFunction(glSecondaryColor3s) +#define glSecondaryColor3sv GLEGetCurrentFunction(glSecondaryColor3sv) +#define glSecondaryColor3ub GLEGetCurrentFunction(glSecondaryColor3ub) +#define glSecondaryColor3ubv GLEGetCurrentFunction(glSecondaryColor3ubv) +#define glSecondaryColor3ui GLEGetCurrentFunction(glSecondaryColor3ui) +#define glSecondaryColor3uiv GLEGetCurrentFunction(glSecondaryColor3uiv) +#define glSecondaryColor3us GLEGetCurrentFunction(glSecondaryColor3us) +#define glSecondaryColor3usv GLEGetCurrentFunction(glSecondaryColor3usv) +#define glSecondaryColorPointer GLEGetCurrentFunction(glSecondaryColorPointer) +#define glWindowPos2d GLEGetCurrentFunction(glWindowPos2d) +#define glWindowPos2dv GLEGetCurrentFunction(glWindowPos2dv) +#define glWindowPos2f GLEGetCurrentFunction(glWindowPos2f) +#define glWindowPos2fv GLEGetCurrentFunction(glWindowPos2fv) +#define glWindowPos2i GLEGetCurrentFunction(glWindowPos2i) +#define glWindowPos2iv GLEGetCurrentFunction(glWindowPos2iv) +#define glWindowPos2s GLEGetCurrentFunction(glWindowPos2s) +#define glWindowPos2sv GLEGetCurrentFunction(glWindowPos2sv) +#define glWindowPos3d GLEGetCurrentFunction(glWindowPos3d) +#define glWindowPos3dv GLEGetCurrentFunction(glWindowPos3dv) +#define glWindowPos3f GLEGetCurrentFunction(glWindowPos3f) +#define glWindowPos3fv GLEGetCurrentFunction(glWindowPos3fv) +#define glWindowPos3i GLEGetCurrentFunction(glWindowPos3i) +#define glWindowPos3iv GLEGetCurrentFunction(glWindowPos3iv) +#define glWindowPos3s GLEGetCurrentFunction(glWindowPos3s) +#define glWindowPos3sv GLEGetCurrentFunction(glWindowPos3sv) + +#endif // GL_VERSION_1_4 + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 + +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 + +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; + +typedef void(GLAPIENTRY* PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); +typedef void(GLAPIENTRY* PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); +typedef void(GLAPIENTRY* PFNGLBUFFERDATAPROC)( + GLenum target, + GLsizeiptr size, + const void* data, + GLenum usage); +typedef void(GLAPIENTRY* PFNGLBUFFERSUBDATAPROC)( + GLenum target, + GLintptr offset, + GLsizeiptr size, + const void* data); +typedef void(GLAPIENTRY* PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint* buffers); +typedef void(GLAPIENTRY* PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint* ids); +typedef void(GLAPIENTRY* PFNGLENDQUERYPROC)(GLenum target); +typedef void(GLAPIENTRY* PFNGLGENBUFFERSPROC)(GLsizei n, GLuint* buffers); +typedef void(GLAPIENTRY* PFNGLGENQUERIESPROC)(GLsizei n, GLuint* ids); +typedef void(GLAPIENTRY* PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint* params); +typedef void(GLAPIENTRY* PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void** params); +typedef void(GLAPIENTRY* PFNGLGETBUFFERSUBDATAPROC)( + GLenum target, + GLintptr offset, + GLsizeiptr size, + void* data); +typedef void(GLAPIENTRY* PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint* params); +typedef void(GLAPIENTRY* PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint* params); +typedef void(GLAPIENTRY* PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint* params); +typedef GLboolean(GLAPIENTRY* PFNGLISBUFFERPROC)(GLuint buffer); +typedef GLboolean(GLAPIENTRY* PFNGLISQUERYPROC)(GLuint id); +typedef void*(GLAPIENTRY* PFNGLMAPBUFFERPROC)(GLenum target, GLenum access); +typedef GLboolean(GLAPIENTRY* PFNGLUNMAPBUFFERPROC)(GLenum target); + +#define glBeginQuery GLEGetCurrentFunction(glBeginQuery) +#define glBindBuffer GLEGetCurrentFunction(glBindBuffer) +#define glBufferData GLEGetCurrentFunction(glBufferData) +#define glBufferSubData GLEGetCurrentFunction(glBufferSubData) +#define glDeleteBuffers GLEGetCurrentFunction(glDeleteBuffers) +#define glDeleteQueries GLEGetCurrentFunction(glDeleteQueries) +#define glEndQuery GLEGetCurrentFunction(glEndQuery) +#define glGenBuffers GLEGetCurrentFunction(glGenBuffers) +#define glGenQueries GLEGetCurrentFunction(glGenQueries) +#define glGetBufferParameteriv GLEGetCurrentFunction(glGetBufferParameteriv) +#define glGetBufferPointerv GLEGetCurrentFunction(glGetBufferPointerv) +#define glGetBufferSubData GLEGetCurrentFunction(glGetBufferSubData) +#define glGetQueryObjectiv GLEGetCurrentFunction(glGetQueryObjectiv) +#define glGetQueryObjectuiv GLEGetCurrentFunction(glGetQueryObjectuiv) +#define glGetQueryiv GLEGetCurrentFunction(glGetQueryiv) +#define glIsBuffer GLEGetCurrentFunction(glIsBuffer) +#define glIsQuery GLEGetCurrentFunction(glIsQuery) +#define glMapBuffer GLEGetCurrentFunction(glMapBuffer) +#define glUnmapBuffer GLEGetCurrentFunction(glUnmapBuffer) + +#endif // GL_VERSION_1_5 + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 + +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_COMPUTE_SHADER 0x91B9 + +typedef void(GLAPIENTRY* PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); +typedef void( + GLAPIENTRY* PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar* name); +typedef void(GLAPIENTRY* PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); +typedef void(GLAPIENTRY* PFNGLCOMPILESHADERPROC)(GLuint shader); +typedef GLuint(GLAPIENTRY* PFNGLCREATEPROGRAMPROC)(void); +typedef GLuint(GLAPIENTRY* PFNGLCREATESHADERPROC)(GLenum type); +typedef void(GLAPIENTRY* PFNGLDELETEPROGRAMPROC)(GLuint program); +typedef void(GLAPIENTRY* PFNGLDELETESHADERPROC)(GLuint shader); +typedef void(GLAPIENTRY* PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); +typedef void(GLAPIENTRY* PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void(GLAPIENTRY* PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum* bufs); +typedef void(GLAPIENTRY* PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void(GLAPIENTRY* PFNGLGETACTIVEATTRIBPROC)( + GLuint program, + GLuint index, + GLsizei maxLength, + GLsizei* length, + GLint* size, + GLenum* type, + GLchar* name); +typedef void(GLAPIENTRY* PFNGLGETACTIVEUNIFORMPROC)( + GLuint program, + GLuint index, + GLsizei maxLength, + GLsizei* length, + GLint* size, + GLenum* type, + GLchar* name); +typedef void(GLAPIENTRY* PFNGLGETATTACHEDSHADERSPROC)( + GLuint program, + GLsizei maxCount, + GLsizei* count, + GLuint* shaders); +typedef GLint(GLAPIENTRY* PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar* name); +typedef void(GLAPIENTRY* PFNGLGETPROGRAMINFOLOGPROC)( + GLuint program, + GLsizei bufSize, + GLsizei* length, + GLchar* infoLog); +typedef void(GLAPIENTRY* PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint* param); +typedef void(GLAPIENTRY* PFNGLGETSHADERINFOLOGPROC)( + GLuint shader, + GLsizei bufSize, + GLsizei* length, + GLchar* infoLog); +typedef void(GLAPIENTRY* PFNGLGETSHADERSOURCEPROC)( + GLuint obj, + GLsizei maxLength, + GLsizei* length, + GLchar* source); +typedef void(GLAPIENTRY* PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint* param); +typedef GLint(GLAPIENTRY* PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar* name); +typedef void(GLAPIENTRY* PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat* params); +typedef void(GLAPIENTRY* PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint* params); +typedef void( + GLAPIENTRY* PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void** pointer); +typedef void(GLAPIENTRY* PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble* params); +typedef void(GLAPIENTRY* PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat* params); +typedef void(GLAPIENTRY* PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint* params); +typedef GLboolean(GLAPIENTRY* PFNGLISPROGRAMPROC)(GLuint program); +typedef GLboolean(GLAPIENTRY* PFNGLISSHADERPROC)(GLuint shader); +typedef void(GLAPIENTRY* PFNGLLINKPROGRAMPROC)(GLuint program); +typedef void(GLAPIENTRY* PFNGLSHADERSOURCEPROC)( + GLuint shader, + GLsizei count, + const GLchar* const* string, + const GLint* length); +typedef void(GLAPIENTRY* PFNGLSTENCILFUNCSEPARATEPROC)( + GLenum frontfunc, + GLenum backfunc, + GLint ref, + GLuint mask); +typedef void(GLAPIENTRY* PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); +typedef void(GLAPIENTRY* PFNGLSTENCILOPSEPARATEPROC)( + GLenum face, + GLenum sfail, + GLenum dpfail, + GLenum dppass); +typedef void(GLAPIENTRY* PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); +typedef void(GLAPIENTRY* PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUNIFORM1IPROC)(GLint location, GLint v0); +typedef void(GLAPIENTRY* PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint* value); +typedef void(GLAPIENTRY* PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); +typedef void(GLAPIENTRY* PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); +typedef void(GLAPIENTRY* PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint* value); +typedef void(GLAPIENTRY* PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void(GLAPIENTRY* PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); +typedef void(GLAPIENTRY* PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint* value); +typedef void( + GLAPIENTRY* PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void(GLAPIENTRY* PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat* value); +typedef void( + GLAPIENTRY* PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void(GLAPIENTRY* PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint* value); +typedef void(GLAPIENTRY* PFNGLUNIFORMMATRIX2FVPROC)( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUNIFORMMATRIX3FVPROC)( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUNIFORMMATRIX4FVPROC)( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUSEPROGRAMPROC)(GLuint program); +typedef void(GLAPIENTRY* PFNGLVALIDATEPROGRAMPROC)(GLuint program); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4NUBPROC)( + GLuint index, + GLubyte x, + GLubyte y, + GLubyte z, + GLubyte w); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4DPROC)( + GLuint index, + GLdouble x, + GLdouble y, + GLdouble z, + GLdouble w); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble* v); +typedef void( + GLAPIENTRY* PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint* v); +typedef void( + GLAPIENTRY* PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort* v); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBPOINTERPROC)( + GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void* pointer); + +#define glAttachShader GLEGetCurrentFunction(glAttachShader) +#define glBindAttribLocation GLEGetCurrentFunction(glBindAttribLocation) +#define glBlendEquationSeparate GLEGetCurrentFunction(glBlendEquationSeparate) +#define glCompileShader GLEGetCurrentFunction(glCompileShader) +#define glCreateProgram GLEGetCurrentFunction(glCreateProgram) +#define glCreateShader GLEGetCurrentFunction(glCreateShader) +#define glDeleteProgram GLEGetCurrentFunction(glDeleteProgram) +#define glDeleteShader GLEGetCurrentFunction(glDeleteShader) +#define glDetachShader GLEGetCurrentFunction(glDetachShader) +#define glDisableVertexAttribArray GLEGetCurrentFunction(glDisableVertexAttribArray) +#define glDrawBuffers GLEGetCurrentFunction(glDrawBuffers) +#define glEnableVertexAttribArray GLEGetCurrentFunction(glEnableVertexAttribArray) +#define glGetActiveAttrib GLEGetCurrentFunction(glGetActiveAttrib) +#define glGetActiveUniform GLEGetCurrentFunction(glGetActiveUniform) +#define glGetAttachedShaders GLEGetCurrentFunction(glGetAttachedShaders) +#define glGetAttribLocation GLEGetCurrentFunction(glGetAttribLocation) +#define glGetProgramInfoLog GLEGetCurrentFunction(glGetProgramInfoLog) +#define glGetProgramiv GLEGetCurrentFunction(glGetProgramiv) +#define glGetShaderInfoLog GLEGetCurrentFunction(glGetShaderInfoLog) +#define glGetShaderSource GLEGetCurrentFunction(glGetShaderSource) +#define glGetShaderiv GLEGetCurrentFunction(glGetShaderiv) +#define glGetUniformLocation GLEGetCurrentFunction(glGetUniformLocation) +#define glGetUniformfv GLEGetCurrentFunction(glGetUniformfv) +#define glGetUniformiv GLEGetCurrentFunction(glGetUniformiv) +#define glGetVertexAttribPointerv GLEGetCurrentFunction(glGetVertexAttribPointerv) +#define glGetVertexAttribdv GLEGetCurrentFunction(glGetVertexAttribdv) +#define glGetVertexAttribfv GLEGetCurrentFunction(glGetVertexAttribfv) +#define glGetVertexAttribiv GLEGetCurrentFunction(glGetVertexAttribiv) +#define glIsProgram GLEGetCurrentFunction(glIsProgram) +#define glIsShader GLEGetCurrentFunction(glIsShader) +#define glLinkProgram GLEGetCurrentFunction(glLinkProgram) +#define glShaderSource GLEGetCurrentFunction(glShaderSource) +#define glStencilFuncSeparate GLEGetCurrentFunction(glStencilFuncSeparate) +#define glStencilMaskSeparate GLEGetCurrentFunction(glStencilMaskSeparate) +#define glStencilOpSeparate GLEGetCurrentFunction(glStencilOpSeparate) +#define glUniform1f GLEGetCurrentFunction(glUniform1f) +#define glUniform1fv GLEGetCurrentFunction(glUniform1fv) +#define glUniform1i GLEGetCurrentFunction(glUniform1i) +#define glUniform1iv GLEGetCurrentFunction(glUniform1iv) +#define glUniform2f GLEGetCurrentFunction(glUniform2f) +#define glUniform2fv GLEGetCurrentFunction(glUniform2fv) +#define glUniform2i GLEGetCurrentFunction(glUniform2i) +#define glUniform2iv GLEGetCurrentFunction(glUniform2iv) +#define glUniform3f GLEGetCurrentFunction(glUniform3f) +#define glUniform3fv GLEGetCurrentFunction(glUniform3fv) +#define glUniform3i GLEGetCurrentFunction(glUniform3i) +#define glUniform3iv GLEGetCurrentFunction(glUniform3iv) +#define glUniform4f GLEGetCurrentFunction(glUniform4f) +#define glUniform4fv GLEGetCurrentFunction(glUniform4fv) +#define glUniform4i GLEGetCurrentFunction(glUniform4i) +#define glUniform4iv GLEGetCurrentFunction(glUniform4iv) +#define glUniformMatrix2fv GLEGetCurrentFunction(glUniformMatrix2fv) +#define glUniformMatrix3fv GLEGetCurrentFunction(glUniformMatrix3fv) +#define glUniformMatrix4fv GLEGetCurrentFunction(glUniformMatrix4fv) +#define glUseProgram GLEGetCurrentFunction(glUseProgram) +#define glValidateProgram GLEGetCurrentFunction(glValidateProgram) +#define glVertexAttrib1d GLEGetCurrentFunction(glVertexAttrib1d) +#define glVertexAttrib1dv GLEGetCurrentFunction(glVertexAttrib1dv) +#define glVertexAttrib1f GLEGetCurrentFunction(glVertexAttrib1f) +#define glVertexAttrib1fv GLEGetCurrentFunction(glVertexAttrib1fv) +#define glVertexAttrib1s GLEGetCurrentFunction(glVertexAttrib1s) +#define glVertexAttrib1sv GLEGetCurrentFunction(glVertexAttrib1sv) +#define glVertexAttrib2d GLEGetCurrentFunction(glVertexAttrib2d) +#define glVertexAttrib2dv GLEGetCurrentFunction(glVertexAttrib2dv) +#define glVertexAttrib2f GLEGetCurrentFunction(glVertexAttrib2f) +#define glVertexAttrib2fv GLEGetCurrentFunction(glVertexAttrib2fv) +#define glVertexAttrib2s GLEGetCurrentFunction(glVertexAttrib2s) +#define glVertexAttrib2sv GLEGetCurrentFunction(glVertexAttrib2sv) +#define glVertexAttrib3d GLEGetCurrentFunction(glVertexAttrib3d) +#define glVertexAttrib3dv GLEGetCurrentFunction(glVertexAttrib3dv) +#define glVertexAttrib3f GLEGetCurrentFunction(glVertexAttrib3f) +#define glVertexAttrib3fv GLEGetCurrentFunction(glVertexAttrib3fv) +#define glVertexAttrib3s GLEGetCurrentFunction(glVertexAttrib3s) +#define glVertexAttrib3sv GLEGetCurrentFunction(glVertexAttrib3sv) +#define glVertexAttrib4Nbv GLEGetCurrentFunction(glVertexAttrib4Nbv) +#define glVertexAttrib4Niv GLEGetCurrentFunction(glVertexAttrib4Niv) +#define glVertexAttrib4Nsv GLEGetCurrentFunction(glVertexAttrib4Nsv) +#define glVertexAttrib4Nub GLEGetCurrentFunction(glVertexAttrib4Nub) +#define glVertexAttrib4Nubv GLEGetCurrentFunction(glVertexAttrib4Nubv) +#define glVertexAttrib4Nuiv GLEGetCurrentFunction(glVertexAttrib4Nuiv) +#define glVertexAttrib4Nusv GLEGetCurrentFunction(glVertexAttrib4Nusv) +#define glVertexAttrib4bv GLEGetCurrentFunction(glVertexAttrib4bv) +#define glVertexAttrib4d GLEGetCurrentFunction(glVertexAttrib4d) +#define glVertexAttrib4dv GLEGetCurrentFunction(glVertexAttrib4dv) +#define glVertexAttrib4f GLEGetCurrentFunction(glVertexAttrib4f) +#define glVertexAttrib4fv GLEGetCurrentFunction(glVertexAttrib4fv) +#define glVertexAttrib4iv GLEGetCurrentFunction(glVertexAttrib4iv) +#define glVertexAttrib4s GLEGetCurrentFunction(glVertexAttrib4s) +#define glVertexAttrib4sv GLEGetCurrentFunction(glVertexAttrib4sv) +#define glVertexAttrib4ubv GLEGetCurrentFunction(glVertexAttrib4ubv) +#define glVertexAttrib4uiv GLEGetCurrentFunction(glVertexAttrib4uiv) +#define glVertexAttrib4usv GLEGetCurrentFunction(glVertexAttrib4usv) +#define glVertexAttribPointer GLEGetCurrentFunction(glVertexAttribPointer) + +#endif // GL_VERSION_2_0 + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 + +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B + +typedef void(GLAPIENTRY* PFNGLUNIFORMMATRIX2X3FVPROC)( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUNIFORMMATRIX2X4FVPROC)( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUNIFORMMATRIX3X2FVPROC)( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUNIFORMMATRIX3X4FVPROC)( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUNIFORMMATRIX4X2FVPROC)( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); +typedef void(GLAPIENTRY* PFNGLUNIFORMMATRIX4X3FVPROC)( + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat* value); + +#define glUniformMatrix2x3fv GLEGetCurrentFunction(glUniformMatrix2x3fv) +#define glUniformMatrix2x4fv GLEGetCurrentFunction(glUniformMatrix2x4fv) +#define glUniformMatrix3x2fv GLEGetCurrentFunction(glUniformMatrix3x2fv) +#define glUniformMatrix3x4fv GLEGetCurrentFunction(glUniformMatrix3x4fv) +#define glUniformMatrix4x2fv GLEGetCurrentFunction(glUniformMatrix4x2fv) +#define glUniformMatrix4x3fv GLEGetCurrentFunction(glUniformMatrix4x3fv) + +#endif // GL_VERSION_2_1 + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 + +#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 +#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 +#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 +#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 +#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 +#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 +#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB +#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES +#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_DEPTH_BUFFER 0x8223 +#define GL_STENCIL_BUFFER 0x8224 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 + +typedef void(GLAPIENTRY* PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode); +typedef void(GLAPIENTRY* PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); +typedef void(GLAPIENTRY* PFNGLBINDFRAGDATALOCATIONPROC)( + GLuint program, + GLuint colorNumber, + const GLchar* name); +typedef void(GLAPIENTRY* PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp); +typedef void(GLAPIENTRY* PFNGLCLEARBUFFERFIPROC)( + GLenum buffer, + GLint drawBuffer, + GLfloat depth, + GLint stencil); +typedef void( + GLAPIENTRY* PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawBuffer, const GLfloat* value); +typedef void( + GLAPIENTRY* PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawBuffer, const GLint* value); +typedef void( + GLAPIENTRY* PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawBuffer, const GLuint* value); +typedef void(GLAPIENTRY* PFNGLCOLORMASKIPROC)( + GLuint buf, + GLboolean red, + GLboolean green, + GLboolean blue, + GLboolean alpha); +typedef void(GLAPIENTRY* PFNGLDISABLEIPROC)(GLenum cap, GLuint index); +typedef void(GLAPIENTRY* PFNGLENABLEIPROC)(GLenum cap, GLuint index); +typedef void(GLAPIENTRY* PFNGLENDCONDITIONALRENDERPROC)(void); +typedef void(GLAPIENTRY* PFNGLENDTRANSFORMFEEDBACKPROC)(void); +typedef void(GLAPIENTRY* PFNGLBINDBUFFERRANGEPROC)( + GLenum target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size); +typedef void(GLAPIENTRY* PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); +typedef void(GLAPIENTRY* PFNGLGETBOOLEANI_VPROC)(GLenum pname, GLuint index, GLboolean* data); +typedef void(GLAPIENTRY* PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint* data); +typedef GLint(GLAPIENTRY* PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar* name); +typedef const GLubyte*(GLAPIENTRY* PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); +typedef void(GLAPIENTRY* PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint* params); +typedef void(GLAPIENTRY* PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint* params); +typedef void(GLAPIENTRY* PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)( + GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei* length, + GLsizei* size, + GLenum* type, + GLchar* name); +typedef void(GLAPIENTRY* PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint* params); +typedef void(GLAPIENTRY* PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint* params); +typedef void(GLAPIENTRY* PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint* params); +typedef GLboolean(GLAPIENTRY* PFNGLISENABLEDIPROC)(GLenum cap, GLuint index); +typedef void( + GLAPIENTRY* PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint* params); +typedef void( + GLAPIENTRY* PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint* params); +typedef void(GLAPIENTRY* PFNGLTRANSFORMFEEDBACKVARYINGSPROC)( + GLuint program, + GLsizei count, + const GLchar* const* varyings, + GLenum bufferMode); +typedef void(GLAPIENTRY* PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); +typedef void(GLAPIENTRY* PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint* value); +typedef void(GLAPIENTRY* PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); +typedef void(GLAPIENTRY* PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint* value); +typedef void(GLAPIENTRY* PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void(GLAPIENTRY* PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint* value); +typedef void( + GLAPIENTRY* PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void(GLAPIENTRY* PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint* value); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint v0, GLint v1); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint v0, GLuint v1); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint v0, GLint v1, GLint v2); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint v0, GLuint v1, GLuint v2); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte* v0); +typedef void( + GLAPIENTRY* PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI4UIPROC)( + GLuint index, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort* v0); +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBIPOINTERPROC)( + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const void* pointer); + +#define glBeginConditionalRender GLEGetCurrentFunction(glBeginConditionalRender) +#define glBeginTransformFeedback GLEGetCurrentFunction(glBeginTransformFeedback) +#define glBindFragDataLocation GLEGetCurrentFunction(glBindFragDataLocation) +#define glClampColor GLEGetCurrentFunction(glClampColor) +#define glClearBufferfi GLEGetCurrentFunction(glClearBufferfi) +#define glClearBufferfv GLEGetCurrentFunction(glClearBufferfv) +#define glClearBufferiv GLEGetCurrentFunction(glClearBufferiv) +#define glClearBufferuiv GLEGetCurrentFunction(glClearBufferuiv) +#define glColorMaski GLEGetCurrentFunction(glColorMaski) +#define glDisablei GLEGetCurrentFunction(glDisablei) +#define glEnablei GLEGetCurrentFunction(glEnablei) +#define glEndConditionalRender GLEGetCurrentFunction(glEndConditionalRender) +#define glEndTransformFeedback GLEGetCurrentFunction(glEndTransformFeedback) +#define glGetBooleani_v GLEGetCurrentFunction(glGetBooleani_v) +#define glGetIntegeri_v GLEGetCurrentFunction(glGetIntegeri_v) +#define glGetFragDataLocation GLEGetCurrentFunction(glGetFragDataLocation) +#define glGetStringi GLEGetCurrentFunction(glGetStringi) +#define glGetTexParameterIiv GLEGetCurrentFunction(glGetTexParameterIiv) +#define glGetTexParameterIuiv GLEGetCurrentFunction(glGetTexParameterIuiv) +#define glGetTransformFeedbackVarying GLEGetCurrentFunction(glGetTransformFeedbackVarying) +#define glGetUniformuiv GLEGetCurrentFunction(glGetUniformuiv) +#define glGetVertexAttribIiv GLEGetCurrentFunction(glGetVertexAttribIiv) +#define glGetVertexAttribIuiv GLEGetCurrentFunction(glGetVertexAttribIuiv) +#define glIsEnabledi GLEGetCurrentFunction(glIsEnabledi) +#define glTexParameterIiv GLEGetCurrentFunction(glTexParameterIiv) +#define glTexParameterIuiv GLEGetCurrentFunction(glTexParameterIuiv) +#define glTransformFeedbackVaryings GLEGetCurrentFunction(glTransformFeedbackVaryings) +#define glUniform1ui GLEGetCurrentFunction(glUniform1ui) +#define glUniform1uiv GLEGetCurrentFunction(glUniform1uiv) +#define glUniform2ui GLEGetCurrentFunction(glUniform2ui) +#define glUniform2uiv GLEGetCurrentFunction(glUniform2uiv) +#define glUniform3ui GLEGetCurrentFunction(glUniform3ui) +#define glUniform3uiv GLEGetCurrentFunction(glUniform3uiv) +#define glUniform4ui GLEGetCurrentFunction(glUniform4ui) +#define glUniform4uiv GLEGetCurrentFunction(glUniform4uiv) +#define glVertexAttribI1i GLEGetCurrentFunction(glVertexAttribI1i) +#define glVertexAttribI1iv GLEGetCurrentFunction(glVertexAttribI1iv) +#define glVertexAttribI1ui GLEGetCurrentFunction(glVertexAttribI1ui) +#define glVertexAttribI1uiv GLEGetCurrentFunction(glVertexAttribI1uiv) +#define glVertexAttribI2i GLEGetCurrentFunction(glVertexAttribI2i) +#define glVertexAttribI2iv GLEGetCurrentFunction(glVertexAttribI2iv) +#define glVertexAttribI2ui GLEGetCurrentFunction(glVertexAttribI2ui) +#define glVertexAttribI2uiv GLEGetCurrentFunction(glVertexAttribI2uiv) +#define glVertexAttribI3i GLEGetCurrentFunction(glVertexAttribI3i) +#define glVertexAttribI3iv GLEGetCurrentFunction(glVertexAttribI3iv) +#define glVertexAttribI3ui GLEGetCurrentFunction(glVertexAttribI3ui) +#define glVertexAttribI3uiv GLEGetCurrentFunction(glVertexAttribI3uiv) +#define glVertexAttribI4bv GLEGetCurrentFunction(glVertexAttribI4bv) +#define glVertexAttribI4i GLEGetCurrentFunction(glVertexAttribI4i) +#define glVertexAttribI4iv GLEGetCurrentFunction(glVertexAttribI4iv) +#define glVertexAttribI4sv GLEGetCurrentFunction(glVertexAttribI4sv) +#define glVertexAttribI4ubv GLEGetCurrentFunction(glVertexAttribI4ubv) +#define glVertexAttribI4ui GLEGetCurrentFunction(glVertexAttribI4ui) +#define glVertexAttribI4uiv GLEGetCurrentFunction(glVertexAttribI4uiv) +#define glVertexAttribI4usv GLEGetCurrentFunction(glVertexAttribI4usv) +#define glVertexAttribIPointer GLEGetCurrentFunction(glVertexAttribIPointer) + +#endif // GL_VERSION_3_0 + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 + +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 + +typedef void(GLAPIENTRY* PFNGLDRAWARRAYSINSTANCEDPROC)( + GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount); +typedef void(GLAPIENTRY* PFNGLDRAWELEMENTSINSTANCEDPROC)( + GLenum mode, + GLsizei count, + GLenum type, + const void* indices, + GLsizei primcount); +typedef void(GLAPIENTRY* PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint buffer); +typedef void(GLAPIENTRY* PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalFormat, GLuint buffer); + +#define glDrawArraysInstanced GLEGetCurrentFunction(glDrawArraysInstanced) +#define glDrawElementsInstanced GLEGetCurrentFunction(glDrawElementsInstanced) +#define glPrimitiveRestartIndex GLEGetCurrentFunction(glPrimitiveRestartIndex) +#define glTexBuffer GLEGetCurrentFunction(glTexBuffer) + +#endif // GL_VERSION_3_1 + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 + +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 + +typedef void(GLAPIENTRY* PFNGLFRAMEBUFFERTEXTUREPROC)( + GLenum target, + GLenum attachment, + GLuint texture, + GLint level); +typedef void( + GLAPIENTRY* PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum value, GLint64* data); +typedef void(GLAPIENTRY* PFNGLGETINTEGER64I_VPROC)(GLenum pname, GLuint index, GLint64* data); + +#define glFramebufferTexture GLEGetCurrentFunction(glFramebufferTexture) +#define glGetBufferParameteri64v GLEGetCurrentFunction(glGetBufferParameteri64v) +#define glGetInteger64i_v GLEGetCurrentFunction(glGetInteger64i_v) + +#endif // GL_VERSION_3_2 + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_RGB10_A2UI 0x906F + +typedef void(GLAPIENTRY* PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); + +#define glVertexAttribDivisor GLEGetCurrentFunction(glVertexAttribDivisor) +#endif + +#ifndef GL_VERSION_4_0 +#define GL_VERSION_4_0 1 + +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F + +typedef void( + GLAPIENTRY* PFNGLBLENDEQUATIONSEPARATEIPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void(GLAPIENTRY* PFNGLBLENDEQUATIONIPROC)(GLuint buf, GLenum mode); +typedef void(GLAPIENTRY* PFNGLBLENDFUNCSEPARATEIPROC)( + GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha); +typedef void(GLAPIENTRY* PFNGLBLENDFUNCIPROC)(GLuint buf, GLenum src, GLenum dst); +typedef void(GLAPIENTRY* PFNGLMINSAMPLESHADINGPROC)(GLclampf value); + +#define glBlendEquationSeparatei GLEGetCurrentFunction(glBlendEquationSeparatei) +#define glBlendEquationi GLEGetCurrentFunction(glBlendEquationi) +#define glBlendFuncSeparatei GLEGetCurrentFunction(glBlendFuncSeparatei) +#define glBlendFunci GLEGetCurrentFunction(glBlendFunci) +#define glMinSampleShading GLEGetCurrentFunction(glMinSampleShading) + +#endif // GL_VERSION_4_0 + +#ifndef GL_VERSION_4_1 +#define GL_VERSION_4_1 1 +// Empty +#endif + +#ifndef GL_VERSION_4_2 +#define GL_VERSION_4_2 1 + +typedef void(GLAPIENTRY* PFNGLMEMORYBARRIER)(GLbitfield barriers); + +#define glMemoryBarrier GLEGetCurrentFunction(glMemoryBarrier) + +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F + +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF + +#endif + +#ifndef GL_VERSION_4_3 +#define GL_VERSION_4_3 1 + +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#endif + +typedef void(GLAPIENTRY* PFNGLDISPATCHCOMPUTEPROC)( + GLuint num_groups_x, + GLuint num_groups_y, + GLuint num_groups_z); +typedef void(GLAPIENTRY* PFNGLBINDIMAGETEXTUREPROC)( + GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); + +#define glDispatchCompute GLEGetCurrentFunction(glDispatchCompute) +#define glBindImageTexture GLEGetCurrentFunction(glBindImageTexture); + +#ifndef GL_VERSION_4_4 +#define GL_VERSION_4_4 1 + +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#endif + +#ifndef GL_VERSION_4_5 +#define GL_VERSION_4_5 1 +// Empty +#endif + +#ifndef GL_AMD_debug_output +#define GL_AMD_debug_output 1 + +#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 +#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 +#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 +#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A +#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B +#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C +#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D +#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E +#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F +#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 + +typedef void(GLAPIENTRY* GLDEBUGPROCAMD)( + GLuint id, + GLenum category, + GLenum severity, + GLsizei length, + const GLchar* message, + void* userParam); + +typedef void( + GLAPIENTRY* PFNGLDEBUGMESSAGECALLBACKAMDPROC)(GLDEBUGPROCAMD callback, void* userParam); +typedef void(GLAPIENTRY* PFNGLDEBUGMESSAGEENABLEAMDPROC)( + GLenum category, + GLenum severity, + GLsizei count, + const GLuint* ids, + GLboolean enabled); +typedef void(GLAPIENTRY* PFNGLDEBUGMESSAGEINSERTAMDPROC)( + GLenum category, + GLenum severity, + GLuint id, + GLsizei length, + const GLchar* buf); +typedef GLuint(GLAPIENTRY* PFNGLGETDEBUGMESSAGELOGAMDPROC)( + GLuint count, + GLsizei bufsize, + GLenum* categories, + GLuint* severities, + GLuint* ids, + GLsizei* lengths, + GLchar* message); + +#define glDebugMessageCallbackAMD GLEGetCurrentFunction(glDebugMessageCallbackAMD) +#define glDebugMessageEnableAMD GLEGetCurrentFunction(glDebugMessageEnableAMD) +#define glDebugMessageInsertAMD GLEGetCurrentFunction(glDebugMessageInsertAMD) +#define glGetDebugMessageLogAMD GLEGetCurrentFunction(glGetDebugMessageLogAMD) + +#define GLE_AMD_debug_output GLEGetCurrentVariable(gle_AMD_debug_output) + +#endif // GL_AMD_debug_output + +/* Disabled until needed +#ifndef GL_AMD_performance_monitor + #define GL_AMD_performance_monitor 1 + + #define GL_COUNTER_TYPE_AMD 0x8BC0 + #define GL_COUNTER_RANGE_AMD 0x8BC1 + #define GL_UNSIGNED_INT64_AMD 0x8BC2 + #define GL_PERCENTAGE_AMD 0x8BC3 + #define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 + #define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 + #define GL_PERFMON_RESULT_AMD 0x8BC6 + + typedef void (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); + typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); + typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); + typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, +GLsizei dataSize, GLuint* data, GLint *bytesWritten); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, +GLenum pname, void *data); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint +counter, GLsizei bufSize, GLsizei* length, GLchar *counterString); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* +numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei +bufSize, GLsizei* length, GLchar *groupString); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei +groupsSize, GLuint *groups); + typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean +enable, GLuint group, GLint numCounters, GLuint* counterList); + + #define glBeginPerfMonitorAMD GLEGetCurrentFunction(glBeginPerfMonitorAMD) + #define glDeletePerfMonitorsAMD GLEGetCurrentFunction(glDeletePerfMonitorsAMD) + #define glEndPerfMonitorAMD GLEGetCurrentFunction(glEndPerfMonitorAMD) + #define glGenPerfMonitorsAMD GLEGetCurrentFunction(glGenPerfMonitorsAMD) + #define glGetPerfMonitorCounterDataAMD GLEGetCurrentFunction(glGetPerfMonitorCounterDataAMD) + #define glGetPerfMonitorCounterInfoAMD GLEGetCurrentFunction(glGetPerfMonitorCounterInfoAMD) + #define glGetPerfMonitorCounterStringAMD GLEGetCurrentFunction(glGetPerfMonitorCounterStringAMD) + #define glGetPerfMonitorCountersAMD GLEGetCurrentFunction(glGetPerfMonitorCountersAMD) + #define glGetPerfMonitorGroupStringAMD GLEGetCurrentFunction(glGetPerfMonitorGroupStringAMD) + #define glGetPerfMonitorGroupsAMD GLEGetCurrentFunction(glGetPerfMonitorGroupsAMD) + #define glSelectPerfMonitorCountersAMD GLEGetCurrentFunction(glSelectPerfMonitorCountersAMD) + + #define GLE_AMD_performance_monitor GLEGetCurrentVariable(gle_AMD_performance_monitor) + +#endif // GL_AMD_performance_monitor +*/ + +#if defined(GLE_CGL_ENABLED) +#ifndef GL_APPLE_aux_depth_stencil +#define GL_APPLE_aux_depth_stencil 1 + +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14g + +#define GLE_APPLE_aux_depth_stencil GLEGetCurrentVariable(gle_APPLE_aux_depth_stencil) +#endif + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 + +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 + +#define GLE_APPLE_client_storage GLEGetCurrentVariable(gle_APPLE_client_storage) +#endif + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 + +#define GL_ELEMENT_ARRAY_APPLE 0x8A0C +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E + +typedef void(GLAPIENTRY* PFNGLDRAWELEMENTARRAYAPPLEPROC)(GLenum mode, GLint first, GLsizei count); +typedef void(GLAPIENTRY* PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC)( + GLenum mode, + GLuint start, + GLuint end, + GLint first, + GLsizei count); +typedef void(GLAPIENTRY* PFNGLELEMENTPOINTERAPPLEPROC)(GLenum type, const void* pointer); +typedef void(GLAPIENTRY* PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC)( + GLenum mode, + const GLint* first, + const GLsizei* count, + GLsizei primcount); +typedef void(GLAPIENTRY* PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC)( + GLenum mode, + GLuint start, + GLuint end, + const GLint* first, + const GLsizei* count, + GLsizei primcount); + +#define glDrawElementArrayAPPLE GLEGetCurrentFunction(glDrawElementArrayAPPLE) +#define glDrawRangeElementArrayAPPLE GLEGetCurrentFunction(glDrawRangeElementArrayAPPLE) +#define glElementPointerAPPLE GLEGetCurrentFunction(glElementPointerAPPLE) +#define glMultiDrawElementArrayAPPLE GLEGetCurrentFunction(glMultiDrawElementArrayAPPLE) +#define glMultiDrawRangeElementArrayAPPLE GLEGetCurrentFunction(glMultiDrawRangeElementArrayAPPLE) + +#define GLE_APPLE_element_array GLEGetCurrentVariable(gle_APPLE_element_array) +#endif + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 + +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B + +typedef void(GLAPIENTRY* PFNGLDELETEFENCESAPPLEPROC)(GLsizei n, const GLuint* fences); +typedef void(GLAPIENTRY* PFNGLFINISHFENCEAPPLEPROC)(GLuint fence); +typedef void(GLAPIENTRY* PFNGLFINISHOBJECTAPPLEPROC)(GLenum object, GLint name); +typedef void(GLAPIENTRY* PFNGLGENFENCESAPPLEPROC)(GLsizei n, GLuint* fences); +typedef GLboolean(GLAPIENTRY* PFNGLISFENCEAPPLEPROC)(GLuint fence); +typedef void(GLAPIENTRY* PFNGLSETFENCEAPPLEPROC)(GLuint fence); +typedef GLboolean(GLAPIENTRY* PFNGLTESTFENCEAPPLEPROC)(GLuint fence); +typedef GLboolean(GLAPIENTRY* PFNGLTESTOBJECTAPPLEPROC)(GLenum object, GLuint name); + +#define glDeleteFencesAPPLE GLEGetCurrentFunction(glDeleteFencesAPPLE) +#define glFinishFenceAPPLE GLEGetCurrentFunction(glFinishFenceAPPLE) +#define glFinishObjectAPPLE GLEGetCurrentFunction(glFinishObjectAPPLE) +#define glGenFencesAPPLE GLEGetCurrentFunction(glGenFencesAPPLE) +#define glIsFenceAPPLE GLEGetCurrentFunction(glIsFenceAPPLE) +#define glSetFenceAPPLE GLEGetCurrentFunction(glSetFenceAPPLE) +#define glTestFenceAPPLE GLEGetCurrentFunction(glTestFenceAPPLE) +#define glTestObjectAPPLE GLEGetCurrentFunction(glTestObjectAPPLE) + +#define GLE_APPLE_fence GLEGetCurrentVariable(gle_APPLE_fence) + +#endif + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels 1 + +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F + +#define GLE_APPLE_float_pixels GLEGetCurrentVariable(gle_APPLE_float_pixels) +#endif + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 + +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 + +typedef void(GLAPIENTRY* PFNGLBUFFERPARAMETERIAPPLEPROC)(GLenum target, GLenum pname, GLint param); +typedef void(GLAPIENTRY* PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC)( + GLenum target, + GLintptr offset, + GLsizeiptr size); + +#define glBufferParameteriAPPLE GLEGetCurrentFunction(glBufferParameteriAPPLE) +#define glFlushMappedBufferRangeAPPLE GLEGetCurrentFunction(glFlushMappedBufferRangeAPPLE) + +#define GLE_APPLE_flush_buffer_range GLEGetCurrentVariable(gle_APPLE_flush_buffer_range) +#endif + +#ifndef GL_APPLE_object_purgeable +#define GL_APPLE_object_purgeable 1 + +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_RETAINED_APPLE 0x8A1B +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_PURGEABLE_APPLE 0x8A1D + +typedef void(GLAPIENTRY* PFNGLGETOBJECTPARAMETERIVAPPLEPROC)( + GLenum objectType, + GLuint name, + GLenum pname, + GLint* params); +typedef GLenum( + GLAPIENTRY* PFNGLOBJECTPURGEABLEAPPLEPROC)(GLenum objectType, GLuint name, GLenum option); +typedef GLenum( + GLAPIENTRY* PFNGLOBJECTUNPURGEABLEAPPLEPROC)(GLenum objectType, GLuint name, GLenum option); + +#define glGetObjectParameterivAPPLE GLEGetCurrentFunction(glGetObjectParameterivAPPLE) +#define glObjectPurgeableAPPLE GLEGetCurrentFunction(glObjectPurgeableAPPLE) +#define glObjectUnpurgeableAPPLE GLEGetCurrentFunction(glObjectUnpurgeableAPPLE) + +#define GLE_APPLE_object_purgeable GLEGetCurrentVariable(gle_APPLE_object_purgeable) +#endif + +#ifndef GL_APPLE_pixel_buffer +#define GL_APPLE_pixel_buffer 1 + +#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 + +#define GLE_APPLE_pixel_buffer GLEGetCurrentVariable(gle_APPLE_pixel_buffer) +#endif + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 + +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_422_APPLE 0x8A1F +#define GL_RGB_RAW_422_APPLE 0x8A51 + +#define GLE_APPLE_rgb_422 GLEGetCurrentVariable(gle_APPLE_rgb_422) +#endif + +#ifndef GL_APPLE_row_bytes +#define GL_APPLE_row_bytes 1 + +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 + +#define GLE_APPLE_row_bytes GLEGetCurrentVariable(gle_APPLE_row_bytes) +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 + +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 + +#define GLE_APPLE_specular_vector GLEGetCurrentVariable(gle_APPLE_specular_vector) +#endif + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range 1 + +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void( + GLAPIENTRY* PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC)(GLenum target, GLenum pname, void** params); +typedef void( + GLAPIENTRY* PFNGLTEXTURERANGEAPPLEPROC)(GLenum target, GLsizei length, const void* pointer); + +#define glGetTexParameterPointervAPPLE GLEGetCurrentFunction(glGetTexParameterPointervAPPLE) +#define glTextureRangeAPPLE GLEGetCurrentFunction(glTextureRangeAPPLE) + +#define GLE_APPLE_texture_range GLEGetCurrentVariable(gle_APPLE_texture_range) +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 + +#define GL_TRANSFORM_HINT_APPLE 0x85B1 + +#define GLE_APPLE_transform_hint GLEGetCurrentVariable(gle_APPLE_transform_hint) +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 + +// This has been superceded by GL_ARB_vertex_array_object, though if you are using Apple +// OpenGL prior to 3.x then only this interface will be available. However, we have made +// it so that glBindVertexArray maps to glBindVertexArrayApple when only the latter is present, +// thus allowing you to write cleaner code. You can always just call glBindVertexArray instead +// of glBindVertexArrayAPPLE, etc. +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 + +typedef void(GLAPIENTRY* PFNGLBINDVERTEXARRAYAPPLEPROC)(GLuint array); +typedef void(GLAPIENTRY* PFNGLDELETEVERTEXARRAYSAPPLEPROC)(GLsizei n, const GLuint* arrays); +typedef void(GLAPIENTRY* PFNGLGENVERTEXARRAYSAPPLEPROC)( + GLsizei n, + const GLuint* arrays); // It's not clear whether arrays needs to be const or not. +typedef GLboolean(GLAPIENTRY* PFNGLISVERTEXARRAYAPPLEPROC)(GLuint array); + +#define glBindVertexArrayAPPLE GLEGetCurrentFunction(glBindVertexArrayAPPLE) +#define glDeleteVertexArraysAPPLE GLEGetCurrentFunction(glDeleteVertexArraysAPPLE) +#define glGenVertexArraysAPPLE GLEGetCurrentFunction(glGenVertexArraysAPPLE) +#define glIsVertexArrayAPPLE GLEGetCurrentFunction(glIsVertexArrayAPPLE) + +#define GLE_APPLE_vertex_array_object GLEGetCurrentVariable(gle_APPLE_vertex_array_object) +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CLIENT_APPLE 0x85B4 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void(GLAPIENTRY* PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC)(GLsizei length, void* pointer); +typedef void(GLAPIENTRY* PFNGLVERTEXARRAYPARAMETERIAPPLEPROC)(GLenum pname, GLint param); +typedef void(GLAPIENTRY* PFNGLVERTEXARRAYRANGEAPPLEPROC)(GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeAPPLE GLEGetCurrentFunction(glFlushVertexArrayRangeAPPLE) +#define glVertexArrayParameteriAPPLE GLEGetCurrentFunction(glVertexArrayParameteriAPPLE) +#define glVertexArrayRangeAPPLE GLEGetCurrentFunction(glVertexArrayRangeAPPLE) + +#define GLE_APPLE_vertex_array_range GLEGetCurrentVariable(gle_APPLE_vertex_array_range) +#endif + +#ifndef GL_APPLE_vertex_program_evaluators +#define GL_APPLE_vertex_program_evaluators 1 + +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 + +typedef void(GLAPIENTRY* PFNGLDISABLEVERTEXATTRIBAPPLEPROC)(GLuint index, GLenum pname); +typedef void(GLAPIENTRY* PFNGLENABLEVERTEXATTRIBAPPLEPROC)(GLuint index, GLenum pname); +typedef GLboolean(GLAPIENTRY* PFNGLISVERTEXATTRIBENABLEDAPPLEPROC)(GLuint index, GLenum pname); +typedef void(GLAPIENTRY* PFNGLMAPVERTEXATTRIB1DAPPLEPROC)( + GLuint index, + GLuint size, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble* points); +typedef void(GLAPIENTRY* PFNGLMAPVERTEXATTRIB1FAPPLEPROC)( + GLuint index, + GLuint size, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat* points); +typedef void(GLAPIENTRY* PFNGLMAPVERTEXATTRIB2DAPPLEPROC)( + GLuint index, + GLuint size, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble* points); +typedef void(GLAPIENTRY* PFNGLMAPVERTEXATTRIB2FAPPLEPROC)( + GLuint index, + GLuint size, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat* points); + +#define glDisableVertexAttribAPPLE GLEGetCurrentFunction(glDisableVertexAttribAPPLE) +#define glEnableVertexAttribAPPLE GLEGetCurrentFunction(glEnableVertexAttribAPPLE) +#define glIsVertexAttribEnabledAPPLE GLEGetCurrentFunction(glIsVertexAttribEnabledAPPLE) +#define glMapVertexAttrib1dAPPLE GLEGetCurrentFunction(glMapVertexAttrib1dAPPLE) +#define glMapVertexAttrib1fAPPLE GLEGetCurrentFunction(glMapVertexAttrib1fAPPLE) +#define glMapVertexAttrib2dAPPLE GLEGetCurrentFunction(glMapVertexAttrib2dAPPLE) +#define glMapVertexAttrib2fAPPLE GLEGetCurrentFunction(glMapVertexAttrib2fAPPLE) + +#define GLE_APPLE_vertex_program_evaluators \ + GLEGetCurrentVariable(gle_APPLE_vertex_program_evaluators) +#endif + +#endif // GLE_CGL_ENABLED + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer 1 + +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 + +typedef void(GLAPIENTRY* PFNGLCOPYBUFFERSUBDATAPROC)( + GLenum readtarget, + GLenum writetarget, + GLintptr readoffset, + GLintptr writeoffset, + GLsizeiptr size); + +#define glCopyBufferSubData GLEGetCurrentFunction(glCopyBufferSubData) + +#define GLE_ARB_copy_buffer GLEGetCurrentVariable(gle_ARB_copy_buffer) +#endif + +#ifndef GL_ARB_debug_output +#define GL_ARB_debug_output 1 + +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 + +typedef void(GLAPIENTRY* GLDEBUGPROCARB)( + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam); + +typedef void( + GLAPIENTRY* PFNGLDEBUGMESSAGECALLBACKARBPROC)(GLDEBUGPROCARB callback, const void* userParam); +typedef void(GLAPIENTRY* PFNGLDEBUGMESSAGECONTROLARBPROC)( + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint* ids, + GLboolean enabled); +typedef void(GLAPIENTRY* PFNGLDEBUGMESSAGEINSERTARBPROC)( + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* buf); +typedef GLuint(GLAPIENTRY* PFNGLGETDEBUGMESSAGELOGARBPROC)( + GLuint count, + GLsizei bufSize, + GLenum* sources, + GLenum* types, + GLuint* ids, + GLenum* severities, + GLsizei* lengths, + GLchar* messageLog); + +#define glDebugMessageCallbackARB GLEGetCurrentFunction(glDebugMessageCallbackARB) +#define glDebugMessageControlARB GLEGetCurrentFunction(glDebugMessageControlARB) +#define glDebugMessageInsertARB GLEGetCurrentFunction(glDebugMessageInsertARB) +#define glGetDebugMessageLogARB GLEGetCurrentFunction(glGetDebugMessageLogARB) + +#define GLE_ARB_debug_output GLEGetCurrentVariable(gle_ARB_debug_output) + +#endif // GL_ARB_debug_output + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 + +// Supercededs GL_NV_depth_buffer_float +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD + +#define GLE_ARB_depth_buffer_float GLEGetCurrentVariable(gle_ARB_depth_buffer_float) +#endif + +/* Disabled until needed +#ifndef GL_ARB_direct_state_access + #define GL_ARB_direct_state_access 1 + + #define GL_TEXTURE_TARGET 0x1006 + #define GL_QUERY_TARGET 0x82EA + #define GL_TEXTURE_BINDING 0x82EB + + typedef void (GLAPIENTRY * PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); + typedef void (GLAPIENTRY * PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint +drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint +dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum +target); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, +GLenum format, GLenum type, const void *data); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum +internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, +GLfloat depth, GLint stencil); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, +GLint drawbuffer, const GLfloat* value); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, +GLint drawbuffer, const GLint* value); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum +buffer, GLint drawbuffer, const GLuint* value); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, +GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, +GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const +void *data); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, +GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum +format, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint +writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint +xoffset, GLint x, GLint y, GLsizei width); + typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint +xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint +xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint* buffers); + typedef void (GLAPIENTRY * PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); + typedef void (GLAPIENTRY * PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines); + typedef void (GLAPIENTRY * PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint* ids); + typedef void (GLAPIENTRY * PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); + typedef void (GLAPIENTRY * PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint* samplers); + typedef void (GLAPIENTRY * PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint* +textures); + typedef void (GLAPIENTRY * PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids); + typedef void (GLAPIENTRY * PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); + typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); + typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); + typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr +offset, GLsizeiptr length); + typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); + typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, +GLsizei bufSize, void *pixels); + typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, +GLint64* params); + typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, +GLint* params); + typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void** +params); + typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, +GLsizeiptr size, void *data); + typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint +framebuffer, GLenum attachment, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum +pname, GLint* param); + typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, +GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum +format, GLenum type, GLsizei bufSize, void *pixels); + typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, +GLenum pname, GLfloat* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, +GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, +GLint* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, +GLuint* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, +GLfloat* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint* +params); + typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint +index, GLint64* param); + typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint +index, GLint* param); + typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint* +param); + typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, +GLenum pname, GLint64* param); + typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum +pname, GLint* param); + typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint* +param); + typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei +numAttachments, const GLenum* attachments); + typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, +GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); + typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, +GLsizeiptr length, GLbitfield access); + typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void +*data, GLenum usage); + typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const +void *data, GLbitfield flags); + typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, +GLsizeiptr size, const void *data); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum +mode); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, +const GLenum* bufs); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum +pname, GLint param); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum +mode); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum +attachment, GLenum renderbuffertarget, GLuint renderbuffer); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum +attachment, GLuint texture, GLint level); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum +attachment, GLuint texture, GLint level, GLint layer); + typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum +internalformat, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, +GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, +GLuint buffer); + typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, +GLuint buffer, GLintptr offset, GLsizeiptr size); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const +GLint* params); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const +GLuint* params); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat +param); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const +GLfloat* param); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint +param); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const +GLint* param); + typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum +internalformat, GLsizei width); + typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum +internalformat, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei +samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum +internalformat, GLsizei width, GLsizei height, GLsizei depth); + typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei +samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean +fixedsamplelocations); + typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint +xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); + typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint +xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void +*pixels); + typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint +xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, +GLenum type, const void *pixels); + typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, +GLuint buffer); + typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, +GLuint buffer, GLintptr offset, GLsizeiptr size); + typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, +GLuint bindingindex); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, +GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, +GLint size, GLenum type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, +GLint size, GLenum type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint +bindingindex, GLuint divisor); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, +GLuint buffer, GLintptr offset, GLsizei stride); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, +GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides); + + #define glBindTextureUnit GLEGetCurrentFunction(glBindTextureUnit) + #define glBlitNamedFramebuffer GLEGetCurrentFunction(glBlitNamedFramebuffer) + #define glCheckNamedFramebufferStatus GLEGetCurrentFunction(glCheckNamedFramebufferStatus) + #define glClearNamedBufferData GLEGetCurrentFunction(glClearNamedBufferData) + #define glClearNamedBufferSubData GLEGetCurrentFunction(glClearNamedBufferSubData) + #define glClearNamedFramebufferfi GLEGetCurrentFunction(glClearNamedFramebufferfi) + #define glClearNamedFramebufferfv GLEGetCurrentFunction(glClearNamedFramebufferfv) + #define glClearNamedFramebufferiv GLEGetCurrentFunction(glClearNamedFramebufferiv) + #define glClearNamedFramebufferuiv GLEGetCurrentFunction(glClearNamedFramebufferuiv) + #define glCompressedTextureSubImage1D GLEGetCurrentFunction(glCompressedTextureSubImage1D) + #define glCompressedTextureSubImage2D GLEGetCurrentFunction(glCompressedTextureSubImage2D) + #define glCompressedTextureSubImage3D GLEGetCurrentFunction(glCompressedTextureSubImage3D) + #define glCopyNamedBufferSubData GLEGetCurrentFunction(glCopyNamedBufferSubData) + #define glCopyTextureSubImage1D GLEGetCurrentFunction(glCopyTextureSubImage1D) + #define glCopyTextureSubImage2D GLEGetCurrentFunction(glCopyTextureSubImage2D) + #define glCopyTextureSubImage3D GLEGetCurrentFunction(glCopyTextureSubImage3D) + #define glCreateBuffers GLEGetCurrentFunction(glCreateBuffers) + #define glCreateFramebuffers GLEGetCurrentFunction(glCreateFramebuffers) + #define glCreateProgramPipelines GLEGetCurrentFunction(glCreateProgramPipelines) + #define glCreateQueries GLEGetCurrentFunction(glCreateQueries) + #define glCreateRenderbuffers GLEGetCurrentFunction(glCreateRenderbuffers) + #define glCreateSamplers GLEGetCurrentFunction(glCreateSamplers) + #define glCreateTextures GLEGetCurrentFunction(glCreateTextures) + #define glCreateTransformFeedbacks GLEGetCurrentFunction(glCreateTransformFeedbacks) + #define glCreateVertexArrays GLEGetCurrentFunction(glCreateVertexArrays) + #define glDisableVertexArrayAttrib GLEGetCurrentFunction(glDisableVertexArrayAttrib) + #define glEnableVertexArrayAttrib GLEGetCurrentFunction(glEnableVertexArrayAttrib) + #define glFlushMappedNamedBufferRange GLEGetCurrentFunction(glFlushMappedNamedBufferRange) + #define glGenerateTextureMipmap GLEGetCurrentFunction(glGenerateTextureMipmap) + #define glGetCompressedTextureImage GLEGetCurrentFunction(glGetCompressedTextureImage) + #define glGetNamedBufferParameteri64v GLEGetCurrentFunction(glGetNamedBufferParameteri64v) + #define glGetNamedBufferParameteriv GLEGetCurrentFunction(glGetNamedBufferParameteriv) + #define glGetNamedBufferPointerv GLEGetCurrentFunction(glGetNamedBufferPointerv) + #define glGetNamedBufferSubData GLEGetCurrentFunction(glGetNamedBufferSubData) + #define glGetNamedFramebufferAttachmentParameteriv +GLEGetCurrentFunction(glGetNamedFramebufferAttachmentParameteriv) + #define glGetNamedFramebufferParameteriv GLEGetCurrentFunction(glGetNamedFramebufferParameteriv) + #define glGetNamedRenderbufferParameteriv +GLEGetCurrentFunction(glGetNamedRenderbufferParameteriv) + #define glGetTextureImage GLEGetCurrentFunction(glGetTextureImage) + #define glGetTextureLevelParameterfv GLEGetCurrentFunction(glGetTextureLevelParameterfv) + #define glGetTextureLevelParameteriv GLEGetCurrentFunction(glGetTextureLevelParameteriv) + #define glGetTextureParameterIiv GLEGetCurrentFunction(glGetTextureParameterIiv) + #define glGetTextureParameterIuiv GLEGetCurrentFunction(glGetTextureParameterIuiv) + #define glGetTextureParameterfv GLEGetCurrentFunction(glGetTextureParameterfv) + #define glGetTextureParameteriv GLEGetCurrentFunction(glGetTextureParameteriv) + #define glGetTransformFeedbacki64_v GLEGetCurrentFunction(glGetTransformFeedbacki64_v) + #define glGetTransformFeedbacki_v GLEGetCurrentFunction(glGetTransformFeedbacki_v) + #define glGetTransformFeedbackiv GLEGetCurrentFunction(glGetTransformFeedbackiv) + #define glGetVertexArrayIndexed64iv GLEGetCurrentFunction(glGetVertexArrayIndexed64iv) + #define glGetVertexArrayIndexediv GLEGetCurrentFunction(glGetVertexArrayIndexediv) + #define glGetVertexArrayiv GLEGetCurrentFunction(glGetVertexArrayiv) + #define glInvalidateNamedFramebufferData GLEGetCurrentFunction(glInvalidateNamedFramebufferData) + #define glInvalidateNamedFramebufferSubData +GLEGetCurrentFunction(glInvalidateNamedFramebufferSubData) + #define glMapNamedBuffer GLEGetCurrentFunction(glMapNamedBuffer) + #define glMapNamedBufferRange GLEGetCurrentFunction(glMapNamedBufferRange) + #define glNamedBufferData GLEGetCurrentFunction(glNamedBufferData) + #define glNamedBufferStorage GLEGetCurrentFunction(glNamedBufferStorage) + #define glNamedBufferSubData GLEGetCurrentFunction(glNamedBufferSubData) + #define glNamedFramebufferDrawBuffer GLEGetCurrentFunction(glNamedFramebufferDrawBuffer) + #define glNamedFramebufferDrawBuffers GLEGetCurrentFunction(glNamedFramebufferDrawBuffers) + #define glNamedFramebufferParameteri GLEGetCurrentFunction(glNamedFramebufferParameteri) + #define glNamedFramebufferReadBuffer GLEGetCurrentFunction(glNamedFramebufferReadBuffer) + #define glNamedFramebufferRenderbuffer GLEGetCurrentFunction(glNamedFramebufferRenderbuffer) + #define glNamedFramebufferTexture GLEGetCurrentFunction(glNamedFramebufferTexture) + #define glNamedFramebufferTextureLayer GLEGetCurrentFunction(glNamedFramebufferTextureLayer) + #define glNamedRenderbufferStorage GLEGetCurrentFunction(glNamedRenderbufferStorage) + #define glNamedRenderbufferStorageMultisample +GLEGetCurrentFunction(glNamedRenderbufferStorageMultisample) + #define glTextureBuffer GLEGetCurrentFunction(glTextureBuffer) + #define glTextureBufferRange GLEGetCurrentFunction(glTextureBufferRange) + #define glTextureParameterIiv GLEGetCurrentFunction(glTextureParameterIiv) + #define glTextureParameterIuiv GLEGetCurrentFunction(glTextureParameterIuiv) + #define glTextureParameterf GLEGetCurrentFunction(glTextureParameterf) + #define glTextureParameterfv GLEGetCurrentFunction(glTextureParameterfv) + #define glTextureParameteri GLEGetCurrentFunction(glTextureParameteri) + #define glTextureParameteriv GLEGetCurrentFunction(glTextureParameteriv) + #define glTextureStorage1D GLEGetCurrentFunction(glTextureStorage1D) + #define glTextureStorage2D GLEGetCurrentFunction(glTextureStorage2D) + #define glTextureStorage2DMultisample GLEGetCurrentFunction(glTextureStorage2DMultisample) + #define glTextureStorage3D GLEGetCurrentFunction(glTextureStorage3D) + #define glTextureStorage3DMultisample GLEGetCurrentFunction(glTextureStorage3DMultisample) + #define glTextureSubImage1D GLEGetCurrentFunction(glTextureSubImage1D) + #define glTextureSubImage2D GLEGetCurrentFunction(glTextureSubImage2D) + #define glTextureSubImage3D GLEGetCurrentFunction(glTextureSubImage3D) + #define glTransformFeedbackBufferBase GLEGetCurrentFunction(glTransformFeedbackBufferBase) + #define glTransformFeedbackBufferRange GLEGetCurrentFunction(glTransformFeedbackBufferRange) + #define glUnmapNamedBuffer GLEGetCurrentFunction(glUnmapNamedBuffer) + #define glVertexArrayAttribBinding GLEGetCurrentFunction(glVertexArrayAttribBinding) + #define glVertexArrayAttribFormat GLEGetCurrentFunction(glVertexArrayAttribFormat) + #define glVertexArrayAttribIFormat GLEGetCurrentFunction(glVertexArrayAttribIFormat) + #define glVertexArrayAttribLFormat GLEGetCurrentFunction(glVertexArrayAttribLFormat) + #define glVertexArrayBindingDivisor GLEGetCurrentFunction(glVertexArrayBindingDivisor) + #define glVertexArrayElementBuffer GLEGetCurrentFunction(glVertexArrayElementBuffer) + #define glVertexArrayVertexBuffer GLEGetCurrentFunction(glVertexArrayVertexBuffer) + #define glVertexArrayVertexBuffers GLEGetCurrentFunction(glVertexArrayVertexBuffers) + + #define GLE_ARB_direct_state_access GLEGetCurrentVariable(gle_ARB_direct_state_access) +#endif // GL_ARB_direct_state_access */ + +#ifndef GL_ARB_ES2_compatibility +#define GL_ARB_ES2_compatibility 1 + +// This is for OpenGL ES compatibility. +#define GL_FIXED 0x140C +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_RGB565 0x8D62 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD + +typedef int GLfixed; + +typedef void(GLAPIENTRY* PFNGLCLEARDEPTHFPROC)(GLclampf d); +typedef void(GLAPIENTRY* PFNGLDEPTHRANGEFPROC)(GLclampf n, GLclampf f); +typedef void(GLAPIENTRY* PFNGLGETSHADERPRECISIONFORMATPROC)( + GLenum shadertype, + GLenum precisiontype, + GLint* range, + GLint* precision); +typedef void(GLAPIENTRY* PFNGLRELEASESHADERCOMPILERPROC)(void); +typedef void(GLAPIENTRY* PFNGLSHADERBINARYPROC)( + GLsizei count, + const GLuint* shaders, + GLenum binaryformat, + const void* binary, + GLsizei length); + +#define glClearDepthf GLEGetCurrentFunction(glClearDepthf) +#define glDepthRangef GLEGetCurrentFunction(glDepthRangef) +#define glGetShaderPrecisionFormat GLEGetCurrentFunction(glGetShaderPrecisionFormat) +#define glReleaseShaderCompiler GLEGetCurrentFunction(glReleaseShaderCompiler) +#define glShaderBinary GLEGetCurrentFunction(glShaderBinary) + +#define GLE_ARB_ES2_compatibility GLEGetCurrentVariable(gle_ARB_ES2_compatibility) +#endif + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 + +// GL_ARB_framebuffer_object is part of the OpenGL 4.4 core profile. +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_INDEX 0x8222 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_SRGB 0x8C40 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 + +typedef void(GLAPIENTRY* PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); +typedef void(GLAPIENTRY* PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); +typedef void(GLAPIENTRY* PFNGLBLITFRAMEBUFFERPROC)( + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); +typedef GLenum(GLAPIENTRY* PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); +typedef void(GLAPIENTRY* PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint* framebuffers); +typedef void(GLAPIENTRY* PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint* renderbuffers); +typedef void(GLAPIENTRY* PFNGLFRAMEBUFFERRENDERBUFFERPROC)( + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer); +typedef void(GLAPIENTRY* PFNGLFRAMEBUFFERTEXTURE1DPROC)( + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level); +typedef void(GLAPIENTRY* PFNGLFRAMEBUFFERTEXTURE2DPROC)( + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level); +typedef void(GLAPIENTRY* PFNGLFRAMEBUFFERTEXTURE3DPROC)( + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level, + GLint layer); +typedef void(GLAPIENTRY* PFNGLFRAMEBUFFERTEXTURELAYERPROC)( + GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer); +typedef void(GLAPIENTRY* PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint* framebuffers); +typedef void(GLAPIENTRY* PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint* renderbuffers); +typedef void(GLAPIENTRY* PFNGLGENERATEMIPMAPPROC)(GLenum target); +typedef void(GLAPIENTRY* PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)( + GLenum target, + GLenum attachment, + GLenum pname, + GLint* params); +typedef void( + GLAPIENTRY* PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint* params); +typedef GLboolean(GLAPIENTRY* PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); +typedef GLboolean(GLAPIENTRY* PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); +typedef void(GLAPIENTRY* PFNGLRENDERBUFFERSTORAGEPROC)( + GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height); +typedef void(GLAPIENTRY* PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + +#define glBindFramebuffer GLEGetCurrentFunction(glBindFramebuffer) +#define glBindRenderbuffer GLEGetCurrentFunction(glBindRenderbuffer) +#define glBlitFramebuffer GLEGetCurrentFunction(glBlitFramebuffer) +#define glCheckFramebufferStatus GLEGetCurrentFunction(glCheckFramebufferStatus) +#define glDeleteFramebuffers GLEGetCurrentFunction(glDeleteFramebuffers) +#define glDeleteRenderbuffers GLEGetCurrentFunction(glDeleteRenderbuffers) +#define glFramebufferRenderbuffer GLEGetCurrentFunction(glFramebufferRenderbuffer) +#define glFramebufferTexture1D GLEGetCurrentFunction(glFramebufferTexture1D) +#define glFramebufferTexture2D GLEGetCurrentFunction(glFramebufferTexture2D) +#define glFramebufferTexture3D GLEGetCurrentFunction(glFramebufferTexture3D) +#define glFramebufferTextureLayer GLEGetCurrentFunction(glFramebufferTextureLayer) +#define glGenFramebuffers GLEGetCurrentFunction(glGenFramebuffers) +#define glGenRenderbuffers GLEGetCurrentFunction(glGenRenderbuffers) +#define glGenerateMipmap GLEGetCurrentFunction(glGenerateMipmap) +#define glGetFramebufferAttachmentParameteriv \ + GLEGetCurrentFunction(glGetFramebufferAttachmentParameteriv) +#define glGetRenderbufferParameteriv GLEGetCurrentFunction(glGetRenderbufferParameteriv) +#define glIsFramebuffer GLEGetCurrentFunction(glIsFramebuffer) +#define glIsRenderbuffer GLEGetCurrentFunction(glIsRenderbuffer) +#define glRenderbufferStorage GLEGetCurrentFunction(glRenderbufferStorage) +#define glRenderbufferStorageMultisample GLEGetCurrentFunction(glRenderbufferStorageMultisample) + +#define GLE_ARB_framebuffer_object GLEGetCurrentVariable(gle_ARB_framebuffer_object) + +#endif // GL_ARB_framebuffer_object + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 + +// GL_ARB_framebuffer_sRGB is part of the OpenGL 4.4 core profile. +#define GL_FRAMEBUFFER_SRGB 0x8DB9 + +#define GLE_ARB_framebuffer_sRGB GLEGetCurrentVariable(gle_ARB_framebuffer_sRGB) +#endif + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample 1 + +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 + +typedef void(GLAPIENTRY* PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat* val); +typedef void(GLAPIENTRY* PFNGLSAMPLEMASKIPROC)(GLuint index, GLbitfield mask); +typedef void(GLAPIENTRY* PFNGLTEXIMAGE2DMULTISAMPLEPROC)( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +typedef void(GLAPIENTRY* PFNGLTEXIMAGE3DMULTISAMPLEPROC)( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + +#define glGetMultisamplefv GLEGetCurrentFunction(glGetMultisamplefv) +#define glSampleMaski GLEGetCurrentFunction(glSampleMaski) +#define glTexImage2DMultisample GLEGetCurrentFunction(glTexImage2DMultisample) +#define glTexImage3DMultisample GLEGetCurrentFunction(glTexImage3DMultisample) + +#define GLE_ARB_texture_multisample GLEGetCurrentVariable(gle_ARB_texture_multisample) + +#endif // GL_ARB_texture_multisample + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 + +#define GLE_ARB_texture_non_power_of_two GLEGetCurrentVariable(gle_ARB_texture_non_power_of_two) +#endif + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 + +// texture_rectangle was added to the OpenGL 3.1 core profile and so this extension is not needed +// unless using an earlier version of OpenGL. +// There are also the GL_EXT_texture_rectangle and GL_NV_texture_rectangle extensions. Apple reports +// the preseence of GL_EXT_texture_rectangle but not GL_ARB_texture_rectangle or +// GL_NV_texture_rectangle. +// You should check for GL_ARB_texture_rectangle instead of these other two. +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 + +#define GLE_ARB_texture_rectangle GLEGetCurrentVariable(gle_ARB_texture_rectangle) +#endif + +#ifndef GL_ARB_texture_storage +#define GL_ARB_texture_storage 1 + +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F + +typedef void(GLAPIENTRY* PFNGLTEXSTORAGE1DPROC)( + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width); +typedef void(GLAPIENTRY* PFNGLTEXSTORAGE2DPROC)( + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +typedef void(GLAPIENTRY* PFNGLTEXSTORAGE3DPROC)( + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); +typedef void(GLAPIENTRY* PFNGLTEXTURESTORAGE1DEXTPROC)( + GLuint texture, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width); +typedef void(GLAPIENTRY* PFNGLTEXTURESTORAGE2DEXTPROC)( + GLuint texture, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +typedef void(GLAPIENTRY* PFNGLTEXTURESTORAGE3DEXTPROC)( + GLuint texture, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + +#define glTexStorage1D GLEGetCurrentFunction(glTexStorage1D) +#define glTexStorage2D GLEGetCurrentFunction(glTexStorage2D) +#define glTexStorage3D GLEGetCurrentFunction(glTexStorage3D) +#define glTextureStorage1DEXT GLEGetCurrentFunction(glTextureStorage1DEXT) +#define glTextureStorage2DEXT GLEGetCurrentFunction(glTextureStorage2DEXT) +#define glTextureStorage3DEXT GLEGetCurrentFunction(glTextureStorage3DEXT) + +#define GLE_ARB_texture_storage GLEGetCurrentVariable(gle_ARB_texture_storage) +#endif + +#ifndef GL_ARB_texture_storage_multisample +#define GL_ARB_texture_storage_multisample 1 + +typedef void(GLAPIENTRY* PFNGLTEXSTORAGE2DMULTISAMPLEPROC)( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +typedef void(GLAPIENTRY* PFNGLTEXSTORAGE3DMULTISAMPLEPROC)( + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); +typedef void(GLAPIENTRY* PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC)( + GLuint texture, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +typedef void(GLAPIENTRY* PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC)( + GLuint texture, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations); + +#define glTexStorage2DMultisample GLEGetCurrentFunction(glTexStorage2DMultisample) +#define glTexStorage3DMultisample GLEGetCurrentFunction(glTexStorage3DMultisample) +#define glTextureStorage2DMultisampleEXT GLEGetCurrentFunction(glTextureStorage2DMultisampleEXT) +#define glTextureStorage3DMultisampleEXT GLEGetCurrentFunction(glTextureStorage3DMultisampleEXT) + +#define GLE_ARB_texture_storage_multisample \ + GLEGetCurrentVariable(gle_ARB_texture_storage_multisample) +#endif + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query 1 + +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 + +typedef void(GLAPIENTRY* PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64* params); +typedef void(GLAPIENTRY* PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64* params); +typedef void(GLAPIENTRY* PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target); + +#define glGetQueryObjecti64v GLEGetCurrentFunction(glGetQueryObjecti64v) +#define glGetQueryObjectui64v GLEGetCurrentFunction(glGetQueryObjectui64v) +#define glQueryCounter GLEGetCurrentFunction(glQueryCounter) + +#define GLE_ARB_timer_query GLEGetCurrentVariable(gle_ARB_timer_query) +#endif + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING 0x85B5 + +typedef void(GLAPIENTRY* PFNGLBINDVERTEXARRAYPROC)(GLuint array); +typedef void(GLAPIENTRY* PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint* arrays); +typedef void(GLAPIENTRY* PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint* arrays); +typedef GLboolean(GLAPIENTRY* PFNGLISVERTEXARRAYPROC)(GLuint array); + +#define glBindVertexArray GLEGetCurrentFunction(glBindVertexArray) +#define glDeleteVertexArrays GLEGetCurrentFunction(glDeleteVertexArrays) +#define glGenVertexArrays GLEGetCurrentFunction(glGenVertexArrays) +#define glIsVertexArray GLEGetCurrentFunction(glIsVertexArray) + +#define GLE_ARB_vertex_array_object GLEGetCurrentVariable(gle_ARB_vertex_array_object) +#endif + +/* Disabled until needed +#ifndef GL_ARB_vertex_attrib_binding + #define GL_ARB_vertex_attrib_binding 1 + + #define GL_VERTEX_ATTRIB_BINDING 0x82D4 + #define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 + #define GL_VERTEX_BINDING_DIVISOR 0x82D6 + #define GL_VERTEX_BINDING_OFFSET 0x82D7 + #define GL_VERTEX_BINDING_STRIDE 0x82D8 + #define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 + #define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA + #define GL_VERTEX_BINDING_BUFFER 0x8F4F + + typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, +GLintptr offset, GLsizei stride); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint +bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint +attribindex, GLuint bindingindex); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint +attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint +attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint +attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint +bindingindex, GLuint divisor); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint +bindingindex); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum +type, GLboolean normalized, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum +type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum +type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); + + #define glBindVertexBuffer GLEGetCurrentFunction(glBindVertexBuffer) + #define glVertexArrayBindVertexBufferEXT GLEGetCurrentFunction(glVertexArrayBindVertexBufferEXT) + #define glVertexArrayVertexAttribBindingEXT +GLEGetCurrentFunction(glVertexArrayVertexAttribBindingEXT) + #define glVertexArrayVertexAttribFormatEXT +GLEGetCurrentFunction(glVertexArrayVertexAttribFormatEXT) + #define glVertexArrayVertexAttribIFormatEXT +GLEGetCurrentFunction(glVertexArrayVertexAttribIFormatEXT) + #define glVertexArrayVertexAttribLFormatEXT +GLEGetCurrentFunction(glVertexArrayVertexAttribLFormatEXT) + #define glVertexArrayVertexBindingDivisorEXT +GLEGetCurrentFunction(glVertexArrayVertexBindingDivisorEXT) + #define glVertexAttribBinding GLEGetCurrentFunction(glVertexAttribBinding) + #define glVertexAttribFormat GLEGetCurrentFunction(glVertexAttribFormat) + #define glVertexAttribIFormat GLEGetCurrentFunction(glVertexAttribIFormat) + #define glVertexAttribLFormat GLEGetCurrentFunction(glVertexAttribLFormat) + #define glVertexBindingDivisor GLEGetCurrentFunction(glVertexBindingDivisor) + + #define GLE_ARB_vertex_attrib_binding GLEGetCurrentVariable(gle_ARB_vertex_attrib_binding) +#endif +*/ + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 + +typedef void(GLAPIENTRY* PFNGLCOLORMASKINDEXEDEXTPROC)( + GLuint buf, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a); +typedef void(GLAPIENTRY* PFNGLDISABLEINDEXEDEXTPROC)(GLenum target, GLuint index); +typedef void(GLAPIENTRY* PFNGLENABLEINDEXEDEXTPROC)(GLenum target, GLuint index); +typedef void( + GLAPIENTRY* PFNGLGETBOOLEANINDEXEDVEXTPROC)(GLenum value, GLuint index, GLboolean* data); +typedef void(GLAPIENTRY* PFNGLGETINTEGERINDEXEDVEXTPROC)(GLenum value, GLuint index, GLint* data); +typedef GLboolean(GLAPIENTRY* PFNGLISENABLEDINDEXEDEXTPROC)(GLenum target, GLuint index); + +#define glColorMaskIndexedEXT GLEGetCurrentFunction(glColorMaskIndexedEXT) +#define glDisableIndexedEXT GLEGetCurrentFunction(glDisableIndexedEXT) +#define glEnableIndexedEXT GLEGetCurrentFunction(glEnableIndexedEXT) +#define glGetBooleanIndexedvEXT GLEGetCurrentFunction(glGetBooleanIndexedvEXT) +#define glGetIntegerIndexedvEXT GLEGetCurrentFunction(glGetIntegerIndexedvEXT) +#define glIsEnabledIndexedEXT GLEGetCurrentFunction(glIsEnabledIndexedEXT) + +#define GLE_EXT_draw_buffers2 GLEGetCurrentVariable(gle_EXT_draw_buffers2) +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 + +#define GLE_EXT_texture_compression_s3tc GLEGetCurrentVariable(gle_EXT_texture_compression_s3tc) +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 + +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF + +#define GLE_EXT_texture_filter_anisotropic GLEGetCurrentVariable(gle_EXT_texture_filter_anisotropic) +#endif + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 + +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F + +#define GLE_EXT_texture_sRGB GLEGetCurrentVariable(gle_EXT_texture_sRGB) +#endif + +/* Disabled until needed +#ifndef GL_KHR_context_flush_control + #define GL_KHR_context_flush_control 1 + + #define GLE_KHR_context_flush_control GLEGetCurrentVariable(gle_KHR_context_flush_control) +#endif +*/ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 + +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_BUFFER 0x82E0 +#define GL_SHADER 0x82E1 +#define GL_PROGRAM 0x82E2 +#define GL_QUERY 0x82E3 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_SAMPLER 0x82E6 +#define GL_DISPLAY_LIST 0x82E7 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_OUTPUT 0x92E0 + +typedef void(GLAPIENTRY* GLDEBUGPROC)( + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam); + +typedef void( + GLAPIENTRY* PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void* userParam); +typedef void(GLAPIENTRY* PFNGLDEBUGMESSAGECONTROLPROC)( + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint* ids, + GLboolean enabled); +typedef void(GLAPIENTRY* PFNGLDEBUGMESSAGEINSERTPROC)( + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* buf); +typedef GLuint(GLAPIENTRY* PFNGLGETDEBUGMESSAGELOGPROC)( + GLuint count, + GLsizei bufSize, + GLenum* sources, + GLenum* types, + GLuint* ids, + GLenum* severities, + GLsizei* lengths, + GLchar* messageLog); +typedef void(GLAPIENTRY* PFNGLGETOBJECTLABELPROC)( + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei* length, + GLchar* label); +typedef void(GLAPIENTRY* PFNGLGETOBJECTPTRLABELPROC)( + const void* ptr, + GLsizei bufSize, + GLsizei* length, + GLchar* label); +typedef void(GLAPIENTRY* PFNGLOBJECTLABELPROC)( + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar* label); +typedef void( + GLAPIENTRY* PFNGLOBJECTPTRLABELPROC)(const void* ptr, GLsizei length, const GLchar* label); +typedef void(GLAPIENTRY* PFNGLPOPDEBUGGROUPPROC)(void); +typedef void(GLAPIENTRY* PFNGLPUSHDEBUGGROUPPROC)( + GLenum source, + GLuint id, + GLsizei length, + const GLchar* message); + +#define glDebugMessageCallback GLEGetCurrentFunction(glDebugMessageCallback) +#define glDebugMessageControl GLEGetCurrentFunction(glDebugMessageControl) +#define glDebugMessageInsert GLEGetCurrentFunction(glDebugMessageInsert) +#define glGetDebugMessageLog GLEGetCurrentFunction(glGetDebugMessageLog) +#define glGetObjectLabel GLEGetCurrentFunction(glGetObjectLabel) +#define glGetObjectPtrLabel GLEGetCurrentFunction(glGetObjectPtrLabel) +#define glObjectLabel GLEGetCurrentFunction(glObjectLabel) +#define glObjectPtrLabel GLEGetCurrentFunction(glObjectPtrLabel) +#define glPopDebugGroup GLEGetCurrentFunction(glPopDebugGroup) +#define glPushDebugGroup GLEGetCurrentFunction(glPushDebugGroup) + +#define GLE_KHR_debug GLEGetCurrentVariable(gle_KHR_debug) +#endif // GL_KHR_debug + +#ifndef GL_KHR_robust_buffer_access_behavior +#define GL_KHR_robust_buffer_access_behavior 1 + +#define GLE_KHR_robust_buffer_access_behavior \ + GLEGetCurrentVariable(gle_KHR_robust_buffer_access_behavior) +#endif + +/* Disabled until needed +#ifndef GL_KHR_robustness + #define GL_KHR_robustness 1 + + #define GL_CONTEXT_LOST 0x0507 + #define GL_LOSE_CONTEXT_ON_RESET 0x8252 + #define GL_GUILTY_CONTEXT_RESET 0x8253 + #define GL_INNOCENT_CONTEXT_RESET 0x8254 + #define GL_UNKNOWN_CONTEXT_RESET 0x8255 + #define GL_RESET_NOTIFICATION_STRATEGY 0x8256 + #define GL_NO_RESET_NOTIFICATION 0x8261 + #define GL_CONTEXT_ROBUST_ACCESS 0x90F3 + + typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei +bufSize, GLfloat* params); + typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei +bufSize, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei +bufSize, GLuint* params); + typedef void (GLAPIENTRY * PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei +height, GLenum format, GLenum type, GLsizei bufSize, void *data); + + #define glGetnUniformfv GLEGetCurrentFunction(glGetnUniformfv) + #define glGetnUniformiv GLEGetCurrentFunction(glGetnUniformiv) + #define glGetnUniformuiv GLEGetCurrentFunction(glGetnUniformuiv) + #define glReadnPixels GLEGetCurrentFunction(glReadnPixels) + + #define GLE_KHR_robustness GLEGetCurrentVariable(gle_KHR_robustness) + +#endif // GL_KHR_robustness +*/ + +#ifndef GL_WIN_swap_hint +#define GL_WIN_swap_hint 1 + +typedef void( + GLAPIENTRY* PFNGLADDSWAPHINTRECTWINPROC)(GLint x, GLint y, GLsizei width, GLsizei height); + +#define glAddSwapHintRectWIN GLEGetCurrentFunction(glAddSwapHintRectWIN) + +#define GLE_WIN_swap_hint GLEGetCurrentVariable(gle_WIN_swap_hint) +#endif + +/************************************************************************************ + Windows-specific (WGL) functionality +************************************************************************************/ + +#if defined(GLE_WGL_ENABLED) +#ifdef __wglext_h_ +#error wglext.h was included before this header. This header needs to be inlcuded instead of or at least before wglext.h +#endif +#define __wglext_h_ // Prevent wglext.h from having any future effect if it's #included. + +// Declare shared types and structs from wglext.h +DECLARE_HANDLE(HPBUFFERARB); // This type is used by a couple extensions. + +// WGL functions from +#if 0 // defined(GLE_HOOKING_ENABLED) We currently don't hook these. +#define wglCopyContext(...) GLEGetCurrentFunction(wglCopyContext)(__VA_ARGS__) +#define wglCreateContext(...) GLEGetCurrentFunction(wglCreateContext)(__VA_ARGS__) +#define wglCreateLayerContext(...) GLEGetCurrentFunction(wglCreateLayerContext)(__VA_ARGS__) +#define wglDeleteContext(...) GLEGetCurrentFunction(wglDeleteContext)(__VA_ARGS__) +#define wglGetCurrentContext(...) GLEGetCurrentFunction(wglGetCurrentContext)(__VA_ARGS__) +#define wglGetCurrentDC(...) GLEGetCurrentFunction(wglGetCurrentDC)(__VA_ARGS__) +#define wglGetProcAddress(...) GLEGetCurrentFunction(wglGetProcAddress)(__VA_ARGS__) +#define wglMakeCurrent(...) GLEGetCurrentFunction(wglMakeCurrent)(__VA_ARGS__) +#define wglShareLists(...) GLEGetCurrentFunction(wglShareLists)(__VA_ARGS__) +#define wglUseFontBitmapsA(...) GLEGetCurrentFunction(wglUseFontBitmapsA)(__VA_ARGS__) +#define wglUseFontBitmapsW(...) GLEGetCurrentFunction(wglUseFontBitmapsW)(__VA_ARGS__) +#define wglUseFontOutlinesA(...) GLEGetCurrentFunction(wglUseFontOutlinesA)(__VA_ARGS__) +#define wglUseFontOutlinesW(...) GLEGetCurrentFunction(wglUseFontOutlinesW)(__VA_ARGS__) +#define wglDescribeLayerPlane(...) GLEGetCurrentFunction(wglDescribeLayerPlane)(__VA_ARGS__) +#define wglSetLayerPaletteEntries(...) GLEGetCurrentFunction(wglSetLayerPaletteEntries)(__VA_ARGS__) +#define wglGetLayerPaletteEntries(...) GLEGetCurrentFunction(wglGetLayerPaletteEntries)(__VA_ARGS__) +#define wglRealizeLayerPalette(...) GLEGetCurrentFunction(wglRealizeLayerPalette)(__VA_ARGS__) +#define wglSwapLayerBuffers(...) GLEGetCurrentFunction(wglSwapLayerBuffers)(__VA_ARGS__) +#define wglSwapMultipleBuffers(...) GLEGetCurrentFunction(wglSwapMultipleBuffers)(__VA_ARGS__) +#else +// The following functions are directly declared in Microsoft's without associated +// typedefs, and are exported from Opengl32.dll. +// We can link to them directly through Opengl32.lib/dll (same as OpenGL 1.1 functions) or we can +// dynamically link them from OpenGL32.dll at runtime. +typedef BOOL(WINAPI* PFNWGLCOPYCONTEXTPROC)(HGLRC, HGLRC, UINT); +typedef HGLRC(WINAPI* PFNWGLCREATECONTEXTPROC)(HDC); +typedef HGLRC(WINAPI* PFNWGLCREATELAYERCONTEXTPROC)(HDC, int); +typedef BOOL(WINAPI* PFNWGLDELETECONTEXTPROC)(HGLRC); +typedef HGLRC(WINAPI* PFNWGLGETCURRENTCONTEXTPROC)(VOID); +typedef HDC(WINAPI* PFNWGLGETCURRENTDCPROC)(VOID); +typedef PROC(WINAPI* PFNWGLGETPROCADDRESSPROC)(LPCSTR); +typedef BOOL(WINAPI* PFNWGLMAKECURRENTPROC)(HDC, HGLRC); +typedef BOOL(WINAPI* PFNWGLSHARELISTSPROC)(HGLRC, HGLRC); +typedef BOOL(WINAPI* PFNWGLUSEFONTBITMAPSAPROC)(HDC, DWORD, DWORD, DWORD); +typedef BOOL(WINAPI* PFNWGLUSEFONTBITMAPSWPROC)(HDC, DWORD, DWORD, DWORD); +typedef BOOL(WINAPI* PFNWGLUSEFONTOUTLINESAPROC)( + HDC, + DWORD, + DWORD, + DWORD, + FLOAT, + FLOAT, + int, + LPGLYPHMETRICSFLOAT); +typedef BOOL(WINAPI* PFNWGLUSEFONTOUTLINESWPROC)( + HDC, + DWORD, + DWORD, + DWORD, + FLOAT, + FLOAT, + int, + LPGLYPHMETRICSFLOAT); +typedef BOOL(WINAPI* PFNWGLDESCRIBELAYERPLANEPROC)(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR); +typedef int(WINAPI* PFNWGLSETLAYERPALETTEENTRIESPROC)(HDC, int, int, int, CONST COLORREF*); +typedef int(WINAPI* PFNWGLGETLAYERPALETTEENTRIESPROC)(HDC, int, int, int, COLORREF*); +typedef BOOL(WINAPI* PFNWGLREALIZELAYERPALETTEPROC)(HDC, int, BOOL); +typedef BOOL(WINAPI* PFNWGLSWAPLAYERBUFFERSPROC)(HDC, UINT); +typedef DWORD(WINAPI* PFNWGLSWAPMULTIPLEBUFFERSPROC)(UINT, CONST WGLSWAP*); + +#if 0 +#define wglCopyContext OVR::GLEContext::GetCurrentContext()->wglCopyContext_Impl +#define wglCreateContext OVR::GLEContext::GetCurrentContext()->wglCreateContext_Impl +#define wglCreateLayerContext OVR::GLEContext::GetCurrentContext()->wglCreateLayerContext_Impl +#define wglDeleteContext OVR::GLEContext::GetCurrentContext()->wglDeleteContext_Impl +#define wglGetCurrentContext OVR::GLEContext::GetCurrentContext()->wglGetCurrentContext_Impl +#define wglGetCurrentDC OVR::GLEContext::GetCurrentContext()->wglGetCurrentDC_Impl +#define wglGetProcAddress OVR::GLEContext::GetCurrentContext()->wglGetProcAddress_Impl +#define wglMakeCurrent OVR::GLEContext::GetCurrentContext()->wglMakeCurrent_Impl +#define wglShareLists OVR::GLEContext::GetCurrentContext()->wglShareLists_Impl +#define wglUseFontBitmapsA OVR::GLEContext::GetCurrentContext()->wglUseFontBitmapsA_Impl +#define wglUseFontBitmapsW OVR::GLEContext::GetCurrentContext()->wglUseFontBitmapsW_Impl +#define wglUseFontOutlinesA OVR::GLEContext::GetCurrentContext()->wglUseFontOutlinesA_Impl +#define wglUseFontOutlinesW OVR::GLEContext::GetCurrentContext()->wglUseFontOutlinesW_Impl +#define wglDescribeLayerPlane OVR::GLEContext::GetCurrentContext()->wglDescribeLayerPlane_Impl +#define wglSetLayerPaletteEntries \ + OVR::GLEContext::GetCurrentContext()->wglSetLayerPaletteEntries_Impl +#define wglGetLayerPaletteEntries \ + OVR::GLEContext::GetCurrentContext()->wglGetLayerPaletteEntries_Impl +#define wglRealizeLayerPalette OVR::GLEContext::GetCurrentContext()->wglRealizeLayerPalette_Impl +#define wglSwapLayerBuffers OVR::GLEContext::GetCurrentContext()->wglSwapLayerBuffers_Impl +#define wglSwapMultipleBuffers OVR::GLEContext::GetCurrentContext()->wglSwapMultipleBuffers_Impl +#endif +#endif + +// Note: In order to detect the WGL extensions' availability, we need to call +// wglGetExtensionsStringARB or +// wglGetExtensionsStringEXT instead of glGetString(GL_EXTENSIONS). +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 + +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 + +typedef HANDLE(WINAPI* PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC, int iLayerPlane, UINT uType); +typedef VOID(WINAPI* PFNWGLDELETEBUFFERREGIONARBPROC)(HANDLE hRegion); +typedef BOOL( + WINAPI* PFNWGLSAVEBUFFERREGIONARBPROC)(HANDLE hRegion, int x, int y, int width, int height); +typedef BOOL(WINAPI* PFNWGLRESTOREBUFFERREGIONARBPROC)( + HANDLE hRegion, + int x, + int y, + int width, + int height, + int xSrc, + int ySrc); + +#define wglCreateBufferRegionARB GLEGetCurrentFunction(wglCreateBufferRegionARB) +#define wglDeleteBufferRegionARB GLEGetCurrentFunction(wglDeleteBufferRegionARB) +#define wglSaveBufferRegionARB GLEGetCurrentFunction(wglSaveBufferRegionARB) +#define wglRestoreBufferRegionARB GLEGetCurrentFunction(wglRestoreBufferRegionARB) + +#define GLE_WGL_ARB_buffer_region GLEGetCurrentVariable(gle_WGL_ARB_buffer_region) +#endif + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 + +typedef const char*(WINAPI* PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc); + +#define wglGetExtensionsStringARB GLEGetCurrentFunction(wglGetExtensionsStringARB) + +#define GLE_WGL_ARB_extensions_string GLEGetCurrentVariable(gle_WGL_ARB_extensions_string) +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C + +typedef BOOL(WINAPI* PFNWGLGETPIXELFORMATATTRIBIVARBPROC)( + HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int* piAttributes, + int* piValues); +typedef BOOL(WINAPI* PFNWGLGETPIXELFORMATATTRIBFVARBPROC)( + HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int* piAttributes, + FLOAT* pfValues); +typedef BOOL(WINAPI* PFNWGLCHOOSEPIXELFORMATARBPROC)( + HDC hdc, + const int* piAttribIList, + const FLOAT* pfAttribFList, + UINT nMaxFormats, + int* piFormats, + UINT* nNumFormats); + +#define wglGetPixelFormatAttribivARB GLEGetCurrentFunction(wglGetPixelFormatAttribivARB) +#define wglGetPixelFormatAttribfvARB GLEGetCurrentFunction(wglGetPixelFormatAttribfvARB) +#define wglChoosePixelFormatARB GLEGetCurrentFunction(wglChoosePixelFormatARB) + +#define GLE_WGL_ARB_pixel_format GLEGetCurrentVariable(gle_WGL_ARB_pixel_format) +#endif + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 + +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 + +typedef BOOL(WINAPI* PFNWGLMAKECONTEXTCURRENTARBPROC)(HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC(WINAPI* PFNWGLGETCURRENTREADDCARBPROC)(void); + +#define wglMakeContextCurrentARB GLEGetCurrentFunction(wglMakeContextCurrentARB) +#define wglGetCurrentReadDCARB GLEGetCurrentFunction(wglGetCurrentReadDCARB) + +#define GLE_WGL_ARB_make_current_read GLEGetCurrentVariable(gle_WGL_ARB_make_current_read) +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 + +typedef HPBUFFERARB(WINAPI* PFNWGLCREATEPBUFFERARBPROC)( + HDC hDC, + int iPixelFormat, + int iWidth, + int iHeight, + const int* piAttribList); +typedef HDC(WINAPI* PFNWGLGETPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer); +typedef int(WINAPI* PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer, HDC hDC); +typedef BOOL(WINAPI* PFNWGLDESTROYPBUFFERARBPROC)(HPBUFFERARB hPbuffer); +typedef BOOL(WINAPI* PFNWGLQUERYPBUFFERARBPROC)(HPBUFFERARB hPbuffer, int iAttribute, int* piValue); + +#define wglCreatePbufferARB GLEGetCurrentFunction(wglCreatePbufferARB) +#define wglGetPbufferDCARB GLEGetCurrentFunction(wglGetPbufferDCARB) +#define wglReleasePbufferDCARB GLEGetCurrentFunction(wglReleasePbufferDCARB) +#define wglDestroyPbufferARB GLEGetCurrentFunction(wglDestroyPbufferARB) +#define wglQueryPbufferARB GLEGetCurrentFunction(wglQueryPbufferARB) + +#define GLE_WGL_ARB_pbuffer GLEGetCurrentVariable(gle_WGL_ARB_pbuffer) +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 + +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 + +typedef BOOL(WINAPI* PFNWGLBINDTEXIMAGEARBPROC)(HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL(WINAPI* PFNWGLRELEASETEXIMAGEARBPROC)(HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL(WINAPI* PFNWGLSETPBUFFERATTRIBARBPROC)(HPBUFFERARB hPbuffer, const int* piAttribList); + +#define wglBindTexImageARB GLEGetCurrentFunction(wglBindTexImageARB) +#define wglReleaseTexImageARB GLEGetCurrentFunction(wglReleaseTexImageARB) +#define wglSetPbufferAttribARB GLEGetCurrentFunction(wglSetPbufferAttribARB) + +#define GLE_WGL_ARB_render_texture GLEGetCurrentVariable(gle_WGL_ARB_render_texture) +#endif + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 + +#define GLE_WGL_ARB_pixel_format_float GLEGetCurrentVariable(gle_WGL_ARB_pixel_format_float) +#endif + +#ifndef WGL_ARB_framebuffer_sRGB +#define WGL_ARB_framebuffer_sRGB 1 + +// There is also the WGL_EXT_framebuffer_sRGB extension, which is the +// same as this. So use this one instead of that for checking. +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 + +#define GLE_WGL_ARB_framebuffer_sRGB GLEGetCurrentVariable(gle_WGL_ARB_framebuffer_sRGB) +#endif + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video 1 + +DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); + +typedef int(WINAPI* PFNWGLENUMERATEVIDEODEVICESNVPROC)(HDC hDC, HVIDEOOUTPUTDEVICENV* phDeviceList); +typedef BOOL(WINAPI* PFNWGLBINDVIDEODEVICENVPROC)( + HDC hDC, + unsigned int uVideoSlot, + HVIDEOOUTPUTDEVICENV hVideoDevice, + const int* piAttribList); +typedef BOOL(WINAPI* PFNWGLQUERYCURRENTCONTEXTNVPROC)(int iAttribute, int* piValue); + +#define wglEnumerateVideoDevicesNV GLEGetCurrentFunction(wglEnumerateVideoDevicesNV) +#define wglBindVideoDeviceNV GLEGetCurrentFunction(wglBindVideoDeviceNV) +#define wglQueryCurrentContextNV GLEGetCurrentFunction(wglQueryCurrentContextNV) + +#define GLE_WGL_NV_present_video GLEGetCurrentVariable(gle_WGL_NV_present_video) +#endif + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context 1 + +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define ERROR_INVALID_VERSION_ARB 0x2095 + +typedef HGLRC( + WINAPI* PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hDC, HGLRC hShareContext, const int* attribList); + +#define wglCreateContextAttribsARB GLEGetCurrentFunction(wglCreateContextAttribsARB) + +#define GLE_WGL_ARB_create_context GLEGetCurrentVariable(gle_WGL_ARB_create_context) +#endif + +#ifndef WGL_ARB_create_context_profile +#define WGL_ARB_create_context_profile 1 + +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define ERROR_INVALID_PROFILE_ARB 0x2096 + +#define GLE_WGL_ARB_create_context_profile GLEGetCurrentVariable(gle_WGL_ARB_create_context_profile) +#endif + +#ifndef WGL_ARB_create_context_robustness +#define WGL_ARB_create_context_robustness 1 + +#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 + +#define GLE_WGL_ARB_create_context_robustness \ + GLEGetCurrentVariable(gle_WGL_ARB_create_context_robustness) +#endif + +#ifndef WGL_ATI_render_texture_rectangle +#define WGL_ATI_render_texture_rectangle 1 + +#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 + +#define GLE_WGL_ATI_render_texture_rectangle \ + GLEGetCurrentVariable(gle_WGL_ATI_render_texture_rectangle) +#endif + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 + +typedef const char*(WINAPI* PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void); + +#define wglGetExtensionsStringEXT GLEGetCurrentFunction(wglGetExtensionsStringEXT) + +#define GLE_WGL_EXT_extensions_string GLEGetCurrentVariable(gle_WGL_EXT_extensions_string) +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 + +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 + +#define GLE_WGL_NV_render_texture_rectangle \ + GLEGetCurrentVariable(gle_WGL_NV_render_texture_rectangle) +#endif + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 + +typedef int(WINAPI* PFNWGLGETSWAPINTERVALEXTPROC)(void); +typedef BOOL(WINAPI* PFNWGLSWAPINTERVALEXTPROC)(int interval); + +#define wglGetSwapIntervalEXT GLEGetCurrentFunction(wglGetSwapIntervalEXT) +#define wglSwapIntervalEXT GLEGetCurrentFunction(wglSwapIntervalEXT) + +#define GLE_WGL_EXT_swap_control GLEGetCurrentVariable(gle_WGL_EXT_swap_control) +#endif + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 + +typedef BOOL(WINAPI* PFNWGLGETSYNCVALUESOMLPROC)(HDC hdc, INT64* ust, INT64* msc, INT64* sbc); +typedef BOOL(WINAPI* PFNWGLGETMSCRATEOMLPROC)(HDC hdc, INT32* numerator, INT32* denominator); +typedef INT64( + WINAPI* PFNWGLSWAPBUFFERSMSCOMLPROC)(HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64(WINAPI* PFNWGLSWAPLAYERBUFFERSMSCOMLPROC)( + HDC hdc, + int fuPlanes, + INT64 target_msc, + INT64 divisor, + INT64 remainder); +typedef BOOL(WINAPI* PFNWGLWAITFORMSCOMLPROC)( + HDC hdc, + INT64 target_msc, + INT64 divisor, + INT64 remainder, + INT64* ust, + INT64* msc, + INT64* sbc); +typedef BOOL( + WINAPI* PFNWGLWAITFORSBCOMLPROC)(HDC hdc, INT64 target_sbc, INT64* ust, INT64* msc, INT64* sbc); + +#define wglGetSyncValuesOML GLEGetCurrentFunction(wglGetSyncValuesOML) +#define wglGetMscRateOML GLEGetCurrentFunction(wglGetMscRateOML) +#define wglSwapBuffersMscOML GLEGetCurrentFunction(wglSwapBuffersMscOML) +#define wglSwapLayerBuffersMscOML GLEGetCurrentFunction(wglSwapLayerBuffersMscOML) +#define wglWaitForMscOML GLEGetCurrentFunction(wglWaitForMscOML) +#define wglWaitForSbcOML GLEGetCurrentFunction(wglWaitForSbcOML) + +#define GLE_WGL_OML_sync_control GLEGetCurrentVariable(gle_WGL_OML_sync_control) +#endif + +#ifndef WGL_NV_video_output +#define WGL_NV_video_output 1 + +DECLARE_HANDLE(HPVIDEODEV); + +typedef BOOL(WINAPI* PFNWGLGETVIDEODEVICENVPROC)(HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice); +typedef BOOL(WINAPI* PFNWGLRELEASEVIDEODEVICENVPROC)(HPVIDEODEV hVideoDevice); +typedef BOOL(WINAPI* PFNWGLBINDVIDEOIMAGENVPROC)( + HPVIDEODEV hVideoDevice, + HPBUFFERARB hPbuffer, + int iVideoBuffer); +typedef BOOL(WINAPI* PFNWGLRELEASEVIDEOIMAGENVPROC)(HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL(WINAPI* PFNWGLSENDPBUFFERTOVIDEONVPROC)( + HPBUFFERARB hPbuffer, + int iBufferType, + unsigned long* pulCounterPbuffer, + BOOL bBlock); +typedef BOOL(WINAPI* PFNWGLGETVIDEOINFONVPROC)( + HPVIDEODEV hpVideoDevice, + unsigned long* pulCounterOutputPbuffer, + unsigned long* pulCounterOutputVideo); + +#define wglGetVideoDeviceNV GLEGetCurrentFunction(wglGetVideoDeviceNV) +#define wglReleaseVideoDeviceNV GLEGetCurrentFunction(wglReleaseVideoDeviceNV) +#define wglBindVideoImageNV GLEGetCurrentFunction(wglBindVideoImageNV) +#define wglReleaseVideoImageNV GLEGetCurrentFunction(wglReleaseVideoImageNV) +#define wglSendPbufferToVideoNV GLEGetCurrentFunction(wglSendPbufferToVideoNV) +#define wglGetVideoInfoNV GLEGetCurrentFunction(wglGetVideoInfoNV) + +#define GLE_WGL_NV_video_output GLEGetCurrentVariable(gle_WGL_NV_video_output) +#endif + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group 1 + +typedef BOOL(WINAPI* PFNWGLJOINSWAPGROUPNVPROC)(HDC hDC, GLuint group); +typedef BOOL(WINAPI* PFNWGLBINDSWAPBARRIERNVPROC)(GLuint group, GLuint barrier); +typedef BOOL(WINAPI* PFNWGLQUERYSWAPGROUPNVPROC)(HDC hDC, GLuint* group, GLuint* barrier); +typedef BOOL( + WINAPI* PFNWGLQUERYMAXSWAPGROUPSNVPROC)(HDC hDC, GLuint* maxGroups, GLuint* maxBarriers); +typedef BOOL(WINAPI* PFNWGLQUERYFRAMECOUNTNVPROC)(HDC hDC, GLuint* count); +typedef BOOL(WINAPI* PFNWGLRESETFRAMECOUNTNVPROC)(HDC hDC); + +#define wglJoinSwapGroupNV GLEGetCurrentFunction(wglJoinSwapGroupNV) +#define wglBindSwapBarrierNV GLEGetCurrentFunction(wglBindSwapBarrierNV) +#define wglQuerySwapGroupNV GLEGetCurrentFunction(wglQuerySwapGroupNV) +#define wglQueryMaxSwapGroupsNV GLEGetCurrentFunction(wglQueryMaxSwapGroupsNV) +#define wglQueryFrameCountNV GLEGetCurrentFunction(wglQueryFrameCountNV) +#define wglResetFrameCountNV GLEGetCurrentFunction(wglResetFrameCountNV) + +#define GLE_WGL_NV_swap_group GLEGetCurrentVariable(gle_WGL_NV_swap_group) +#endif + +#ifndef WGL_NV_video_capture +#define WGL_NV_video_capture 1 + +#define WGL_UNIQUE_ID_NV 0x20CE +#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF + +typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +} GPU_DEVICE, *PGPU_DEVICE; +DECLARE_HANDLE(HVIDEOINPUTDEVICENV); + +typedef BOOL( + WINAPI* PFNWGLBINDVIDEOCAPTUREDEVICENVPROC)(UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); +typedef UINT( + WINAPI* PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC)(HDC hDc, HVIDEOINPUTDEVICENV* phDeviceList); +typedef BOOL(WINAPI* PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC)(HDC hDc, HVIDEOINPUTDEVICENV hDevice); +typedef BOOL(WINAPI* PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC)( + HDC hDc, + HVIDEOINPUTDEVICENV hDevice, + int iAttribute, + int* piValue); +typedef BOOL(WINAPI* PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC)(HDC hDc, HVIDEOINPUTDEVICENV hDevice); + +#define wglBindVideoCaptureDeviceNV GLEGetCurrentFunction(wglBindVideoCaptureDeviceNV) +#define wglEnumerateVideoCaptureDevicesNV GLEGetCurrentFunction(wglEnumerateVideoCaptureDevicesNV) +#define wglLockVideoCaptureDeviceNV GLEGetCurrentFunction(wglLockVideoCaptureDeviceNV) +#define wglQueryVideoCaptureDeviceNV GLEGetCurrentFunction(wglQueryVideoCaptureDeviceNV) +#define wglReleaseVideoCaptureDeviceNV GLEGetCurrentFunction(wglReleaseVideoCaptureDeviceNV) + +#define GLE_WGL_NV_video_capture GLEGetCurrentVariable(gle_WGL_NV_video_capture) +#endif + +#ifndef WGL_NV_copy_image +#define WGL_NV_copy_image 1 + +typedef BOOL(WINAPI* PFNWGLCOPYIMAGESUBDATANVPROC)( + HGLRC hSrcRC, + GLuint srcName, + GLenum srcTarget, + GLint srcLevel, + GLint srcX, + GLint srcY, + GLint srcZ, + HGLRC hDstRC, + GLuint dstName, + GLenum dstTarget, + GLint dstLevel, + GLint dstX, + GLint dstY, + GLint dstZ, + GLsizei width, + GLsizei height, + GLsizei depth); + +#define wglCopyImageSubDataNV GLEGetCurrentFunction(wglCopyImageSubDataNV) + +#define GLE_WGL_NV_copy_image GLEGetCurrentVariable(gle_WGL_NV_copy_image) +#endif + +#ifndef WGL_NV_DX_interop +#define WGL_NV_DX_interop 1 + +// Note that modern AMD drivers support this NVidia extension. +#define WGL_ACCESS_READ_ONLY_NV 0x0000 +#define WGL_ACCESS_READ_WRITE_NV 0x0001 +#define WGL_ACCESS_WRITE_DISCARD_NV 0x0002 + +typedef BOOL(WINAPI* PFNWGLDXCLOSEDEVICENVPROC)(HANDLE hDevice); +typedef BOOL(WINAPI* PFNWGLDXLOCKOBJECTSNVPROC)(HANDLE hDevice, GLint count, HANDLE* hObjects); +typedef BOOL(WINAPI* PFNWGLDXOBJECTACCESSNVPROC)(HANDLE hObject, GLenum access); +typedef HANDLE(WINAPI* PFNWGLDXOPENDEVICENVPROC)(void* dxDevice); +typedef HANDLE(WINAPI* PFNWGLDXREGISTEROBJECTNVPROC)( + HANDLE hDevice, + void* dxObject, + GLuint name, + GLenum type, + GLenum access); +typedef BOOL(WINAPI* PFNWGLDXSETRESOURCESHAREHANDLENVPROC)(void* dxObject, HANDLE shareHandle); +typedef BOOL(WINAPI* PFNWGLDXUNLOCKOBJECTSNVPROC)(HANDLE hDevice, GLint count, HANDLE* hObjects); +typedef BOOL(WINAPI* PFNWGLDXUNREGISTEROBJECTNVPROC)(HANDLE hDevice, HANDLE hObject); + +#define wglDXCloseDeviceNV GLEGetCurrentFunction(wglDXCloseDeviceNV) +#define wglDXLockObjectsNV GLEGetCurrentFunction(wglDXLockObjectsNV) +#define wglDXObjectAccessNV GLEGetCurrentFunction(wglDXObjectAccessNV) +#define wglDXOpenDeviceNV GLEGetCurrentFunction(wglDXOpenDeviceNV) +#define wglDXRegisterObjectNV GLEGetCurrentFunction(wglDXRegisterObjectNV) +#define wglDXSetResourceShareHandleNV GLEGetCurrentFunction(wglDXSetResourceShareHandleNV) +#define wglDXUnlockObjectsNV GLEGetCurrentFunction(wglDXUnlockObjectsNV) +#define wglDXUnregisterObjectNV GLEGetCurrentFunction(wglDXUnregisterObjectNV) + +#define GLE_WGL_NV_DX_interop GLEGetCurrentVariable(gle_WGL_NV_DX_interop) +#endif + +#ifndef WGL_NV_DX_interop2 +#define WGL_NV_DX_interop2 1 + +// This is an update to WGL_NV_DX_interop to support DX10/DX11. +// https://www.opengl.org/registry/specs/NV/DX_interop2.txt +#define GLE_WGL_NV_DX_interop2 GLEGetCurrentVariable(gle_WGL_NV_DX_interop2) + +#endif + +#endif // GLE_WGL_ENABLED + +/************************************************************************************ + Apple-specific (CGL) functionality +************************************************************************************/ + +#if defined(GLE_CGL_ENABLED) +// We don't currently disable Apple's OpenGL/OpenGL.h and replicate its declarations here. +// We might want to do that if we intended to support hooking its functions here like we do for wgl +// functions. +#include +#endif + +/************************************************************************************ + Unix-specific (GLX) functionality +************************************************************************************/ + +#if defined(GLE_GLX_ENABLED) +#ifdef __glxext_h_ +#error glxext.h was included before this header. This header needs to be inlcuded instead of or at least before glxext.h +#endif +#define __glxext_h_ + +#if defined(GLX_H) || defined(__GLX_glx_h__) || defined(__glx_h__) +#error glx.h was included before this header. This header needs to be inlcuded instead of or at least before glx.h +#endif +#define GLX_H +#define __GLX_glx_h__ +#define __glx_h__ + +// FIXME: Including These Raw Causes Major Conflicts! +#include +#include +#include + +// GLX version 1.0 functions are assumed to always be present. +#ifndef GLX_VERSION_1_0 +#define GLX_VERSION_1_0 1 + +#define GLX_USE_GL 1 +#define GLX_BUFFER_SIZE 2 +#define GLX_LEVEL 3 +#define GLX_RGBA 4 +#define GLX_DOUBLEBUFFER 5 +#define GLX_STEREO 6 +#define GLX_AUX_BUFFERS 7 +#define GLX_RED_SIZE 8 +#define GLX_GREEN_SIZE 9 +#define GLX_BLUE_SIZE 10 +#define GLX_ALPHA_SIZE 11 +#define GLX_DEPTH_SIZE 12 +#define GLX_STENCIL_SIZE 13 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_ALPHA_SIZE 17 +#define GLX_BAD_SCREEN 1 +#define GLX_BAD_ATTRIBUTE 2 +#define GLX_NO_EXTENSION 3 +#define GLX_BAD_VISUAL 4 +#define GLX_BAD_CONTEXT 5 +#define GLX_BAD_VALUE 6 +#define GLX_BAD_ENUM 7 + +typedef XID GLXDrawable; +typedef XID GLXPixmap; +typedef unsigned int GLXVideoDeviceNV; +typedef struct __GLXcontextRec* GLXContext; + +// GLE_HOOKING_ENABLED +// We don't currently support hooking the following GLX 1.0 functions like we do with the analagous +// windows wgl functions. +// However, we can do this if needed. We would just have something like this: +// #define glXQueryExtension(...) GLEGetCurrentFunction(glXQueryExtension)(__VA_ARGS__) +// plus a member function like: +// Bool glXQueryExtension_Hook(Display*, int*, int*); +// See wglCopyContext for an example. + +extern Bool glXQueryExtension(Display* dpy, int* errorBase, int* eventBase); +extern Bool glXQueryVersion(Display* dpy, int* major, int* minor); +extern int glXGetConfig(Display* dpy, XVisualInfo* vis, int attrib, int* value); +extern XVisualInfo* glXChooseVisual(Display* dpy, int screen, int* attribList); +extern GLXPixmap glXCreateGLXPixmap(Display* dpy, XVisualInfo* vis, Pixmap pixmap); +extern void glXDestroyGLXPixmap(Display* dpy, GLXPixmap pix); +extern GLXContext +glXCreateContext(Display* dpy, XVisualInfo* vis, GLXContext shareList, Bool direct); +extern void glXDestroyContext(Display* dpy, GLXContext ctx); +extern Bool glXIsDirect(Display* dpy, GLXContext ctx); +extern void glXCopyContext(Display* dpy, GLXContext src, GLXContext dst, GLulong mask); +extern Bool glXMakeCurrent(Display* dpy, GLXDrawable drawable, GLXContext ctx); +extern GLXContext glXGetCurrentContext(void); +extern GLXDrawable glXGetCurrentDrawable(void); +extern void glXWaitGL(void); +extern void glXWaitX(void); +extern void glXSwapBuffers(Display* dpy, GLXDrawable drawable); +extern void glXUseXFont(Font font, int first, int count, int listBase); + +#endif // GLX_VERSION_1_0 + +#ifndef GLX_VERSION_1_1 +#define GLX_VERSION_1_1 + +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_EXTENSIONS 0x3 + +// These function pointers are assumed to always be present. +extern const char* glXQueryExtensionsString(Display* dpy, int screen); +extern const char* glXGetClientString(Display* dpy, int name); +extern const char* glXQueryServerString(Display* dpy, int screen, int name); +#endif + +#ifndef GLX_VERSION_1_2 +#define GLX_VERSION_1_2 1 + +typedef Display* (*PFNGLXGETCURRENTDISPLAYPROC)(void); + +#define glXGetCurrentDisplay GLEGetCurrentFunction(glXGetCurrentDisplay) +#endif + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 + +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_DONT_CARE 0xFFFFFFFF + +typedef XID GLXFBConfigID; +typedef XID GLXPbuffer; +typedef XID GLXWindow; +typedef struct __GLXFBConfigRec* GLXFBConfig; + +typedef struct { + int event_type; + int draw_type; + unsigned long serial; + Bool send_event; + Display* display; + GLXDrawable drawable; + unsigned int buffer_mask; + unsigned int aux_buffer; + int x, y; + int width, height; + int count; +} GLXPbufferClobberEvent; + +typedef union __GLXEvent { + GLXPbufferClobberEvent glxpbufferclobber; + long pad[24]; +} GLXEvent; + +typedef GLXFBConfig* ( + *PFNGLXCHOOSEFBCONFIGPROC)(::Display* dpy, int screen, const int* attrib_list, int* nelements); +typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)( + ::Display* dpy, + GLXFBConfig config, + int render_type, + GLXContext share_list, + Bool direct); +typedef GLXPbuffer ( + *PFNGLXCREATEPBUFFERPROC)(::Display* dpy, GLXFBConfig config, const int* attrib_list); +typedef GLXPixmap (*PFNGLXCREATEPIXMAPPROC)( + ::Display* dpy, + GLXFBConfig config, + Pixmap pixmap, + const int* attrib_list); +typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)( + ::Display* dpy, + GLXFBConfig config, + Window win, + const int* attrib_list); +typedef void (*PFNGLXDESTROYPBUFFERPROC)(::Display* dpy, GLXPbuffer pbuf); +typedef void (*PFNGLXDESTROYPIXMAPPROC)(::Display* dpy, GLXPixmap pixmap); +typedef void (*PFNGLXDESTROYWINDOWPROC)(::Display* dpy, GLXWindow win); +typedef GLXDrawable (*PFNGLXGETCURRENTREADDRAWABLEPROC)(void); +typedef int ( + *PFNGLXGETFBCONFIGATTRIBPROC)(::Display* dpy, GLXFBConfig config, int attribute, int* value); +typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(::Display* dpy, int screen, int* nelements); +typedef void ( + *PFNGLXGETSELECTEDEVENTPROC)(::Display* dpy, GLXDrawable draw, unsigned long* event_mask); +typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(::Display* dpy, GLXFBConfig config); +typedef Bool (*PFNGLXMAKECONTEXTCURRENTPROC)( + ::Display* display, + GLXDrawable draw, + GLXDrawable read, + GLXContext ctx); +typedef int (*PFNGLXQUERYCONTEXTPROC)(::Display* dpy, GLXContext ctx, int attribute, int* value); +typedef void ( + *PFNGLXQUERYDRAWABLEPROC)(::Display* dpy, GLXDrawable draw, int attribute, unsigned int* value); +typedef void (*PFNGLXSELECTEVENTPROC)(::Display* dpy, GLXDrawable draw, unsigned long event_mask); + +#define glXChooseFBConfig GLEGetCurrentFunction(glXChooseFBConfig) +#define glXCreateNewContext GLEGetCurrentFunction(glXCreateNewContext) +#define glXCreatePbuffer GLEGetCurrentFunction(glXCreatePbuffer) +#define glXCreatePixmap GLEGetCurrentFunction(glXCreatePixmap) +#define glXCreateWindow GLEGetCurrentFunction(glXCreateWindow) +#define glXDestroyPbuffer GLEGetCurrentFunction(glXDestroyPbuffer) +#define glXDestroyPixmap GLEGetCurrentFunction(glXDestroyPixmap) +#define glXDestroyWindow GLEGetCurrentFunction(glXDestroyWindow) +#define glXGetCurrentReadDrawable GLEGetCurrentFunction(glXGetCurrentReadDrawable) +#define glXGetFBConfigAttrib GLEGetCurrentFunction(glXGetFBConfigAttrib) +#define glXGetFBConfigs GLEGetCurrentFunction(glXGetFBConfigs) +#define glXGetSelectedEvent GLEGetCurrentFunction(glXGetSelectedEvent) +#define glXGetVisualFromFBConfig GLEGetCurrentFunction(glXGetVisualFromFBConfig) +#define glXMakeContextCurrent GLEGetCurrentFunction(glXMakeContextCurrent) +#define glXQueryContext GLEGetCurrentFunction(glXQueryContext) +#define glXQueryDrawable GLEGetCurrentFunction(glXQueryDrawable) +#define glXSelectEvent GLEGetCurrentFunction(glXSelectEvent) + +#endif // GLX_VERSION_1_3 + +#ifndef GLX_VERSION_1_4 +#define GLX_VERSION_1_4 1 + +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 + +// This was glXGetProcAddressARB in GLX versions prior to v1.4. +// This function pointer is assumed to always be present. +extern void (*glXGetProcAddress(const GLubyte* procName))(); + +// For backward compatibility +extern void (*glXGetProcAddressARB(const GLubyte* procName))(); +#endif + +#ifndef GLX_ARB_create_context +#define GLX_ARB_create_context 1 + +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 + +typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)( + Display* dpy, + GLXFBConfig config, + GLXContext share_context, + Bool direct, + const int* attrib_list); + +#define glXCreateContextAttribsARB GLEGetCurrentFunction(glXCreateContextAttribsARB) + +#define GLE_GLX_ARB_create_context GLEGetCurrentVariable(gle_GLX_ARB_create_context) +#endif + +#ifndef GLX_ARB_create_context_profile +#define GLX_ARB_create_context_profile 1 + +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 + +#define GLE_GLX_ARB_create_context_profile GLEGetCurrentVariable(gle_GLX_ARB_create_context_profile) +#endif + +#ifndef GLX_ARB_create_context_robustness +#define GLX_ARB_create_context_robustness 1 + +#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 + +#define GLE_GLX_ARB_create_context_robustness \ + GLEGetCurrentVariable(gle_GLX_ARB_create_context_robustness) +#endif + +// Note: In order to detect the GLX extensions' availability, we need to call +// glXQueryExtensionsString instead of glGetString(GL_EXTENSIONS). +#ifndef GLX_EXT_swap_control +#define GLX_EXT_swap_control 1 + +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 + +typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display* dpy, GLXDrawable drawable, int interval); + +#define glXSwapIntervalEXT GLEGetCurrentFunction(glXSwapIntervalEXT) + +#define GLE_GLX_EXT_swap_control GLEGetCurrentVariable(gle_GLX_EXT_swap_control) +#endif + +#ifndef GLX_OML_sync_control +#define GLX_OML_sync_control 1 + +typedef Bool (*PFNGLXGETMSCRATEOMLPROC)( + Display* dpy, + GLXDrawable drawable, + int32_t* numerator, + int32_t* denominator); +typedef Bool (*PFNGLXGETSYNCVALUESOMLPROC)( + Display* dpy, + GLXDrawable drawable, + int64_t* ust, + int64_t* msc, + int64_t* sbc); +typedef int64_t (*PFNGLXSWAPBUFFERSMSCOMLPROC)( + Display* dpy, + GLXDrawable drawable, + int64_t target_msc, + int64_t divisor, + int64_t remainder); +typedef Bool (*PFNGLXWAITFORMSCOMLPROC)( + Display* dpy, + GLXDrawable drawable, + int64_t target_msc, + int64_t divisor, + int64_t remainder, + int64_t* ust, + int64_t* msc, + int64_t* sbc); +typedef Bool (*PFNGLXWAITFORSBCOMLPROC)( + Display* dpy, + GLXDrawable drawable, + int64_t target_sbc, + int64_t* ust, + int64_t* msc, + int64_t* sbc); + +#define glXGetMscRateOML GLEGetCurrentFunction(glXGetMscRateOML) +#define glXGetSyncValuesOML GLEGetCurrentFunction(glXGetSyncValuesOML) +#define glXSwapBuffersMscOML GLEGetCurrentFunction(glXSwapBuffersMscOML) +#define glXWaitForMscOML GLEGetCurrentFunction(glXWaitForMscOML) +#define glXWaitForSbcOML GLEGetCurrentFunction(glXWaitForSbcOML) + +#define GLE_GLX_OML_sync_control GLEGetCurrentVariable(gle_GLX_OML_sync_control) +#endif + +#ifndef GLX_MESA_swap_control +#define GLX_MESA_swap_control 1 + +// GLX_MESA_swap_control has the same functionality as GLX_EXT_swap_control but with a different +// interface, so we have an independent entry for it here. +typedef int (*PFNGLXGETSWAPINTERVALMESAPROC)(void); +typedef int (*PFNGLXSWAPINTERVALMESAPROC)(unsigned int interval); + +#define glXGetSwapIntervalMESA GLEGetCurrentFunction(glXGetSwapIntervalMESA) +#define glXSwapIntervalMESA GLEGetCurrentFunction(glXSwapIntervalMESA) + +#define GLE_MESA_swap_control GLEGetCurrentVariable(gle_MESA_swap_control) +#endif + +#endif // GLE_GLX_ENABLED + +// Undo some defines, because the user may include after including this header. +#if defined(GLE_WINGDIAPI_DEFINED) +#undef WINGDIAPI +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // OVR_CAPI_GLE_GL_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Alg.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Alg.cpp new file mode 100644 index 0000000..89573f7 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Alg.cpp @@ -0,0 +1,53 @@ +/************************************************************************************ + +Filename : OVR_Alg.cpp +Content : Static lookup tables for Alg functions +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Types.h" + +namespace OVR { +namespace Alg { + +//------------------------------------------------------------------------ +extern const uint8_t UpperBitTable[256] = { + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; + +extern const uint8_t LowerBitTable[256] = { + 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0}; +} // namespace Alg +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Alg.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Alg.h new file mode 100644 index 0000000..6dcd51c --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Alg.h @@ -0,0 +1,1385 @@ +/************************************************************************************ + +Filename : OVR_Alg.h +Content : Simple general purpose algorithms: Sort, Binary Search, etc. +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Alg_h +#define OVR_Alg_h + +#include +#include "OVR_Types.h" +#if defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#pragma intrinsic(_BitScanReverse) +#if defined(_M_AMD64) +#pragma intrinsic(_BitScanForward64) +#pragma intrinsic(_BitScanReverse64) +#endif +#elif defined(__GNUC__) || defined(__clang__) +#include +#endif + +namespace OVR { +namespace Alg { + +inline int CountTrailing0Bits(uint16_t x) { +#if defined(_MSC_VER) + unsigned long i; + unsigned char nonZero = _BitScanForward(&i, x); + return nonZero ? (int)i : 16; + +#elif defined(__GNUC__) || defined(__clang__) + if (x) + return __builtin_ctz(x); + return 16; +#else + if (x) { + int n = 1; + if ((x & 0x000000ff) == 0) { + n += 8; + x >>= 8; + } + if ((x & 0x0000000f) == 0) { + n += 4; + x >>= 4; + } + if ((x & 0x00000003) == 0) { + n += 2; + x >>= 2; + } + return n - int(x & 1); + } + return 16; +#endif +} + +inline int CountTrailing0Bits(uint32_t x) { +#if defined(_MSC_VER) + unsigned long i; + unsigned char nonZero = _BitScanForward(&i, x); + return nonZero ? (int)i : 32; +#elif defined(__GNUC__) || defined(__clang__) + if (x) + return __builtin_ctz(x); + return 32; +#else + if (x) { + int n = 1; + if ((x & 0x0000ffff) == 0) { + n += 16; + x >>= 16; + } + if ((x & 0x000000ff) == 0) { + n += 8; + x >>= 8; + } + if ((x & 0x0000000f) == 0) { + n += 4; + x >>= 4; + } + if ((x & 0x00000003) == 0) { + n += 2; + x >>= 2; + } + return n - int(x & 1); + } + return 32; +#endif +} + +inline int CountTrailing0Bits(uint64_t x) { +#if defined(_MSC_VER) && defined(_M_AMD64) + unsigned long i; + unsigned char nonZero = _BitScanForward64(&i, x); + return nonZero ? (int)i : 64; +#elif (defined(__GNUC__) || defined(__clang__)) && defined(__x86_64__) + if (x) + return __builtin_ctzll(x); + return 64; +#else + if (x) { + int n = 1; + if ((x & 0xffffffff) == 0) { + n += 32; + x >>= 32; + } + if ((x & 0x0000ffff) == 0) { + n += 16; + x >>= 16; + } + if ((x & 0x000000ff) == 0) { + n += 8; + x >>= 8; + } + if ((x & 0x0000000f) == 0) { + n += 4; + x >>= 4; + } + if ((x & 0x00000003) == 0) { + n += 2; + x >>= 2; + } + return n - (int)(uint32_t)(x & 1); + } + return 64; +#endif +} + +// Returns the number of leading (contiguous most significant) bits. Returns 32 for an input of 0. +inline int CountLeading0Bits(uint32_t x) { +#if defined(_MSC_VER) + unsigned long i; + unsigned char nonZero = _BitScanReverse(&i, x); // Return highest index non-zero bit. + return nonZero ? (int)(31 - i) : 32; // 31 - i returns the count of the leading zeroes. +#elif (defined(__GNUC__) || defined(__clang__)) + if (x) + return __builtin_clz(x); + return 32; +#else + unsigned n = 0; // This is typically faster than the tricky solution. + if (x == 0) + return 32; + while (1) { + if (static_cast(x) < 0) + break; + n++; + x <<= 1; + } + return n; +#endif +} + +// Returns the number of leading (contiguous most significant) bits. Returns 64 for an input of 0. +inline int CountLeading0Bits(uint64_t x) { +#if defined(_MSC_VER) && defined(_M_AMD64) + unsigned long i; + unsigned char nonZero = _BitScanReverse64(&i, x); // Return highest index non-zero bit. + return nonZero ? (int)(63 - i) : 64; // 63 - i returns the count of the leading zeroes. +#elif (defined(__GNUC__) || defined(__clang__)) && defined(__x86_64__) + if (x) + return __builtin_clzll(x); + return 64; +#else + unsigned n = 0; + if (x == 0) + return 64; + while (1) { + if (static_cast(x) < 0) + break; + n++; + x <<= 1; + } + return n; +#endif +} + +//----------------------------------------------------------------------------------- +// ***** Operator extensions + +template +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 +OVR_FORCE_INLINE const T Min(const T a, const T b) { + return (a < b) ? a : b; +} + +template +OVR_FORCE_INLINE const T Max(const T a, const T b) { + return (b < a) ? a : b; +} + +template +OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal) { + return Max(minVal, Min(v, maxVal)); +} + +template +OVR_FORCE_INLINE int Chop(T f) { + return (int)f; +} + +template +OVR_FORCE_INLINE T Lerp(T a, T b, T f) { + return (b - a) * f + a; +} + +// Smooth transition between 0..1 that has 0 first derivative at 0 and 1. +template +OVR_FORCE_INLINE const T SmoothStep(const T s) { + return s * s * (s * T(-2) + T(3)); +} + +// Same as SmoothStep but with 0 first and second derivatives at 0 and 1 +template +OVR_FORCE_INLINE const T SmootherStep(const T s) { + return s * s * s * (s * (s * T(6) - T(15)) + T(10)); +} + +// 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 +OVR_FORCE_INLINE const T PMin(const T a, const T b) { + OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t)); + return (a < b) ? a : b; +} +template +OVR_FORCE_INLINE const T PMax(const T a, const T b) { + OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t)); + return (b < a) ? a : b; +} + +template +OVR_FORCE_INLINE const T Abs(const T v) { + return (v >= 0) ? v : -v; +} + +//----------------------------------------------------------------------------------- +// ***** OperatorLess +// +template +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 +void QuickSortSliced(Array& arr, size_t start, size_t end, Less less) { + enum { Threshold = 9 }; + + if (end - start < 2) + return; + + intptr_t stack[80]; + intptr_t* top = stack; + intptr_t base = (intptr_t)start; + intptr_t limit = (intptr_t)end; + + for (;;) { + intptr_t len = limit - base; + intptr_t 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 +void QuickSortSliced(Array& arr, size_t start, size_t end) { + typedef typename Array::ValueType ValueType; + QuickSortSliced(arr, start, end, OperatorLess::Compare); +} + +// Same as corresponding G_QuickSortSliced but with checking array limits to avoid +// crash in the case of wrong comparator functor. +template +bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end, Less less) { + enum { Threshold = 9 }; + + if (end - start < 2) + return true; + + intptr_t stack[80]; + intptr_t* top = stack; + intptr_t base = (intptr_t)start; + intptr_t limit = (intptr_t)end; + + for (;;) { + intptr_t len = limit - base; + intptr_t 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 +bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end) { + typedef typename Array::ValueType ValueType; + return QuickSortSlicedSafe(arr, start, end, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** QuickSort +// +// Sort an array Array, ArrayPaged, ArrayUnsafe. +// The array must have GetSize() function. +// The comparison predicate must be specified. +template +void QuickSort(Array& arr, Less less) { + QuickSortSliced(arr, 0, arr.GetSize(), less); +} + +// checks for boundaries +template +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 +void QuickSort(Array& arr) { + typedef typename Array::ValueType ValueType; + QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess::Compare); +} + +template +bool QuickSortSafe(Array& arr) { + typedef typename Array::ValueType ValueType; + return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess::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 +void InsertionSortSliced(Array& arr, size_t start, size_t end, Less less) { + size_t j = start; + size_t i = j + 1; + size_t 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 +void InsertionSortSliced(Array& arr, size_t start, size_t end) { + typedef typename Array::ValueType ValueType; + InsertionSortSliced(arr, start, end, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** InsertionSort +// +// Sort an array Array, ArrayPaged, ArrayUnsafe. +// The array must have GetSize() function. +// The comparison predicate must be specified. + +template +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 +void InsertionSort(Array& arr) { + typedef typename Array::ValueType ValueType; + InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** Median +// Returns a median value of the input array. +// Caveats: partially sorts the array, returns a reference to the array element +// TBD: This needs to be optimized and generalized +// +template +typename Array::ValueType& Median(Array& arr) { + size_t count = arr.GetSize(); + size_t mid = (count - 1) / 2; + OVR_ASSERT(count > 0); + + for (size_t j = 0; j <= mid; j++) { + size_t min = j; + for (size_t k = j + 1; k < count; k++) + if (arr[k] < arr[min]) + min = k; + Swap(arr[j], arr[min]); + } + return arr[mid]; +} + +//----------------------------------------------------------------------------------- +// ***** LowerBoundSliced +// +template +size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less) { + intptr_t first = (intptr_t)start; + intptr_t len = (intptr_t)(end - start); + intptr_t half; + intptr_t 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 (size_t)first; +} + +//----------------------------------------------------------------------------------- +// ***** LowerBoundSliced +// +template +size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) { + return LowerBoundSliced(arr, start, end, val, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** LowerBoundSized +// +template +size_t LowerBoundSized(const Array& arr, size_t size, const Value& val) { + return LowerBoundSliced(arr, 0, size, val, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** LowerBound +// +template +size_t LowerBound(const Array& arr, const Value& val, Less less) { + return LowerBoundSliced(arr, 0, arr.GetSize(), val, less); +} + +//----------------------------------------------------------------------------------- +// ***** LowerBound +// +template +size_t LowerBound(const Array& arr, const Value& val) { + return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** UpperBoundSliced +// +template +size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less) { + intptr_t first = (intptr_t)start; + intptr_t len = (intptr_t)(end - start); + intptr_t half; + intptr_t 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 (size_t)first; +} + +//----------------------------------------------------------------------------------- +// ***** UpperBoundSliced +// +template +size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) { + return UpperBoundSliced(arr, start, end, val, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** UpperBoundSized +// +template +size_t UpperBoundSized(const Array& arr, size_t size, const Value& val) { + return UpperBoundSliced(arr, 0, size, val, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** UpperBound +// +template +size_t UpperBound(const Array& arr, const Value& val, Less less) { + return UpperBoundSliced(arr, 0, arr.GetSize(), val, less); +} + +//----------------------------------------------------------------------------------- +// ***** UpperBound +// +template +size_t UpperBound(const Array& arr, const Value& val) { + return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** ReverseArray +// +template +void ReverseArray(Array& arr) { + intptr_t from = 0; + intptr_t to = arr.GetSize() - 1; + while (from < to) { + Swap(arr[from], arr[to]); + ++from; + --to; + } +} + +// ***** AppendArray +// +template +void AppendArray(CDst& dst, const CSrc& src) { + size_t 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 ArrayAdaptor { + public: + typedef T ValueType; + ArrayAdaptor() : Data(0), Size(0) {} + ArrayAdaptor(T* ptr, size_t size) : Data(ptr), Size(size) {} + size_t GetSize() const { + return Size; + } + int GetSizeI() const { + return (int)GetSize(); + } + const T& operator[](size_t i) const { + return Data[i]; + } + T& operator[](size_t i) { + return Data[i]; + } + + private: + T* Data; + size_t 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 ConstArrayAdaptor { + public: + typedef T ValueType; + ConstArrayAdaptor() : Data(0), Size(0) {} + ConstArrayAdaptor(const T* ptr, size_t size) : Data(ptr), Size(size) {} + size_t GetSize() const { + return Size; + } + int GetSizeI() const { + return (int)GetSize(); + } + const T& operator[](size_t i) const { + return Data[i]; + } + + private: + const T* Data; + size_t Size; +}; + +//----------------------------------------------------------------------------------- +extern const uint8_t UpperBitTable[256]; +extern const uint8_t LowerBitTable[256]; + +//----------------------------------------------------------------------------------- +inline uint8_t UpperBit(size_t 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 uint8_t LowerBit(size_t 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, size_t byteCount) { + return memcmp(p1, p2, byteCount); + } + static int Cmp16(const void* p1, const void* p2, size_t int16Count); + static int Cmp32(const void* p1, const void* p2, size_t int32Count); + static int Cmp64(const void* p1, const void* p2, size_t int64Count); +}; + +// ** Inline Implementation + +inline int MemUtil::Cmp16(const void* p1, const void* p2, size_t int16Count) { + int16_t* pa = (int16_t*)p1; + int16_t* pb = (int16_t*)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, size_t int32Count) { + int32_t* pa = (int32_t*)p1; + int32_t* pb = (int32_t*)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, size_t int64Count) { + int64_t* pa = (int64_t*)p1; + int64_t* pb = (int64_t*)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) { + uint8_t* pb = (uint8_t*)pv; + uint8_t temp; + for (int i = 0; i < (size / 2); i++) { + temp = pb[size - 1 - i]; + pb[size - 1 - i] = pb[i]; + pb[i] = temp; + } +} + +// Swap the byte order of primitive types +inline uint8_t SwapOrder(uint8_t v) { + return v; +} +inline int8_t SwapOrder(int8_t v) { + return v; +} +inline uint16_t SwapOrder(uint16_t v) { + return uint16_t(v >> 8) | uint16_t(v << 8); +} +inline int16_t SwapOrder(int16_t v) { + return int16_t((uint16_t(v) >> 8) | (v << 8)); +} +inline uint32_t SwapOrder(uint32_t v) { + return (v >> 24) | ((v & 0x00FF0000) >> 8) | ((v & 0x0000FF00) << 8) | (v << 24); +} +inline int32_t SwapOrder(int32_t p) { + return (int32_t)SwapOrder(uint32_t(p)); +} +inline uint64_t SwapOrder(uint64_t v) { + return (v >> 56) | ((v & uint64_t(0x00FF000000000000ULL)) >> 40) | + ((v & uint64_t(0x0000FF0000000000ULL)) >> 24) | ((v & uint64_t(0x000000FF00000000ULL)) >> 8) | + ((v & uint64_t(0x00000000FF000000ULL)) << 8) | ((v & uint64_t(0x0000000000FF0000ULL)) << 24) | + ((v & uint64_t(0x000000000000FF00ULL)) << 40) | (v << 56); +} +inline int64_t SwapOrder(int64_t v) { + return (int64_t)SwapOrder(uint64_t(v)); +} +inline float SwapOrder(float p) { + union { + float p; + uint32_t v; + } u; + u.p = p; + u.v = SwapOrder(u.v); + return u.p; +} + +inline double SwapOrder(double p) { + union { + double p; + uint64_t 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 uint8_t LEToSystem(uint8_t v) { + return v; +} +inline int8_t LEToSystem(int8_t v) { + return v; +} +inline uint16_t LEToSystem(uint16_t v) { + return v; +} +inline int16_t LEToSystem(int16_t v) { + return v; +} +inline uint32_t LEToSystem(uint32_t v) { + return v; +} +inline int32_t LEToSystem(int32_t v) { + return v; +} +inline uint64_t LEToSystem(uint64_t v) { + return v; +} +inline int64_t LEToSystem(int64_t v) { + return v; +} +inline float LEToSystem(float v) { + return v; +} +inline double LEToSystem(double v) { + return v; +} + +// Big Endian to System (LE) +inline uint8_t BEToSystem(uint8_t v) { + return SwapOrder(v); +} +inline int8_t BEToSystem(int8_t v) { + return SwapOrder(v); +} +inline uint16_t BEToSystem(uint16_t v) { + return SwapOrder(v); +} +inline int16_t BEToSystem(int16_t v) { + return SwapOrder(v); +} +inline uint32_t BEToSystem(uint32_t v) { + return SwapOrder(v); +} +inline int32_t BEToSystem(int32_t v) { + return SwapOrder(v); +} +inline uint64_t BEToSystem(uint64_t v) { + return SwapOrder(v); +} +inline int64_t BEToSystem(int64_t 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 uint8_t SystemToLE(uint8_t v) { + return v; +} +inline int8_t SystemToLE(int8_t v) { + return v; +} +inline uint16_t SystemToLE(uint16_t v) { + return v; +} +inline int16_t SystemToLE(int16_t v) { + return v; +} +inline uint32_t SystemToLE(uint32_t v) { + return v; +} +inline int32_t SystemToLE(int32_t v) { + return v; +} +inline uint64_t SystemToLE(uint64_t v) { + return v; +} +inline int64_t SystemToLE(int64_t v) { + return v; +} +inline float SystemToLE(float v) { + return v; +} +inline double SystemToLE(double v) { + return v; +} + +// System (LE) to Big Endian +inline uint8_t SystemToBE(uint8_t v) { + return SwapOrder(v); +} +inline int8_t SystemToBE(int8_t v) { + return SwapOrder(v); +} +inline uint16_t SystemToBE(uint16_t v) { + return SwapOrder(v); +} +inline int16_t SystemToBE(int16_t v) { + return SwapOrder(v); +} +inline uint32_t SystemToBE(uint32_t v) { + return SwapOrder(v); +} +inline int32_t SystemToBE(int32_t v) { + return SwapOrder(v); +} +inline uint64_t SystemToBE(uint64_t v) { + return SwapOrder(v); +} +inline int64_t SystemToBE(int64_t 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 uint8_t LEToSystem(uint8_t v) { + return SwapOrder(v); +} +inline int8_t LEToSystem(int8_t v) { + return SwapOrder(v); +} +inline uint16_t LEToSystem(uint16_t v) { + return SwapOrder(v); +} +inline int16_t LEToSystem(int16_t v) { + return SwapOrder(v); +} +inline uint32_t LEToSystem(uint32_t v) { + return SwapOrder(v); +} +inline int32_t LEToSystem(int32_t v) { + return SwapOrder(v); +} +inline uint64_t LEToSystem(uint64_t v) { + return SwapOrder(v); +} +inline int64_t LEToSystem(int64_t 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 uint8_t BEToSystem(uint8_t v) { + return v; +} +inline int8_t BEToSystem(int8_t v) { + return v; +} +inline uint16_t BEToSystem(uint16_t v) { + return v; +} +inline int16_t BEToSystem(int16_t v) { + return v; +} +inline uint32_t BEToSystem(uint32_t v) { + return v; +} +inline int32_t BEToSystem(int32_t v) { + return v; +} +inline uint64_t BEToSystem(uint64_t v) { + return v; +} +inline int64_t BEToSystem(int64_t v) { + return v; +} +inline float BEToSystem(float v) { + return v; +} +inline double BEToSystem(double v) { + return v; +} + +// System (BE) to Little Endian +inline uint8_t SystemToLE(uint8_t v) { + return SwapOrder(v); +} +inline int8_t SystemToLE(int8_t v) { + return SwapOrder(v); +} +inline uint16_t SystemToLE(uint16_t v) { + return SwapOrder(v); +} +inline int16_t SystemToLE(int16_t v) { + return SwapOrder(v); +} +inline uint32_t SystemToLE(uint32_t v) { + return SwapOrder(v); +} +inline int32_t SystemToLE(int32_t v) { + return SwapOrder(v); +} +inline uint64_t SystemToLE(uint64_t v) { + return SwapOrder(v); +} +inline int64_t SystemToLE(int64_t 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 uint8_t SystemToBE(uint8_t v) { + return v; +} +inline int8_t SystemToBE(int8_t v) { + return v; +} +inline uint16_t SystemToBE(uint16_t v) { + return v; +} +inline int16_t SystemToBE(int16_t v) { + return v; +} +inline uint32_t SystemToBE(uint32_t v) { + return v; +} +inline int32_t SystemToBE(int32_t v) { + return v; +} +inline uint64_t SystemToBE(uint64_t v) { + return v; +} +inline int64_t SystemToBE(int64_t 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 + +// Used primarily for hardware interfacing such as sensor reports, firmware, etc. +// Reported data is all little-endian. +inline uint16_t DecodeUInt16(const uint8_t* buffer) { + return ByteUtil::LEToSystem(*(const uint16_t*)buffer); +} + +inline int16_t DecodeSInt16(const uint8_t* buffer) { + return ByteUtil::LEToSystem(*(const int16_t*)buffer); +} + +inline uint32_t DecodeUInt32(const uint8_t* buffer) { + return ByteUtil::LEToSystem(*(const uint32_t*)buffer); +} + +inline int32_t DecodeSInt32(const uint8_t* buffer) { + return ByteUtil::LEToSystem(*(const int32_t*)buffer); +} + +inline float DecodeFloat(const uint8_t* buffer) { + union { + uint32_t U; + float F; + }; + + U = DecodeUInt32(buffer); + return F; +} + +inline void EncodeUInt16(uint8_t* buffer, uint16_t val) { + *(uint16_t*)buffer = ByteUtil::SystemToLE(val); +} + +inline void EncodeSInt16(uint8_t* buffer, int16_t val) { + *(int16_t*)buffer = ByteUtil::SystemToLE(val); +} + +inline void EncodeUInt32(uint8_t* buffer, uint32_t val) { + *(uint32_t*)buffer = ByteUtil::SystemToLE(val); +} + +inline void EncodeSInt32(uint8_t* buffer, int32_t val) { + *(int32_t*)buffer = ByteUtil::SystemToLE(val); +} + +inline void EncodeFloat(uint8_t* buffer, float val) { + union { + uint32_t U; + float F; + }; + + F = val; + EncodeUInt32(buffer, U); +} + +// Converts an 8-bit binary-coded decimal +inline int8_t DecodeBCD(uint8_t byte) { + uint8_t digit1 = (byte >> 4) & 0x0f; + uint8_t digit2 = byte & 0x0f; + int decimal = digit1 * 10 + digit2; // maximum value = 99 + return (int8_t)decimal; +} + +// Updates the previousCount uint_64t with the new value from the bitCount wrap-around counter +// newCount32 +// Returns the delta as uint32_t +// 0 < bitCount <= 32 +template +uint32_t inline UpdateWraparoundCounter(uint64_t* previousCount, uint32_t newCount32) { + OVR_ASSERT(bitCount <= 32); + + const uint64_t mask = ((uint64_t)1u << bitCount) - 1; + OVR_ASSERT((newCount32 & ~mask) == 0); + + // Do int64_t subtraction to avoid invoking what is technically undefined behavior + int64_t delta = ((int64_t)newCount32 - (int64_t)(*previousCount & mask)); + if (delta < 0) + delta += ((uint64_t)1u << bitCount); + + *previousCount += delta; + // We know that delta >=0 and < (1u << bitCount), and thus fits in a uint32_t + return (uint32_t)delta; +} + +// Returns true if T is a signed built in type and (x + y) would overflow or underflow the storage +// maximum or minimum of type T. +template +inline bool SignedAdditionWouldOverflow(T x, T y) { + const T temp = (T)(x + y); + return ((~(x ^ y)) & (x ^ temp)) < 0; +} + +// Returns true if T is a signed type and (x - y) would overflow or underflow the storage maximum or +// minimum of type T. +template +inline bool SignedSubtractionWouldOverflow(T x, T y) { + y = -y; + const T temp = (T)(x + y); + return ((temp ^ x) & (temp ^ y)) < 0; +} + +// Returns true if T is an unsigned type and (x + y) would overflow the storage maximum of type T. +template +inline bool UnsignedAdditionWouldOverflow(T x, T y) { + return (T)(x + y) < x; +} + +// Returns true if T is an unsigned type and (x - y) would underflow the storage minimum of type T. +template +inline bool UnsignedSubtractionWouldOverflow(T x, T y) { + return y > x; +} + +// Returns true if T is an unsigned type and (x * y) would overflow the storage maximum of type T. +template +inline bool UnsignedMultiplyWouldOverflow(T x, T y) { + if (y) + return (((T)(x * y) / y) != x); + return false; +} + +// Returns true if (x * y) would overflow or underflow the storage maximum or minimum of type +// int32_t. +inline bool SignedMultiplyWouldOverflow(int32_t x, int32_t y) { + if ((y < 0) && (x == (int32_t)INT32_C(0x80000000))) + return true; + if (y) + return (((x * y) / y) != x); + return false; +} + +// Returns true if (x * y) would overflow or underflow the storage maximum or minimum of type +// int64_t. +inline bool SignedMultiplyWouldOverflow(int64_t x, int64_t y) { + if ((y < 0) && (x == (int64_t)INT64_C(0x8000000000000000))) + return true; + if (y) + return (((x * y) / y) != x); + return false; +} + +// Returns true if (x / y) would overflow the maximum of type T. +template +inline bool UnsignedDivisionWouldOverflow(T /*x*/, T y) { + return y == 0; +} + +// Returns true if (x / y) would overflow or underflow the maximum or mimumum of type T. +template +inline bool SignedDivisionWouldOverflow(T x, T y) { + return (y == 0) || ((x == (T)((T)1 << ((sizeof(T) * 8) - 1))) && (y == -1)); +} +} // namespace Alg +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Allocator.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Allocator.cpp new file mode 100644 index 0000000..d8c1c5b --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Allocator.cpp @@ -0,0 +1,3717 @@ +/************************************************************************************ + +Filename : OVR_Allocator.cpp +Content : Installable memory allocator implementation +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Allocator.h" +#include +#include +#include +#include +#include +#include +#include "OVR_Alg.h" +#include "OVR_DebugHelp.h" +#include "OVR_Std.h" +#include "Util/Util_SystemInfo.h" + +#if defined(_MSC_VER) +#include +OVR_DISABLE_MSVC_WARNING(4996) // 'sscanf': This function or variable may be unsafe. +OVR_DISABLE_MSVC_WARNING(4351) // elements of array will be default initialized +#endif + +#if !defined(WIN32) +#include +#include +#include +#include +#if defined(__APPLE__) +#include +#else +#include +#endif +#endif + +#if !defined(OVR_DEBUG_TRACE) +#if defined(_WIN32) +#define OVR_DEBUG_TRACE(str) ::OutputDebugStringA(str); +#else +#define OVR_DEBUG_TRACE(str) ::fputs(str, stderr); +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_DEBUG_CRT_PRESENT +// +// Defined as 0 or 1. 0 means release CRT is present (release build). +// Indicates if the debug version or the CRT will be linked into the application. +// If it's present then malloc hooking will need to include the debug malloc functions +// that are present in the debug CRT. If it's not present then we need to not include +// them, as they won't be present. +// You can't modify this value' it's a property of the build environment. +// +#if !defined(OVR_DEBUG_CRT_PRESENT) +#if defined(_DEBUG) +#define OVR_DEBUG_CRT_PRESENT 1 +#else +#define OVR_DEBUG_CRT_PRESENT 0 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_STATIC_CRT_PRESENT +// +// Defined as 0 or 1. 0 means DLL CRT, static means static CRT. +// Indicates if the CRT being compiled against is the static CRT or the DLL CRT. +// You can't modify this value' it's a property of the build environment. +// +#if !defined(OVR_STATIC_CRT_PRESENT) +#if defined(_DLL) // VC++ defines _DLL if you are building against the DLL CRT. +#define OVR_STATIC_CRT_PRESENT 0 +#else +#define OVR_STATIC_CRT_PRESENT 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_ALLOCATOR_DEBUG_PAGE_HEAP_ENABLED +// +// Defined as 0 or 1. +// If enabled then we use our debug page heap instead of a regular heap by default. +// However, even if this is disabled it can still be enabled at runtime by manually +// setting the appropriate environment variable/registry key. +// The debug page heap is available only with 64 bit platforms, as the page use is +// too high for some 32 bit platforms. +// +#ifndef OVR_ALLOCATOR_DEBUG_PAGE_HEAP_ENABLED +#if defined(OVR_BUILD_DEBUG) +// Disabled because currently the Oculus OAF module usage of this feature makes the app slow. +#define OVR_ALLOCATOR_DEBUG_PAGE_HEAP_ENABLED 0 +#else +#define OVR_ALLOCATOR_DEBUG_PAGE_HEAP_ENABLED 0 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_ALLOCATOR_TRACKING_ENABLED +// +// Defined as 0 or 1. +// If enabled then memory is tracked by default and reports on it can be done at runtime. +// However, even if this is disabled it can still be enabled at runtime by manually +// setting the appropriate environment variable/registry key: +// HKEY_LOCAL_MACHINE\SOFTWARE\Oculus\HeapTrackingEnabled +// +#ifndef OVR_ALLOCATOR_TRACKING_ENABLED +#if defined(OVR_BUILD_DEBUG) +// Disabled because currently Microsoft iterator debugging makes the app slow. +#define OVR_ALLOCATOR_TRACKING_ENABLED 0 +#else +#define OVR_ALLOCATOR_TRACKING_ENABLED 0 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_REDIRECT_CRT_MALLOC +// +// Defined as 0 or 1. +// If enabled and if a default allocator is used, then the malloc family of functions +// is redirected to the default allocator. This allows memory tracking of malloc in +// addition to operator new. +// +#ifndef OVR_REDIRECT_CRT_MALLOC +#if defined(_MSC_VER) && defined(_DEBUG) && (_MSC_VER >= 1900) && \ + OVR_STATIC_CRT_PRESENT // Not supported for DLL CRT until we can figure out how to work around +// some difficulties. +#define OVR_REDIRECT_CRT_MALLOC 0 // Disabled until we are confident in it. +#else +#define OVR_REDIRECT_CRT_MALLOC 0 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** CRT internal symbols we use. +// +#if defined(_MSC_VER) +#if OVR_STATIC_CRT_PRESENT +#if (_MSC_VER < 1900) +extern "C" HANDLE _crtheap; +#else +extern "C" void __cdecl __acrt_lock(int lock); +extern "C" void __cdecl __acrt_unlock(int lock); +extern "C" HANDLE __acrt_heap; +#endif +#else +// The CRT locks are not accessible from outside the MSVCRT DLL. +// Maybe it's privately exported through an export table via ordinal number, though. +#if (_MSC_VER >= 1900) +extern "C" void __cdecl __acrt_lock(int /*lock*/) { + OVR_FAIL(); +} // We don't currently have a way to access this, but we don't support this pattern of usage +// anyway. +extern "C" void __cdecl __acrt_unlock(int /*lock*/) { + OVR_FAIL(); +} +extern "C" HANDLE __cdecl __acrt_get_msvcrt_heap_handle() { + OVR_FAIL(); + return NULL; +} +#endif +#endif + +inline HANDLE GetCRTHeapHandle() { +#if OVR_STATIC_CRT_PRESENT +#if (_MSC_VER < 1900) // If VS2013 or earlier... + return _crtheap; +#else + return __acrt_heap; +#endif +#else +#if (_MSC_VER < 1900) // If VS2013 or earlier... +#error "Need to find the function that does this" +#else + return __acrt_get_msvcrt_heap_handle(); +#endif +#endif +} + +#if OVR_DEBUG_CRT_PRESENT +// We need to replicate a couple items from the debug CRT heap. This may change with +// future VC++ versions, though that's unlikely and wouldn't likely change by much. +struct CrtMemBlockHeader { + CrtMemBlockHeader* block_header_next; + CrtMemBlockHeader* block_header_prev; + const char* file_name; + int line_number; +#if defined(_WIN64) || (_MSC_VER >= 1900) + int block_use; + size_t data_size; +#else + size_t data_size; + int block_use; +#endif + long request_number; + unsigned char gap[4]; + // unsigned char data[data_size]; // User pointer. + // unsigned char another_gap[4]; +}; + +static const CrtMemBlockHeader* header_from_block(const void* block) { + return (static_cast(block) - 1); +} + +// Clone of _malloc_dbg +#if (_MSC_VER >= 1900) +static const uint8_t no_mans_land_fill = 0xFD; +static const uint8_t clean_land_fill = 0xCD; +static const size_t no_mans_land_size = 4; +static const long request_number_for_ignore_blocks = 0; +static const int line_number_for_ignore_blocks = static_cast(0xFEDCBABC); + +static void* block_from_header(void* header) { + return (static_cast(header) + 1); +} + +extern "C" void* crt_malloc_dbg(size_t size, int /*blockUse*/, const char* /*file*/, int /*line*/) { + struct AutoLock { + AutoLock() { + __acrt_lock(0); + } + ~AutoLock() { + __acrt_unlock(0); + } + } autoLock; + void* block = nullptr; + + if (size > (size_t)((_HEAP_MAXREQ - no_mans_land_size) - sizeof(CrtMemBlockHeader))) { + errno = ENOMEM; + return nullptr; + } + + size_t const block_size = sizeof(CrtMemBlockHeader) + size + no_mans_land_size; + CrtMemBlockHeader* header = + static_cast(HeapAlloc(GetCRTHeapHandle(), 0, block_size)); + + if (!header) { + errno = ENOMEM; + return nullptr; + } + + // Set this block to be ignored by the debug heap. This makes it somewhat invisible. + header->block_header_next = nullptr; + header->block_header_prev = nullptr; + header->file_name = nullptr; + header->line_number = line_number_for_ignore_blocks; + header->data_size = size; + header->block_use = _IGNORE_BLOCK; + header->request_number = request_number_for_ignore_blocks; + + memset(header->gap, no_mans_land_fill, no_mans_land_size); + memset((char*)block_from_header(header) + size, no_mans_land_fill, no_mans_land_size); + memset(block_from_header(header), clean_land_fill, size); + + block = block_from_header(header); + + return block; +} +#else +#if OVR_STATIC_CRT_PRESENT +extern "C" void* __cdecl _nh_malloc_dbg( + size_t size, + int /*flag*/, + int nBlockUse, + const char* file, + int line); + +extern "C" void* crt_malloc_dbg(size_t size, int blockUse, const char* file, int line) { + return _nh_malloc_dbg(size, 0, blockUse, file, line); +} +#endif +#endif +#elif OVR_STATIC_CRT_PRESENT +extern "C" void* __cdecl _aligned_malloc_base(size_t size, size_t align); +extern "C" void __cdecl _free_base(void* p); +// extern "C" void* __cdecl _realloc_base(void* p, size_t newsize); +#if defined(WINDOWS_SDK_VERSION) && WINDOWS_SDK_VERSION >= 17763 +// These functions aren't available in the 10.0.17763.0 Windows SDK. +extern "C" void __cdecl _aligned_free_base(void* /*p*/) { + OVR_FAIL(); +} +extern "C" void* __cdecl _aligned_realloc_base(void* /*p*/, size_t /*newSize*/, size_t /*align*/) { + OVR_FAIL(); + return nullptr; +} +#else +extern "C" void __cdecl _aligned_free_base(void* p); +extern "C" void* __cdecl _aligned_realloc_base(void* p, size_t newSize, size_t align); +#endif +#else +extern "C" _ACRTIMP void __cdecl _free_base(void* p); +extern "C" void __cdecl _aligned_free_base(void* /*p*/) { + OVR_FAIL(); +} +extern "C" void* __cdecl _aligned_realloc_base(void* /*p*/, size_t /*newSize*/, size_t /*align*/) { + OVR_FAIL(); + return nullptr; +} +#endif +#endif // defined(_MSC_VER) + +//----------------------------------------------------------------------------------- +// ***** OVR_ALLOCATOR_UNSPECIFIED_TAG +// +#define OVR_ALLOCATOR_UNSPECIFIED_TAG "none" + +//----------------------------------------------------------------------------------- +// ***** OVR_USE_JEMALLOC +// +// Defined as 0 or 1. +// If enabled then jemalloc is used as a heap instead of other heaps. +// +#ifndef OVR_USE_JEMALLOC +// Currently unilaterally disabled because our jemalloc has stability problems on Windows. +#define OVR_USE_JEMALLOC 0 +#endif +#if OVR_USE_JEMALLOC +#include "src/jemalloc/jemalloc.h" +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_HUNT_UNTRACKED_ALLOCS +// +// Defined as 0 or 1. +// This will cause an assertion to trip whenever an allocation occurs outside of our +// custom allocator. This helps track down allocations that are not being done +// correctly via OVR_ALLOC(). +// +#ifndef OVR_HUNT_UNTRACKED_ALLOCS +#define OVR_HUNT_UNTRACKED_ALLOCS 0 +#endif + +#if OVR_HUNT_UNTRACKED_ALLOCS + +static const char* WhiteList[] = {"OVR_Allocator.cpp", + "OVR_Log.cpp", + "crtw32", // Ignore CRT internal allocations + nullptr}; + +static int +HuntUntrackedAllocHook(int, void*, size_t, int, long, const unsigned char* szFileName, int) { + if (!szFileName) { + return TRUE; + } + + for (int i = 0; WhiteList[i] != nullptr; ++i) { + if (strstr((const char*)szFileName, WhiteList[i]) != 0) { + return TRUE; + } + } + + // At this point we have an allocation that's occurring ourside our custom allocator. + // It means that the application is going around our OVR_ALLOC interface. + OVR_ASSERT(false); + return FALSE; +} + +#endif // OVR_HUNT_UNTRACKED_ALLOCS + +//----------------------------------------------------------------------------------- +// ***** OVR_BENCHMARK_ALLOCATOR +// +// Defined as 0 or 1. +// If we are benchmarking the allocator, define this. +// Do not enable this in shipping code! +// +#ifndef OVR_BENCHMARK_ALLOCATOR +#define OVR_BENCHMARK_ALLOCATOR 0 +#endif + +#if OVR_BENCHMARK_ALLOCATOR +#error \ + "This code should not be compiled! It really hurts performance. Only enable this during testing." + +// This gets the double constant that can convert ::QueryPerformanceCounter +// LARGE_INTEGER::QuadPart into a number of seconds. +// This is the same as in the Timer code except we cannot use Timer code +// because the allocator gets called during static initializers before +// the Timer code is initialized. +static double GetPerfFrequencyInverse() { + // Static value containing frequency inverse of performance counter + static double PerfFrequencyInverse = 0.; + + // If not initialized, + if (PerfFrequencyInverse == 0.) { + // Initialize the inverse (same as in Timer code) + LARGE_INTEGER freq; + ::QueryPerformanceFrequency(&freq); + PerfFrequencyInverse = 1.0 / (double)freq.QuadPart; + } + + return PerfFrequencyInverse; +} + +// Record a delta timestamp for an allocator operation +static void ReportDT(LARGE_INTEGER& t0, LARGE_INTEGER& t1) { + // Stats lock to avoid multiple threads corrupting the shared stats + // This lock is the reason we cannot enable this code. + static Lock theLock; + + // Running stats + static double timeSum = 0.; // Sum of dts + static double timeMax = 0.; // Max dt in set + static int timeCount = 0; // Number of dts recorded + + // Calculate delta time between start and end of operation + // based on the provided QPC timestamps + double dt = (t1.QuadPart - t0.QuadPart) * GetPerfFrequencyInverse(); + + // Init the average and max to print to zero. + // If they stay zero we will not print them. + double ravg = 0., rmax = 0.; + { + // Hold the stats lock + Lock::Locker locker(&theLock); + + // Accumulate stats + timeSum += dt; + if (dt > timeMax) + timeMax = dt; + + // Every X recordings, + if (++timeCount >= 1000) { + // Set average/max to print + ravg = timeSum / timeCount; + rmax = timeMax; + + timeSum = 0; + timeMax = 0; + timeCount = 0; + } + } + + // If printing, + if (rmax != 0.) { + LogText( + "------- Allocator Stats: AvgOp = %lf usec, MaxOp = %lf usec\n", + ravg * 1000000., + rmax * 1000000.); + } +} + +#define OVR_ALLOC_BENCHMARK_START() \ + LARGE_INTEGER t0; \ + ::QueryPerformanceCounter(&t0); +#define OVR_ALLOC_BENCHMARK_END() \ + LARGE_INTEGER t1; \ + ::QueryPerformanceCounter(&t1); \ + ReportDT(t0, t1); +#else +#define OVR_ALLOC_BENCHMARK_START() +#define OVR_ALLOC_BENCHMARK_END() +#endif // OVR_BENCHMARK_ALLOCATOR + +namespace OVR { + +bad_alloc::bad_alloc(const char* description) OVR_NOEXCEPT { + if (description) + OVR_strlcpy(Description, description, sizeof(Description)); + else + Description[0] = '\0'; + + OVR_strlcat(Description, " at ", sizeof(Description)); + + // read the current backtrace + // We cannot attempt to symbolize this here as that would attempt to + // allocate memory. That would be unwise within a bad_alloc exception. + void* backtrace_data[20]; + char addressDescription[256] = + {}; // Write into this temporary instead of member Description in case an exception is thrown. + +#if defined(_WIN32) + int count = CaptureStackBackTrace( + 2, sizeof(backtrace_data) / sizeof(backtrace_data[0]), backtrace_data, nullptr); +#else + int count = backtrace(backtrace_data, sizeof(backtrace_data) / sizeof(backtrace_data[0])); +#endif + + for (int i = 0; i < count; ++i) { + char address[(sizeof(void*) * 2) + 1 + 1]; // hex address string plus possible space plus null + // terminator. + snprintf(address, sizeof(address), "%p%s", backtrace_data[i], (i + 1 < count) ? " " : ""); + OVR_strlcat(addressDescription, address, sizeof(addressDescription)); + } + + OVR_strlcat(Description, addressDescription, sizeof(Description)); +} + +//----------------------------------------------------------------------------------- +// ***** SysMemAlloc / SysMemFree +// +void* SysMemAlloc(size_t n) { +#if defined(_WIN32) + void* p = HeapAlloc(GetProcessHeap(), 0, n); + return p; +#else + // To do: Need to replace this with a true system memory source. + return malloc(n); +#endif +} + +void SysMemFree(void* p, size_t /*n*/) { +#if defined(_WIN32) + if (p) + HeapFree(GetProcessHeap(), 0, p); +#else + // To do: Need to replace this with a true system memory source. + free(p); +#endif +} + +// To consider: Move Symbols to the Allocator class member data. The problem with that +// is that it exposes the debug interface from header file, which can be done but we +// would rather not if possible. +static OVR::SymbolLookup Symbols; + +//----------------------------------------------------------------------------------- +// ***** InterceptCRTMalloc +// +// Intercept malloc and posssibly redirect it to an alternative. +// +// Primary use cases: +// - We want to hook (listen in on calls to) the existing malloc but not replace it. +// - We want to replace the existing malloc. +// +// Requirements: +// - We need to be able to hook malloc after it has already been used. This necessary +// because main startup function called directly by the OS does mallocs before the +// application code can possibly override it (without prohibitively invasive alternatives). +// - We need to be able to stop what we are doing at any point and restore the system +// to how it was before we startd intercepting it. +// +// VC++ doesn't support overriding malloc and so we have to do it manually, the hard way. +// There are many functions (at least 28) that need overriding in order to fully and properly +// handle this. +// +class InterceptCRTMalloc { + public: + typedef void* (*ovr_malloc_type)(size_t size); + typedef void* (*ovr_calloc_type)(size_t count, size_t size); + typedef void* (*ovr_realloc_type)(void* p, size_t newSize); + typedef void* (*ovr_recalloc_type)(void* p, size_t count, size_t size); + typedef void* (*ovr_expand_type)(void* p, size_t newSize); + typedef size_t (*ovr_msize_type)(void* p); + typedef void (*ovr_free_type)(void* p); + typedef void* (*ovr_aligned_malloc_type)(size_t size, size_t align); + typedef void* (*ovr_aligned_offset_malloc_type)(size_t size, size_t align, size_t offset); + typedef void* (*ovr_aligned_realloc_type)(void* p, size_t size, size_t align); + typedef void* ( + *ovr_aligned_offset_realloc_type)(void* p, size_t size, size_t align, size_t offset); + typedef void* (*ovr_aligned_recalloc_type)(void* p, size_t count, size_t size, size_t align); + typedef void* (*ovr_aligned_offset_recalloc_type)( + void* p, + size_t count, + size_t size, + size_t align, + size_t offset); + typedef size_t (*ovr_aligned_msize_type)(void* p, size_t align, size_t offset); + typedef void (*ovr_aligned_free_type)(void* p); + typedef void* (*ovr_malloc_dbg_type)(size_t size, int blockUse, const char* file, int line); + typedef void* ( + *ovr_calloc_dbg_type)(size_t count, size_t size, int blockUse, const char* file, int line); + typedef void* ( + *ovr_realloc_dbg_type)(void* p, size_t newSize, int blockUse, const char* file, int line); + typedef void* (*ovr_recalloc_dbg_type)( + void* p, + size_t count, + size_t size, + int blockUse, + const char* file, + int line); + typedef void* ( + *ovr_expand_dbg_type)(void* p, size_t newSize, int blockType, const char* file, int line); + typedef size_t (*ovr_msize_dbg_type)(void* p, int blockUse); + typedef void (*ovr_free_dbg_type)(void* p, int blockUse); + typedef void* ( + *ovr_aligned_malloc_dbg_type)(size_t size, size_t align, const char* file, int line); + typedef void* (*ovr_aligned_offset_malloc_dbg_type)( + size_t size, + size_t align, + size_t offset, + const char* file, + int line); + typedef void* (*ovr_aligned_realloc_dbg_type)( + void* p, + size_t size, + size_t align, + const char* file, + int line); + typedef void* (*ovr_aligned_offset_realloc_dbg_type)( + void* p, + size_t size, + size_t align, + size_t offset, + const char* file, + int line); + typedef void* (*ovr_aligned_recalloc_dbg_type)( + void* p, + size_t count, + size_t size, + size_t align, + const char* file, + int line); + typedef void* (*ovr_aligned_offset_recalloc_dbg_type)( + void* p, + size_t count, + size_t size, + size_t align, + size_t offset, + const char* file, + int line); + typedef size_t (*ovr_aligned_msize_dbg_type)(void* p, size_t align, size_t offset); + typedef void (*ovr_aligned_free_dbg_type)(void* p); + + // Grouping of all the malloc functions into a struct. + struct MallocFunctionPointers { + ovr_malloc_type malloc_ptr; + ovr_calloc_type calloc_ptr; + ovr_realloc_type realloc_ptr; + ovr_recalloc_type recalloc_ptr; + ovr_expand_type expand_ptr; + ovr_msize_type msize_ptr; + ovr_free_type free_ptr; + ovr_aligned_malloc_type aligned_malloc_ptr; + ovr_aligned_offset_malloc_type aligned_offset_malloc_ptr; + ovr_aligned_realloc_type aligned_realloc_ptr; + ovr_aligned_offset_realloc_type aligned_offset_realloc_ptr; + ovr_aligned_recalloc_type aligned_recalloc_ptr; + ovr_aligned_offset_recalloc_type aligned_offset_recalloc_ptr; + ovr_aligned_msize_type aligned_msize_ptr; + ovr_aligned_free_type aligned_free_ptr; + ovr_malloc_dbg_type malloc_dbg_ptr; + ovr_calloc_dbg_type calloc_dbg_ptr; + ovr_realloc_dbg_type realloc_dbg_ptr; + ovr_recalloc_dbg_type recalloc_dbg_ptr; + ovr_expand_dbg_type expand_dbg_ptr; + ovr_msize_dbg_type msize_dbg_ptr; + ovr_free_dbg_type free_dbg_ptr; + ovr_aligned_malloc_dbg_type aligned_malloc_dbg_ptr; + ovr_aligned_offset_malloc_dbg_type aligned_offset_malloc_dbg_ptr; + ovr_aligned_realloc_dbg_type aligned_realloc_dbg_ptr; + ovr_aligned_offset_realloc_dbg_type aligned_offset_realloc_dbg_ptr; + ovr_aligned_recalloc_dbg_type aligned_recalloc_dbg_ptr; + ovr_aligned_offset_recalloc_dbg_type aligned_offset_recalloc_dbg_ptr; + ovr_aligned_msize_dbg_type aligned_msize_dbg_ptr; + ovr_aligned_free_dbg_type aligned_free_dbg_ptr; + }; + +#if defined(_WIN32) +#include +#endif + + protected: + struct SavedMallocFunctions { + OVR::SavedFunction malloc_saved; + OVR::SavedFunction calloc_saved; + OVR::SavedFunction realloc_saved; + OVR::SavedFunction recalloc_saved; + OVR::SavedFunction expand_saved; + OVR::SavedFunction msize_saved; + OVR::SavedFunction free_saved; + OVR::SavedFunction aligned_malloc_saved; + OVR::SavedFunction aligned_offset_malloc_saved; + OVR::SavedFunction aligned_realloc_saved; + OVR::SavedFunction aligned_offset_realloc_saved; + OVR::SavedFunction aligned_recalloc_saved; + OVR::SavedFunction aligned_offset_recalloc_saved; + OVR::SavedFunction aligned_msize_saved; + OVR::SavedFunction aligned_free_saved; + OVR::SavedFunction malloc_dbg_saved; + OVR::SavedFunction calloc_dbg_saved; + OVR::SavedFunction realloc_dbg_saved; + OVR::SavedFunction recalloc_dbg_saved; + OVR::SavedFunction expand_dbg_saved; + OVR::SavedFunction msize_dbg_saved; + OVR::SavedFunction free_dbg_saved; + OVR::SavedFunction aligned_malloc_dbg_saved; + OVR::SavedFunction aligned_offset_malloc_dbg_saved; + OVR::SavedFunction aligned_realloc_dbg_saved; + OVR::SavedFunction aligned_offset_realloc_dbg_saved; + OVR::SavedFunction aligned_recalloc_dbg_saved; + OVR::SavedFunction aligned_offset_recalloc_dbg_saved; + OVR::SavedFunction aligned_msize_dbg_saved; + OVR::SavedFunction aligned_free_dbg_saved; + }; + + public: + InterceptCRTMalloc(); + ~InterceptCRTMalloc(); + + // Replaces the existing CRT malloc functions with the ones referred to by mallocFunctionPointers. + bool ReplaceCRTMalloc(InterceptCRTMalloc::MallocFunctionPointers& mallocFunctionPointers); + + bool RestoreCRTMalloc(); + + const SavedMallocFunctions& SavedFunctions() const { + return SavedMallocFunctions; + } + + protected: + bool MallocReplaced; // True if ReplaceMalloc was successfully called. + bool CRTMallocPreserved; // If true then PreservedMallocFunctionPointers is valid. It turns out + // this is possible only if malloc is implemented as a jump to a real + // malloc implementation. + MallocFunctionPointers + PreservedMallocFunctionPointers; // Points to callable vesions of the CRT malloc functions. + bool MallocFunctionsSaved; // If true then SavedMallocFunctions contains saved functions. This + // will typically be always true if MallocReplaced is true. Possibly we + // can omit this variable. + SavedMallocFunctions SavedMallocFunctions; // +}; + +InterceptCRTMalloc::InterceptCRTMalloc() + : MallocReplaced(false), + CRTMallocPreserved(false), + PreservedMallocFunctionPointers(), + MallocFunctionsSaved(false), + SavedMallocFunctions() {} + +InterceptCRTMalloc::~InterceptCRTMalloc() { + // Default behavior is to not RestoreCRTMalloc(). +} + +#ifdef __clang__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmicrosoft-cast" +#endif +bool InterceptCRTMalloc::ReplaceCRTMalloc( + InterceptCRTMalloc::MallocFunctionPointers& mallocFunctionPointers) { + // Malloc calls are made by seemingly one of three means: + // + // 1) static CRT (debug builds): + // E8 42 38 00 00 call malloc + // -> + // E9 rel32 This is a direct intra-module 32 bit relative jump. E9 cd -- JMP rel32 + // -- Jump near, relative, RIP = RIP + 32-bit displacement sign extended to 64-bits + // -> + // + // + // 2) static CRT (release builds): + // E8 88 1F 00 00 call malloc + // -> + // + // + // 3) DLL CRT (debug and release builds): + // FF 15 6B DD 00 00 call qword ptr [__imp_malloc] This is an indirect jump to the 64 bit + // destination stored at the memory location 0000DD6B bytes from this location. __imp__malloc + // is an internal variable name which refers to this memory location. FF /5 -- JMP m16:64 -- + // Jump far, absolute indirect, address given in m16:64. + // -> + // + // + // In cases 1 and 3 above, malloc is called through a jump. That means we can replace the jump but + // leave the jump destination (actual malloc implementation) unmodified and thus potentially + // callable. There isn't a good solution for dealing with case #2, because in that case we would + // be overwriting the bytes of the actual malloc implementation, this making it uncallable in the + // future (without the risky trick of modifying the bytes as we call them). Copying the malloc + // instruction memory to a new location is not an option because malloc's implementation will have + // relative addess redirects which would break if it was in a different location. + + // We currently just set all the pointers to NULL. In the future we will want to make it so that + // in the case that malloc is a jump to a real malloc, we will want to set these pointers to the + // real malloc that it jumps to, so that we have the option of directly calling that malloc + // through PreservedMallocFunctionPointers. + PreservedMallocFunctionPointers = MallocFunctionPointers(); + CRTMallocPreserved = false; + +// We modify the initial instruction bytes of the CRT malloc functions to instead jump to the +// malloc functions specified by mallocFunctionPointers. Note that the initial CRT malloc function +// instruction bytes may be merly a jump to the real CRT malloc function implementation. +// +// The code here redirects functions by replacing their initial instruction bytes with instructions +// that redirect (jmp) execution to our own code. A primary risk of this is that the replacement +// will happen while the bytes are being executed by another thread, in which case the results are +// unpredictable and likely exceptional. We need to be careful to do this at some known safe time, +// such as before the application has started executing additional threads. +// +#if OVR_STATIC_CRT_PRESENT && defined(_MSC_VER) + // Override malloc, which is the CRT malloc function or code to jump to the CRT malloc function. + RedirectCdeclFunction( + malloc, mallocFunctionPointers.malloc_ptr, &SavedMallocFunctions.malloc_saved); + RedirectCdeclFunction( + calloc, mallocFunctionPointers.calloc_ptr, &SavedMallocFunctions.calloc_saved); + RedirectCdeclFunction( + realloc, mallocFunctionPointers.realloc_ptr, &SavedMallocFunctions.realloc_saved); + RedirectCdeclFunction( + _recalloc, mallocFunctionPointers.recalloc_ptr, &SavedMallocFunctions.recalloc_saved); + RedirectCdeclFunction( + _expand, mallocFunctionPointers.expand_ptr, &SavedMallocFunctions.expand_saved); + RedirectCdeclFunction( + _msize, mallocFunctionPointers.msize_ptr, &SavedMallocFunctions.msize_saved); + RedirectCdeclFunction(free, mallocFunctionPointers.free_ptr, &SavedMallocFunctions.free_saved); + RedirectCdeclFunction( + _aligned_malloc, + mallocFunctionPointers.aligned_malloc_ptr, + &SavedMallocFunctions.aligned_malloc_saved); + RedirectCdeclFunction( + _aligned_offset_malloc, + mallocFunctionPointers.aligned_offset_malloc_ptr, + &SavedMallocFunctions.aligned_offset_malloc_saved); + RedirectCdeclFunction( + _aligned_realloc, + mallocFunctionPointers.aligned_realloc_ptr, + &SavedMallocFunctions.aligned_realloc_saved); + RedirectCdeclFunction( + _aligned_offset_realloc, + mallocFunctionPointers.aligned_offset_realloc_ptr, + &SavedMallocFunctions.aligned_offset_realloc_saved); + RedirectCdeclFunction( + _aligned_recalloc, + mallocFunctionPointers.aligned_recalloc_ptr, + &SavedMallocFunctions.aligned_recalloc_saved); + RedirectCdeclFunction( + _aligned_offset_recalloc, + mallocFunctionPointers.aligned_offset_recalloc_ptr, + &SavedMallocFunctions.aligned_offset_recalloc_saved); + RedirectCdeclFunction( + _aligned_msize, + mallocFunctionPointers.aligned_msize_ptr, + &SavedMallocFunctions.aligned_msize_saved); + RedirectCdeclFunction( + _aligned_free, + mallocFunctionPointers.aligned_free_ptr, + &SavedMallocFunctions.aligned_free_saved); + +#if OVR_DEBUG_CRT_PRESENT // Within an ifdef because _malloc_dbg isn't present in a non-debug build. + RedirectCdeclFunction( + _malloc_dbg, mallocFunctionPointers.malloc_dbg_ptr, &SavedMallocFunctions.malloc_dbg_saved); + RedirectCdeclFunction( + _calloc_dbg, mallocFunctionPointers.calloc_dbg_ptr, &SavedMallocFunctions.calloc_dbg_saved); + RedirectCdeclFunction( + _realloc_dbg, + mallocFunctionPointers.realloc_dbg_ptr, + &SavedMallocFunctions.realloc_dbg_saved); + RedirectCdeclFunction( + _recalloc_dbg, + mallocFunctionPointers.recalloc_dbg_ptr, + &SavedMallocFunctions.recalloc_dbg_saved); + RedirectCdeclFunction( + _expand_dbg, mallocFunctionPointers.expand_dbg_ptr, &SavedMallocFunctions.expand_dbg_saved); + RedirectCdeclFunction( + _msize_dbg, mallocFunctionPointers.msize_dbg_ptr, &SavedMallocFunctions.msize_dbg_saved); + RedirectCdeclFunction( + _free_dbg, mallocFunctionPointers.free_dbg_ptr, &SavedMallocFunctions.free_dbg_saved); + RedirectCdeclFunction( + _aligned_malloc_dbg, + mallocFunctionPointers.aligned_malloc_dbg_ptr, + &SavedMallocFunctions.aligned_malloc_dbg_saved); + RedirectCdeclFunction( + _aligned_offset_malloc_dbg, + mallocFunctionPointers.aligned_offset_malloc_dbg_ptr, + &SavedMallocFunctions.aligned_offset_malloc_dbg_saved); + RedirectCdeclFunction( + _aligned_realloc_dbg, + mallocFunctionPointers.aligned_realloc_dbg_ptr, + &SavedMallocFunctions.aligned_realloc_dbg_saved); + RedirectCdeclFunction( + _aligned_offset_realloc_dbg, + mallocFunctionPointers.aligned_offset_realloc_dbg_ptr, + &SavedMallocFunctions.aligned_offset_realloc_dbg_saved); + RedirectCdeclFunction( + _aligned_recalloc_dbg, + mallocFunctionPointers.aligned_recalloc_dbg_ptr, + &SavedMallocFunctions.aligned_recalloc_dbg_saved); + RedirectCdeclFunction( + _aligned_offset_recalloc_dbg, + mallocFunctionPointers.aligned_offset_recalloc_dbg_ptr, + &SavedMallocFunctions.aligned_offset_recalloc_dbg_saved); + RedirectCdeclFunction( + _aligned_msize_dbg, + mallocFunctionPointers.aligned_msize_dbg_ptr, + &SavedMallocFunctions.aligned_msize_dbg_saved); + RedirectCdeclFunction( + _aligned_free_dbg, + mallocFunctionPointers.aligned_free_dbg_ptr, + &SavedMallocFunctions.aligned_free_dbg_saved); +#endif +#else + // It would be better to modify __imp_malloc, which is a pointer-sized data variable (void*) that + // indicates the addess to malloc in the CRT DLL. That way we could call the real malloc in the + // DLL directly if needed. Actually, if we con't override __imp_malloc and try to directly + // override malloc in the DLL then on 64 bit platforms the redirect will probably fail with our + // current implementation because it relies on a 32 bit relative jump, which will usually be too + // short to jump between modules. Note that overriding __imp_malloc needs to be done via modifying + // it as a data address and not by modifying it via a call to RedirectCdeclFunction below. + + OVR_UNUSED(mallocFunctionPointers); +#endif + + // We currently assume that if the first one succeeded, all succeeded. + if (SavedMallocFunctions.malloc_saved.Function) + MallocFunctionsSaved = true; + else { + MallocFunctionsSaved = false; + CRTMallocPreserved = false; + return false; + } + + MallocReplaced = true; + return true; +} + +bool InterceptCRTMalloc::RestoreCRTMalloc() { + MallocReplaced = false; + + if (MallocFunctionsSaved) { + MallocFunctionsSaved = false; + + RestoreCdeclFunction(&SavedMallocFunctions.malloc_saved); + RestoreCdeclFunction(&SavedMallocFunctions.calloc_saved); + RestoreCdeclFunction(&SavedMallocFunctions.realloc_saved); + RestoreCdeclFunction(&SavedMallocFunctions.recalloc_saved); + RestoreCdeclFunction(&SavedMallocFunctions.expand_saved); + RestoreCdeclFunction(&SavedMallocFunctions.msize_saved); + RestoreCdeclFunction(&SavedMallocFunctions.free_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_malloc_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_malloc_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_realloc_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_offset_realloc_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_recalloc_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_offset_recalloc_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_msize_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_free_saved); + +#if OVR_DEBUG_CRT_PRESENT + RestoreCdeclFunction(&SavedMallocFunctions.malloc_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.calloc_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.realloc_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.recalloc_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.expand_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.msize_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.free_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_malloc_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_offset_malloc_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_realloc_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_offset_realloc_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_recalloc_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_offset_recalloc_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_msize_dbg_saved); + RestoreCdeclFunction(&SavedMallocFunctions.aligned_free_dbg_saved); +#endif + } + + CRTMallocPreserved = false; + + return true; +} +#ifdef __clang__ +#pragma GCC diagnostic pop +#endif + +void* ovr_malloc(size_t size) { + return OVR::Allocator::GetInstance()->Alloc(size, nullptr); +} + +void* ovr_calloc(size_t count, size_t size) { + return OVR::Allocator::GetInstance()->Calloc(count, size, nullptr); +} + +void* ovr_realloc(void* p, size_t newSize) { + return OVR::Allocator::GetInstance()->Realloc(p, newSize); +} + +void* ovr_recalloc(void* p, size_t count, size_t size) { + return OVR::Allocator::GetInstance()->Recalloc(p, count, size); +} + +void* ovr_expand(void* /*p*/, size_t /*size*/) { + return nullptr; +} // Always fail an expand request, which is valid to do. + +size_t ovr_msize(void* p) { + return OVR::Allocator::GetInstance()->GetAllocSize(p); +} + +void ovr_free(void* p) { + return OVR::Allocator::GetInstance()->Free(p); +} + +void* ovr_aligned_malloc(size_t size, size_t align) { + return OVR::Allocator::GetInstance()->AllocAligned(size, align, nullptr); +} + +void* ovr_aligned_offset_malloc(size_t size, size_t align, size_t offset) { + OVR_ASSERT_AND_UNUSED(offset == 0, offset); + return ovr_aligned_malloc(size, align); +} // We don't currently support alignment offset. I've rarely seen it used. + +void* ovr_aligned_realloc(void* p, size_t size, size_t align) { + return OVR::Allocator::GetInstance()->ReallocAligned(p, size, align); +} + +void* ovr_aligned_offset_realloc(void* p, size_t size, size_t align, size_t offset) { + OVR_ASSERT_AND_UNUSED(offset == 0, offset); + return ovr_aligned_realloc(p, size, align); +} + +void* ovr_aligned_recalloc(void* p, size_t count, size_t size, size_t align) { + return OVR::Allocator::GetInstance()->RecallocAligned(p, count, size, align); +} + +void* ovr_aligned_offset_recalloc(void* p, size_t count, size_t size, size_t align, size_t offset) { + OVR_ASSERT_AND_UNUSED(offset == 0, offset); + return ovr_aligned_recalloc(p, count, size, align); +} + +size_t ovr_aligned_msize(void* p, size_t align, size_t offset) { + OVR_ASSERT_AND_UNUSED(offset == 0, offset); + return OVR::Allocator::GetInstance()->GetAllocAlignedSize(p, align); +} + +void ovr_aligned_free(void* p) { + return OVR::Allocator::GetInstance()->FreeAligned(p); +} + +#ifdef OVR_DEBUG_CRT_PRESENT // This is within an ifdef because the Microsoft dbg functions aren't +// present in non-debug-CRT builds. +void* ovr_malloc_dbg(size_t size, int /*blockUse*/, const char* file, int line) { + return OVR::Allocator::GetInstance()->AllocDebug(size, nullptr, file, line); +} + +void* ovr_calloc_dbg(size_t count, size_t size, int /*blockUse*/, const char* file, int line) { + return OVR::Allocator::GetInstance()->CallocDebug(count, size, nullptr, file, line); +} + +void* ovr_realloc_dbg(void* p, size_t newSize, int /*blockUse*/, const char* file, int line) { + return OVR::Allocator::GetInstance()->ReallocDebug(p, newSize, file, line); +} + +void* ovr_recalloc_dbg( + void* p, + size_t count, + size_t size, + int /*blockUse*/, + const char* file, + int line) { + return OVR::Allocator::GetInstance()->RecallocDebug(p, count, size, file, line); +} + +void* ovr_expand_dbg( + void* /*p*/, + size_t /*newSize*/, + int /*blockUse*/, + const char* /*file*/, + int /*line*/) { + return nullptr; +} // Always fail an expand request, which is valid to do. + +size_t ovr_msize_dbg(void* p, int /*blockUse*/) { + return OVR::Allocator::GetInstance()->GetAllocSize(p); +} + +void ovr_free_dbg(void* p, int /*blockUse*/) { + return OVR::Allocator::GetInstance()->Free(p); +} + +void* ovr_aligned_malloc_dbg(size_t size, size_t align, const char* file, int line) { + return OVR::Allocator::GetInstance()->AllocAlignedDebug(size, align, nullptr, file, line); +} + +void* ovr_aligned_offset_malloc_dbg( + size_t size, + size_t align, + size_t offset, + const char* file, + int line) { + OVR_ASSERT_AND_UNUSED(offset == 0, offset); + return ovr_aligned_malloc_dbg(size, align, file, line); +} + +void* ovr_aligned_realloc_dbg(void* p, size_t size, size_t align, const char* file, int line) { + return OVR::Allocator::GetInstance()->ReallocAlignedDebug(p, size, align, file, line); +} + +void* ovr_aligned_offset_realloc_dbg( + void* p, + size_t size, + size_t align, + size_t offset, + const char* file, + int line) { + OVR_ASSERT_AND_UNUSED(offset == 0, offset); + return ovr_aligned_realloc_dbg(p, size, align, file, line); +} + +void* ovr_aligned_recalloc_dbg( + void* p, + size_t count, + size_t size, + size_t align, + const char* file, + int line) { + return OVR::Allocator::GetInstance()->RecallocAlignedDebug(p, count, size, align, file, line); +} + +void* ovr_aligned_offset_recalloc_dbg( + void* p, + size_t count, + size_t size, + size_t align, + size_t offset, + const char* file, + int line) { + OVR_ASSERT_AND_UNUSED(offset == 0, offset); + return ovr_aligned_recalloc_dbg(p, count, size, align, file, line); +} + +size_t ovr_aligned_msize_dbg(void* p, size_t align, size_t offset) { + OVR_ASSERT_AND_UNUSED(offset == 0, offset); + return ovr_aligned_msize(p, align, 0); +} + +void ovr_aligned_free_dbg(void* p) { + return OVR::Allocator::GetInstance()->FreeAligned(p); +} +#endif + +//----------------------------------------------------------------------------------- +// ***** AllocatorAutoCreate +// +#if defined(_MSC_VER) +// #pragma init_seg(lib) statement makes it so that this module's globals are initialized right +// after the C standard library has initialized, and are destroyed right before the C standard +// library is destroyed (after after all other app globals are destroyed). That way we can execute +// code before other global variable constructors are called and execute code after other global +// variable destructors are called. There are other init_seg directives that can be used, such as +// those below. The linker actually just goes in alphabetic order, so you could initialize before +// the CRT by using init_seg(".CRT$XCB"). Useful links: +// https://blogs.msdn.microsoft.com/ce_base/2008/06/02/dynamic-initialization-of-variables/ +// http://shimpossible.blogspot.com/2013_07_01_archive.html +//#pragma init_seg(compiler) // Same as init_seg(".CRT$XCC") +//#pragma init_seg(lib) // Same as init_seg(".CRT$XCL") +//#pragma init_seg(user) // Same as init_seg(".CRT$XCU") +//#pragma init_seg("user_defined_segment_name") + +#pragma warning(disable : 4073) // warning C4073: initializers put in library initialization area. +#pragma warning(disable : 4074) // warning C4075: initializers put in compiler initialization area. +#pragma warning( \ + disable : 4075) // warning C4075: initializers put in unrecognized initialization area. +#pragma init_seg(lib) +#endif + +struct AllocatorAutoCreate { + AllocatorAutoCreate() { + Allocator::GetInstance(true); + } + + ~AllocatorAutoCreate() { + if (Allocator::GetInstance(false)) + Allocator::DestroyInstance(); + } +}; + +#if defined(_MSC_VER) +// Some linkers (including sometimes VC++) eliminate unreferenced globals such as the +// AllocatorAutoCreate instance below. However, we can prevent the linker from doing this via +// various techniques, such as dll-exporting the instance. +__declspec(dllexport) +#endif + AllocatorAutoCreate allocatorAutoCreate; + +//----------------------------------------------------------------------------------- +// ***** Allocator +// + +Allocator* Allocator::DefaultAllocator = nullptr; +uint64_t Allocator::ReferenceHeapTimeNs = 0; // Don't set this to GetCurrentHeapTimeNs() because we +// may need to initialize it earlier than that +// construction occurs. + +Allocator* Allocator::GetInstance(bool create) { + if (!DefaultAllocator && create) { +// This is not thread-safe. Two calls could race to this point. +#if defined(_WIN32) + // Cannot allocate memory while doing the following. + wchar_t moduleNameW[MAX_PATH]; + char defaultAllocatorName[MAX_PATH * 6] = + {}; // Maximum possible requirement for a UTF16 to UTF8 conversion. + DWORD nameStrlen = GetModuleFileNameW(nullptr, moduleNameW, MAX_PATH); + WideCharToMultiByte( + CP_UTF8, + 0, + moduleNameW, + nameStrlen + 1, + defaultAllocatorName, + sizeof(defaultAllocatorName), + nullptr, + nullptr); // +1 because WideCharToMultiByte will only 0-terminate if you include the 0 as + // part of the input. + defaultAllocatorName[sizeof(defaultAllocatorName) - 1] = '\0'; + std::transform( + defaultAllocatorName, + defaultAllocatorName + strlen(defaultAllocatorName), + defaultAllocatorName, + [](char c) { return ((c == '/') ? '\\' : c); }); // Convert any / to \. + const char* lastSeparator = strrchr(defaultAllocatorName, '\\'); + if (lastSeparator) + memmove(defaultAllocatorName, lastSeparator + 1, strlen(lastSeparator + 1) + 1); + OVR_strlcat(defaultAllocatorName, " Default Allocator", sizeof(defaultAllocatorName)); +#else + const char* defaultAllocatorName = "Default Allocator"; +#endif + DefaultAllocator = new (SysMemAlloc(sizeof(Allocator))) Allocator(defaultAllocatorName); + DefaultAllocator->Init(); + } + + return DefaultAllocator; +} + +void Allocator::DestroyInstance() { + if (DefaultAllocator) { + // This is not thread-safe. Two calls could race to this line. + DefaultAllocator->Shutdown(); + DefaultAllocator->~Allocator(); + SysMemFree(DefaultAllocator, sizeof(Allocator)); + DefaultAllocator = nullptr; + } +} + +Allocator::Allocator(const char* allocatorName) + : AllocatorName{}, + Heap(nullptr), + DebugPageHeapEnabled(false), + OSHeapEnabled(false), + MallocRedirectEnabled(false), + MallocRedirect(nullptr), + TrackingEnabled(false), + TraceAllocationsOnShutdown(false), + TrackLock(), + TrackIterator(), + AllocationMap(), + DelayedFreeList(), + DelayedAlignedFreeList(), + CurrentCounter(), + SymbolLookupEnabled(false), + TagMap(), + TagMapLock() { + SetAllocatorName(allocatorName); + + if (ReferenceHeapTimeNs == 0) // There is a thread race condition for the case that on startup two + // threads somehow execute this line at the same time. + ReferenceHeapTimeNs = GetCurrentHeapTimeNs(); +} + +void Allocator::SetAllocatorName(const char* allocatorName) { + if (allocatorName) + OVR::OVR_strlcpy(AllocatorName, allocatorName, OVR_ARRAY_COUNT(AllocatorName)); +} + +const char* Allocator::GetAllocatorName() const { + return AllocatorName; +} + +Allocator::~Allocator() { + Allocator::Shutdown(); +} + +bool Allocator::Init() { + if (!Heap) // If not already initialized... + { + // Potentially redirect the CRT malloc family of functions. + if (!MallocRedirectEnabled) // If not programmatically enabled before this init call... + { +#if OVR_REDIRECT_CRT_MALLOC + MallocRedirectEnabled = true; +#elif defined(_WIN32) + // "HKEY_LOCAL_MACHINE\SOFTWARE\Oculus\MallocRedirectEnabled" + // This code uses the registry API instead of OVR::Util::SettingsManager, because this code + // is allocator code which is special in that it needs to execute before all else is + // initialized. + MallocRedirectEnabled = + OVR::Util::GetRegistryBoolW(L"Software\\Oculus", L"MallocRedirectEnabled", false); +#else + MallocRedirectEnabled = false; +#endif + + if (Allocator::GetInstance(false) != this) // Only redirect malloc if we are the default heap. + MallocRedirectEnabled = false; + } + + if (MallocRedirectEnabled) { + // We will need to enable tracking so that we can distinguish between our pointers and + // pointers allocated via malloc before we did this redirect. + TrackingEnabled = true; + + // Make a struct of our override function pointers. + OVR::InterceptCRTMalloc::MallocFunctionPointers mfp; + + mfp.malloc_ptr = ovr_malloc; + mfp.calloc_ptr = ovr_calloc; + mfp.realloc_ptr = ovr_realloc; + mfp.recalloc_ptr = ovr_recalloc; + mfp.msize_ptr = ovr_msize; + mfp.free_ptr = ovr_free; + mfp.aligned_malloc_ptr = ovr_aligned_malloc; + mfp.aligned_offset_malloc_ptr = ovr_aligned_offset_malloc; + mfp.aligned_realloc_ptr = ovr_aligned_realloc; + mfp.aligned_offset_realloc_ptr = ovr_aligned_offset_realloc; + mfp.aligned_recalloc_ptr = ovr_aligned_recalloc; + mfp.aligned_offset_recalloc_ptr = ovr_aligned_offset_recalloc; + mfp.aligned_msize_ptr = ovr_aligned_msize; + mfp.aligned_free_ptr = ovr_aligned_free; + +#ifdef OVR_DEBUG_CRT_PRESENT + mfp.malloc_dbg_ptr = ovr_malloc_dbg; + mfp.calloc_dbg_ptr = ovr_calloc_dbg; + mfp.realloc_dbg_ptr = ovr_realloc_dbg; + mfp.recalloc_dbg_ptr = ovr_recalloc_dbg; + mfp.msize_dbg_ptr = ovr_msize_dbg; + mfp.free_dbg_ptr = ovr_free_dbg; + mfp.aligned_malloc_dbg_ptr = ovr_aligned_malloc_dbg; + mfp.aligned_offset_malloc_dbg_ptr = ovr_aligned_offset_malloc_dbg; + mfp.aligned_realloc_dbg_ptr = ovr_aligned_realloc_dbg; + mfp.aligned_offset_realloc_dbg_ptr = ovr_aligned_offset_realloc_dbg; + mfp.aligned_recalloc_dbg_ptr = ovr_aligned_recalloc_dbg; + mfp.aligned_offset_recalloc_dbg_ptr = ovr_aligned_offset_recalloc_dbg; + mfp.aligned_msize_dbg_ptr = ovr_aligned_msize_dbg; + mfp.aligned_free_dbg_ptr = ovr_aligned_free_dbg; +#endif + + MallocRedirect = new (SysMemAlloc(sizeof(OVR::InterceptCRTMalloc))) OVR::InterceptCRTMalloc; + MallocRedirect->ReplaceCRTMalloc(mfp); + } + + // Potentially enable the debug page heap. + if (!DebugPageHeapEnabled) // If not programmatically enabled before this init call... + { +// The debug page heap is restricted to 64 bit platforms due to the potential for address space +// exhaustion on 32-bit platforms. +#if defined(OVR_CPU_X86_64) +#if OVR_ALLOCATOR_DEBUG_PAGE_HEAP_ENABLED // If we should try to enable the debug heap... + DebugPageHeapEnabled = true; +#elif defined(_MSC_VER) + // "HKEY_LOCAL_MACHINE\SOFTWARE\Oculus\DebugPageHeapEnabled" + // This code uses the registry API instead of OVR::Util::SettingsManager, because this code + // is allocator code which is special in that it needs to execute before all else is + // initialized. + DebugPageHeapEnabled = OVR::Util::GetRegistryBoolW( + L"Software\\Oculus", L"DebugPageHeapEnabled", DebugPageHeapEnabled); +#else + DebugPageHeapEnabled = false; +#endif + +#ifdef __clang__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmicrosoft-cast" +#endif +#if defined(OVR_BUILD_DEBUG) && defined(_MSC_VER) + if (DebugPageHeapEnabled) { + // Make _CrtIsValidHeapPointer always return true. The VC++ concurrency library has a bug in + // that it's calling _CrtIsValidHeapPointer, which is invalid and recommended against by + // Microsoft themselves. We need to deal with this nevertheless. The problem is that the + // VC++ concurrency library is calling _CrtIsValidHeapPointer on the default heap instead of + // the current heap (DebugPageHeap). So we modify the _CrtIsValidHeapPointer implementation + // to always return true. The primary risk with this change is that there's some code + // somewhere that uses it for a non-diagnostic purpose. However this os + // Oculus-debug-internal and so has no effect on any formally published software. + DebugPageHeapEnabled = OVR::KillCdeclFunction( + _CrtIsValidHeapPointer, + true); // If we can successfully kill _CrtIsValidHeapPointer, enable our debug heap. + } +#ifdef __clang__ +#pragma GCC diagnostic pop +#endif +#endif +#endif + } + + if (DebugPageHeapEnabled) { + // We will need to enable tracking so that we can distinguish between our pointers and + // pointers allocated via malloc before we did this redirect. + TrackingEnabled = true; + + Heap = new (SysMemAlloc(sizeof(DebugPageHeap))) DebugPageHeap; + Heap->Init(); + } else if (MallocRedirectEnabled) { + // We will need to enable tracking so that we can distinguish between our pointers and + // pointers allocated via malloc before we did this redirect. + TrackingEnabled = true; + OSHeapEnabled = true; + + // If we are redirecting CRT malloc then we can't use the default heap, because it used CRT + // malloc, which would we be circular. + Heap = new (SysMemAlloc(sizeof(OSHeap))) OSHeap; + Heap->Init(); + } else // Else default heap (which uses malloc). + { + Heap = new (SysMemAlloc(sizeof(DefaultHeap))) DefaultHeap; + Heap->Init(); + } + + // Potentially enable allocation tracking. + if (!TrackingEnabled) // If not programmatically enabled before this init call... + { +#if OVR_ALLOCATOR_TRACKING_ENABLED + TrackingEnabled = true; +#else + TrackingEnabled = IsHeapTrackingRegKeyEnabled(TrackingEnabled); +#endif + } + + // Initialize the symbol and backtrace utility library + SymbolLookupEnabled = SymbolLookup::Initialize(); + } + + return true; +} + +void Allocator::Shutdown() { + if (Heap) // If we were initialized... + { + if (TraceAllocationsOnShutdown) + TraceTrackedAllocations(nullptr, 0); + + if (SymbolLookupEnabled) + SymbolLookup::Shutdown(); + + if (MallocRedirectEnabled) { + MallocRedirect->RestoreCRTMalloc(); + MallocRedirect->~InterceptCRTMalloc(); + SysMemFree(MallocRedirect, sizeof(OVR::InterceptCRTMalloc)); + MallocRedirect = nullptr; + } + +#if defined(_MSC_VER) + for (auto p : DelayedAlignedFreeList) + _aligned_free(p); +#endif + DelayedAlignedFreeList.clear(); + + for (auto p : DelayedFreeList) + free(p); + DelayedFreeList.clear(); + + AllocationMap.clear(); + TagMap.clear(); + CurrentCounter = 0; + + // Free the heap. + if (Heap) { + Heap->Shutdown(); + Heap->~Heap(); + if (DebugPageHeapEnabled) + SysMemFree(Heap, sizeof(DebugPageHeap)); + else + SysMemFree(Heap, sizeof(DefaultHeap)); + } + Heap = nullptr; + } +} + +void* Allocator::Alloc(size_t size, const char* tag) { + return AllocDebug(size, tag, nullptr, 0); +} + +void* Allocator::Calloc(size_t count, size_t size, const char* tag) { + return CallocDebug(count, size, tag, nullptr, 0); +} + +void* Allocator::AllocAligned(size_t size, size_t align, const char* tag) { + return AllocAlignedDebug(size, align, tag, nullptr, 0); +} + +void* Allocator::AllocDebug(size_t size, const char* tag, const char* file, unsigned line) { + OVR_ALLOC_BENCHMARK_START(); + + void* p = Heap->Alloc(size); + + if (p) { + TrackAlloc(p, size, tag, file, line); + } + + OVR_ALLOC_BENCHMARK_END(); + + return p; +} + +void* Allocator::CallocDebug( + size_t count, + size_t size, + const char* tag, + const char* file, + unsigned line) { + void* p = AllocDebug(count * size, tag, file, line); + + if (p) { + memset(p, 0, count * size); + } + + return p; +} + +void* Allocator::AllocAlignedDebug( + size_t size, + size_t align, + const char* tag, + const char* file, + unsigned line) { + OVR_ALLOC_BENCHMARK_START(); + + void* p = Heap->AllocAligned(size, align); + + if (p) { + TrackAlloc(p, size, tag, file, line); + } + + OVR_ALLOC_BENCHMARK_END(); + + return p; +} + +size_t Allocator::GetAllocSize(const void* p) const { + return Heap->GetAllocSize(p); +} + +size_t Allocator::GetAllocAlignedSize(const void* p, size_t align) const { + return Heap->GetAllocAlignedSize(p, align); +} + +void Allocator::Free(void* p) { + OVR_ALLOC_BENCHMARK_START(); + + if (p) { + if (UntrackAlloc(p)) // If this pointer is recognized as belonging to us... + { + Heap->Free(p); + } else { + // We don't recognize the pointer being freed. That almost always means one of two things: + // - We are overriding malloc/free and somebody is freeing memory that they allocated + // before we + // started overriding malloc and free. + // - We are not overriding malloc/free and somebody is freeing memory via operater delete + // which they allocated with malloc(). That's disallowed C++ but in fact it happens. + // We have a number of options for dealing with this and try to choose the best option: + // - Call CRT free function. + // Can't do this if we are overriding CRT free and have lost access to the original CRT + // free function. + // - Call the CRT underlying _free_base function. + // Can't do this if the debug CRT is active, because p is not the actual pointer to + // free. + // - Call the OS underlying HeapFree function. + // Can't do this if the debug CRT is active, because this method results in the debug + // heap structures being corrupt. + // - Put the pointer in a list which we free later, in the case that we are overriding CRT + // free and have lost access to the original CRT free function. + // This works fairly well. + // - Do nothing and let the memory leak in the underlying heap. + // This works fairly well but results in there looking like there was a CRT memory leak. + +#if defined(_MSC_VER) + if (MallocRedirect) { +#if OVR_DEBUG_CRT_PRESENT || (defined(_MSC_VER) && (_MSC_VER < 1900)) + // VS2013 doesn't expose _free_base, so use this delayed approach with VS2013. + // In this case we can't just call the internal CRT _free_base function becase the debug + // heap is active and we would need to call a dbg function. The best way for us to do that + // would be to implement our own function which works the same as _free_dbg(). However, for + // now we just add this pointer to the delayed free list and simply free it the normal way + // later when we shutdown. + DelayedFreeList.push_back( + p); // We will call free on the pointer later when we've restored the MallocRedirect. +#else + // In this case we can just call the internal CRT _free_base function that underlies all CRT + // malloc functions. + _free_base(p); +#endif + } else +#endif // defined(_MSC_VER) + { + free(p); + } + } + } + + OVR_ALLOC_BENCHMARK_END(); +} + +void Allocator::FreeAligned(void* p) { + OVR_ALLOC_BENCHMARK_START(); + + if (p) { + if (UntrackAlloc(p)) { + Heap->FreeAligned(p); + } else { +#if defined(_MSC_VER) + if (MallocRedirect) { +#if OVR_DEBUG_CRT_PRESENT || \ + (_MSC_VER < \ + 1900) // VS2013 doesn't expose _aligned_free_base, so use this delayed approach with VS2013. + // In this case we can't just call the internal CRT _aligned_free_base function becase the + // debug heap is active and we would need to call a dbg function. The best way for us to do + // that would be to implement our own function which works the same as _aligned_free_dbg(). + // However, for now we just add this pointer to the delayed free list and simply free it the + // normal way later when we shutdown. + DelayedAlignedFreeList.push_back(p); // We will call _aligned_free on the pointer later when +// we've restored the MallocRedirect. +#else + // In this case we can just call the internal CRT _free_base function that underlies all CRT + // malloc functions. + _aligned_free_base(p); +#endif + } else { + _aligned_free(p); + } +#else + free(p); +#endif + } + } + + OVR_ALLOC_BENCHMARK_END(); +} + +void* Allocator::Realloc(void* p, size_t newSize) { + return ReallocDebug(p, newSize, nullptr, 0); +} + +void* Allocator::Recalloc(void* p, size_t count, size_t newSize) { + return RecallocDebug(p, count, newSize, nullptr, 0); +} + +void* Allocator::ReallocAligned(void* p, size_t newSize, size_t newAlign) { + return ReallocAlignedDebug(p, newSize, newAlign, nullptr, 0); +} + +void* Allocator::RecallocAligned(void* p, size_t count, size_t newSize, size_t newAlign) { + return RecallocAlignedDebug(p, count, newSize, newAlign, nullptr, 0); +} + +void* Allocator::ReallocDebug(void* p, size_t newSize, const char* file, unsigned line) { + OVR_ALLOC_BENCHMARK_START(); + + // We have a tedious problem to solve here. If we have overridden malloc and the memory p was + // allocated by malloc before we did the override, then p belongs to the original malloc heap. We + // can attempt to reallocate it here with our own heap or we can reallocate it in the original + // heap it came from. The latter is simpler. + + AllocMetadata metadata; + bool valid = true; // realloc allows you to reallocate NULL, so set this to true by default. + void* pNew = nullptr; + + if (p) { + GetAllocMetadata(p, metadata); + valid = UntrackAlloc(p); // valid will be true if p is NULL, which is what we want. + } + + if (valid) { + pNew = Heap->Realloc(p, newSize); + + if (pNew) { + TrackAlloc(pNew, newSize, metadata.Tag, file, line); + } + } // Else p came from the CRT heap. It was likely malloc'd before we edirected malloc. + else if (MallocRedirect) { +#if defined(_MSC_VER) +// VS2013 doesn't expose _realloc_base, so use this delayed approach with VS2013. +#if OVR_DEBUG_CRT_PRESENT || (_MSC_VER < 1900) +#if OVR_DEBUG_CRT_PRESENT + size_t originalSize = header_from_block(p)->data_size; // We have to read internal debug data. + pNew = crt_malloc_dbg(newSize, _NORMAL_BLOCK, file, line); +#else + size_t originalSize = HeapSize(GetCRTHeapHandle(), 0, p); + pNew = HeapAlloc(GetCRTHeapHandle(), 0, newSize); +#endif // OVR_DEBUG_CRT_PRESENT + if (pNew) { + size_t copySize = std::min(originalSize, newSize); + memcpy(pNew, p, copySize); + DelayedFreeList.push_back(p); + } // Else don't free p and return nullptr. +#else + pNew = _realloc_base(p, newSize); +#endif // OVR_DEBUG_CRT_PRESENT +#else + OVR_UNUSED2(file, line); + return realloc(p, newSize); +#endif // _MSC_VER + } else { + pNew = realloc(p, newSize); + } + + OVR_ALLOC_BENCHMARK_END(); + + return pNew; +} + +void* Allocator::RecallocDebug( + void* p, + size_t count, + size_t newSize, + const char* file, + unsigned line) { + void* pNew = nullptr; + + if (!OVR::Alg::UnsignedMultiplyWouldOverflow(count, newSize)) { + newSize *= count; + + size_t oldSize; + bool valid = IsAllocTracked(p); + + if (valid) { + oldSize = GetAllocSize(p); + } else if (MallocRedirect) { +#if defined(_MSC_VER) +#if OVR_DEBUG_CRT_PRESENT + oldSize = header_from_block(p)->data_size; // We have to read internal debug data. +#else + oldSize = HeapSize(GetCRTHeapHandle(), 0, p); +#endif +#elif defined(__APPLE__) + oldSize = malloc_size(p); +#else + oldSize = malloc_usable_size(p); +#endif + } else { +#if defined(_MSC_VER) + // So which heap does this allocation come from? + oldSize = _msize(p); +#elif defined(__APPLE__) + oldSize = malloc_size(p); +#else + oldSize = malloc_usable_size(p); +#endif + } + + pNew = ReallocDebug(p, newSize, file, line); + + if (pNew && (newSize > oldSize)) { + memset( + reinterpret_cast(reinterpret_cast(pNew) + oldSize), + 0, + (newSize - oldSize)); + } + } + + return pNew; +} + +void* Allocator::ReallocAlignedDebug( + void* p, + size_t newSize, + size_t newAlign, + const char* file, + unsigned line) { + OVR_ALLOC_BENCHMARK_START(); + + AllocMetadata metadata; + bool valid = true; // realloc allows you to reallocate NULL, so set this to true by default. + void* pNew = nullptr; + + if (p) { + GetAllocMetadata(p, metadata); + valid = UntrackAlloc(p); // valid will be true if p is NULL, which is what we want. + } + + if (valid) { + pNew = Heap->ReallocAligned(p, newSize, newAlign); + + if (pNew) { + TrackAlloc(pNew, newSize, metadata.Tag, file, line); + } + + return pNew; + } else if (MallocRedirect) // Else this must go to the CRT heap. It was likely malloc'd before we + // existed. + { +#if defined(_MSC_VER) +#if OVR_DEBUG_CRT_PRESENT || (_MSC_VER < 1900) + // To do. This function in practice is not used by the CRT and so is not very important to us, + // especially as this is debug-build only. + OVR_FAIL_M("Allocator::ReallocAlignedDebug not implemented yet."); +#else + pNew = _aligned_realloc_base(p, newSize, newAlign); +#endif +#else + OVR_FAIL(); +#endif + } else { +#if defined(_MSC_VER) + pNew = _aligned_realloc(p, newSize, newAlign); +#else + OVR_FAIL(); +#endif + } + + OVR_ALLOC_BENCHMARK_END(); + + return pNew; +} + +void* Allocator::RecallocAlignedDebug( + void* p, + size_t count, + size_t newSize, + size_t newAlign, + const char* file, + unsigned line) { + void* pNew = nullptr; + + if (!OVR::Alg::UnsignedMultiplyWouldOverflow(count, newSize)) { + newSize *= count; + + size_t oldSize; + bool valid = IsAllocTracked(p); + + if (valid) { + oldSize = GetAllocAlignedSize( + p, newAlign); // We really want the original alignment, not the new alignment. + } else if (MallocRedirect) { +#if defined(_MSC_VER) +#if OVR_DEBUG_CRT_PRESENT + oldSize = header_from_block(p)->data_size; // We have to read internal debug data. +#else + oldSize = HeapSize(GetCRTHeapHandle(), 0, p); +#endif +#elif defined(__APPLE__) + oldSize = malloc_size(p); +#else + oldSize = malloc_usable_size(p); +#endif + } else { +#if defined(_MSC_VER) + // So which heap does this allocation come from? + oldSize = _aligned_msize( + p, newAlign, 0); // We really want the original alignment, not the new alignment. +#elif defined(__APPLE__) + oldSize = malloc_size(p); +#else + oldSize = malloc_usable_size(p); +#endif + } + + pNew = ReallocAlignedDebug(p, newSize, newAlign, file, line); + + if (pNew && (newSize > oldSize)) { + memset( + reinterpret_cast(reinterpret_cast(pNew) + oldSize), + 0, + (newSize - oldSize)); + } + } + + return pNew; +} + +uint64_t Allocator::GetCurrentHeapTimeNs() { +#if defined(_WIN32) + LARGE_INTEGER tickCount; + ::QueryPerformanceCounter(&tickCount); + + // To do: Move this to a single call on startup. + LARGE_INTEGER qpfFrequency; + ::QueryPerformanceFrequency(&qpfFrequency); + + return (uint64_t)((tickCount.QuadPart * UINT64_C(1000000000)) / qpfFrequency.QuadPart) - + ReferenceHeapTimeNs; +#else + auto current = std::chrono::high_resolution_clock::now().time_since_epoch(); + return std::chrono::duration_cast(current).count(); +#endif +} + +static AllocatorThreadId GetThreadId() { +#if defined(_WIN32) + return ::GetCurrentThreadId(); +#else + return (AllocatorThreadId)pthread_self(); // This cast isn't strictly portable. +#endif +} + +static bool ThreadIdIsValid(AllocatorThreadId threadId) { +#if defined(_WIN32) + bool result = false; + HANDLE h = ::OpenThread(THREAD_QUERY_LIMITED_INFORMATION, TRUE, threadId); + + if (h) { + DWORD exitCode; + BOOL bResult = ::GetExitCodeThread(h, &exitCode); + result = ((bResult != FALSE) && (exitCode != STILL_ACTIVE)); + ::CloseHandle(h); + } + + return result; +#else + OVR_UNUSED(threadId); + return true; +#endif +} + +void Allocator::PushTag(const char* tag) { + AllocatorThreadId threadId = GetThreadId(); + + Lock::Locker locker(&TagMapLock); + + TagMap[threadId].push_back(tag); + + if (TagMap.size() > 128) // This is some number that should be more than the number of unique + // threads we ever have. + PurgeTagMap(); +} + +void Allocator::PopTag() { + AllocatorThreadId threadId = GetThreadId(); + + Lock::Locker locker(&TagMapLock); + + // We do some error checking to make sure we don't crash if this facility is mis-used. + ThreadIdToTagVectorMap::iterator it = TagMap.find(threadId); + + if (it != TagMap.end()) { + if (!it->second.empty()) + it->second.pop_back(); + } +} + +const char* Allocator::GetTag(const char* defaultTag) { + Lock::Locker locker(&TagMapLock); + + AllocatorThreadId threadId = GetThreadId(); + ThreadIdToTagVectorMap::const_iterator it = TagMap.find(threadId); + + if (it != TagMap.end()) { + if (!it->second.empty()) + return it->second.back(); + } + + if (defaultTag) + return defaultTag; + + return OVR_ALLOCATOR_UNSPECIFIED_TAG; +} + +void Allocator::PurgeTagMap() { + Lock::Locker locker(&TagMapLock); + + for (ThreadIdToTagVectorMap::iterator it = TagMap.begin(); it != TagMap.end();) { + AllocatorThreadId threadId = it->first; + + if (!ThreadIdIsValid(threadId)) + it = TagMap.erase(it); + else + ++it; + } +} + +void Allocator::SetNewBlockMetadata( + Allocator* allocator, + AllocMetadata& amd, + const void* alloc, + uint64_t allocSize, + uint64_t blockSize, + const char* file, + int line, + const char* tag, + void** backtraceArray, + size_t backtraceArraySize) { + amd.Alloc = alloc; + amd.Backtrace.assign(backtraceArray, backtraceArray + backtraceArraySize); + amd.BacktraceSymbols.clear(); // This is only set when needed. + amd.File = file; + amd.Line = line; + amd.TimeNs = Allocator::GetCurrentHeapTimeNs(); + amd.Count = allocator->GetAndUpdateCounter(); + amd.AllocSize = allocSize; + amd.BlockSize = blockSize; + amd.Tag = tag; + amd.ThreadId = GetThreadId(); + OVR::Thread::GetCurrentThreadName( + amd.ThreadName, sizeof(amd.ThreadName)); // Currently works on Windows only for threads that + // were named via our OVR thread naming API. +} + +void Allocator::TrackAlloc( + const void* p, + size_t size, + const char* tag, + const char* file, + int line) { + if (p && TrackingEnabled) // To consider: Make TrackingEnabled an atomic. + { + auto AlignSizeUp = + [](size_t value, size_t alignment) -> size_t { // To do: Have a centralized version of this. + return ((value + (alignment - 1)) & ~(alignment - 1)); + }; + + TrackedAllocMap::value_type value(p, AllocMetadata()); + +#if defined(_WIN64) + void* addressArray[128]; + size_t frameCount = Symbols.GetBacktrace(addressArray, OVR_ARRAY_COUNT(addressArray), 2); +#else + // Currently 32 bit backtrace reading is too slow. We can fix it by writing our own version + // that reads the stack frames, but it's not a high priority since we work mostly with 64 bit. + void* addressArray[1] = {nullptr}; + size_t frameCount = 0; +#endif + + if (!tag) + tag = GetTag(); + + SetNewBlockMetadata( + this, + value.second, + p, + size, + AlignSizeUp(size, 8), // This is only a default value, and may be under-represented at time + // time, until we can have that passed into this function as well. + file, + line, + tag, + addressArray, + frameCount); + + Lock::Locker locker(&TrackLock); + + if (TrackingEnabled) // To consider: Do we really need to do this? + { + AllocationMap.insert(value); + } + } +} + +bool Allocator::UntrackAlloc(const void* p) { + if (!TrackingEnabled) + return true; // Just assume the pointer is valid. + + if (p) { + Lock::Locker locker(&TrackLock); + + TrackedAllocMap::iterator it = AllocationMap.find(p); + + if (it != AllocationMap.end()) { + AllocationMap.erase(it); + return true; + } + } + + return false; +} + +bool Allocator::IsAllocTracked(const void* p) { + if (!TrackingEnabled) + return true; // Just assume the pointer is valid. + + if (p) { + Lock::Locker locker(&TrackLock); + + return (AllocationMap.find(p) != AllocationMap.end()); + } + + return false; +} + +bool Allocator::GetAllocMetadata(const void* p, AllocMetadata& metadata) { + Lock::Locker locker(&TrackLock); + + TrackedAllocMap::iterator it = AllocationMap.find(p); + + if (it != AllocationMap.end()) { + const TrackedAllocMap::value_type& v = *it; + metadata = v.second; + return true; + } + + return false; +} + +bool Allocator::EnableTracking(bool enable) { + bool result = false; + + // We may need to deal with the case that this is called when we + // have already started memory allocation activity. Currently disabled. + Lock::Locker locker(&TrackLock); + + if (!Heap) // If we haven't initialized yet... + { + TrackingEnabled = enable; + result = true; + } else if (TrackingEnabled != enable) // if there is a change being requested... + { + // Currently we support the enabling and disabling of tracking after initialization + // only if we aren't using the page debug heap. We may be able to work around that + // in the future if needed. Tracking is enabled by default before initialization when + // the page debug heap is enabled, so it's only a matter here of attempting to + // disable tracking after it's been enabled, in practice. + if (!DebugPageHeapEnabled) { + TrackingEnabled = enable; + + if (!TrackingEnabled) // If we are disabling tracking... + { + AllocationMap.clear(); // Clear all the tracking we've done so far. + } + + result = true; + } // Else don't allow the change. + } else // Else there's no change. + { + result = true; + } + + return result; +} + +bool Allocator::EnableDebugPageHeap(bool enable) { + bool result = false; + + if (!Heap) // If we haven't initialized yet... + { + DebugPageHeapEnabled = enable; + result = true; + } + + return result; +} + +bool Allocator::EnableMallocRedirect() { + bool result = false; + + if (!Heap) { + MallocRedirectEnabled = true; + result = true; + } + + return result; +} + +bool Allocator::IsHeapTrackingRegKeyEnabled(bool defaultValue) { +#if defined(_WIN32) + // "HKEY_LOCAL_MACHINE\SOFTWARE\Oculus\HeapTrackingEnabled", REG_DWORD of 0 or 1. + // This code uses the registry API instead of OVR::Util::SettingsManager, because this code + // is allocator code which is special in that it needs to execute before all else is initialized. + return OVR::Util::GetRegistryBoolW(L"Software\\Oculus", L"HeapTrackingEnabled", defaultValue); +#else + return defaultValue; +#endif +} + +const AllocMetadata* Allocator::IterateHeapBegin() { + TrackLock.DoLock(); // Will be unlocked in IterateHeapEnd(). + + if (TrackingEnabled) { + // We have a problem in the case that a single thread calls IterateHeapBegin twice + // before calling IterateHeapEnd. It can be resolved the application calling IterateHeapEnd + // twice as well, but do we want to support that usage? It's probably easier to just disallow + // it. + + if (!AllocationMap.empty()) { + TrackIterator = AllocationMap.begin(); + return &TrackIterator->second; + } + } + + return nullptr; +} + +const AllocMetadata* Allocator::IterateHeapNext() { + ++TrackIterator; + + if (TrackIterator == AllocationMap.end()) + return nullptr; + + return &TrackIterator->second; +} + +void Allocator::IterateHeapEnd() { + TrackLock.Unlock(); +} + +size_t Allocator::DescribeAllocation( + const AllocMetadata* amd, + int amdFlags, + char* description, + size_t descriptionCapacity, + size_t appendedNewlineCount) { + SysAllocatedString descriptionString; + char buffer[2048]; + + if (amdFlags & AMFAlloc) { + snprintf(buffer, OVR_ARRAY_COUNT(buffer), "0x%p", amd->Alloc); + descriptionString += buffer; + } + + if (amdFlags & AMFAllocSize) { + snprintf(buffer, OVR_ARRAY_COUNT(buffer), ", size: %llu", (unsigned long long)amd->AllocSize); + descriptionString += buffer; + } + + if (amdFlags & AMFBlockSize) { + snprintf( + buffer, OVR_ARRAY_COUNT(buffer), ", block size: %llu", (unsigned long long)amd->BlockSize); + descriptionString += buffer; + } + + if (amdFlags & AMFTime) { + snprintf( + buffer, + OVR_ARRAY_COUNT(buffer), + ", time: %llus", + (unsigned long long)(amd->TimeNs / UINT64_C(1000000000))); + descriptionString += buffer; + } + + if (amdFlags & AMFCount) { + snprintf(buffer, OVR_ARRAY_COUNT(buffer), ", #: %llu", (unsigned long long)amd->Count); + descriptionString += buffer; + } + + if (amdFlags & AMFTag) { + snprintf( + buffer, + OVR_ARRAY_COUNT(buffer), + ", tag: %s", + amd->Tag ? amd->Tag : OVR_ALLOCATOR_UNSPECIFIED_TAG); + descriptionString += buffer; + } + + if (amdFlags & AMFThreadId) { + snprintf(buffer, OVR_ARRAY_COUNT(buffer), ", tid: %lu", (unsigned long)amd->ThreadId); + descriptionString += buffer; + } + + if (amdFlags & AMFThreadName) { + snprintf(buffer, OVR_ARRAY_COUNT(buffer), ", thread name: %s", amd->ThreadName); + descriptionString += buffer; + } + + if ((amdFlags & AMFFile) || (amdFlags & AMFLine)) { + snprintf(buffer, OVR_ARRAY_COUNT(buffer), ", file/line: %s(%d)", amd->File, amd->Line); + descriptionString += buffer; + } + + if (amdFlags & (AMFBacktrace | AMFBacktraceSymbols)) { + if (!descriptionString.empty()) // If anything was written above... + descriptionString += "\n"; + + for (size_t j = 0, jEnd = amd->Backtrace.size(); + (j < jEnd) && (descriptionString.length() < descriptionCapacity); + ++j) { + const bool shouldLookupSymbols = + (SymbolLookupEnabled && ((amdFlags & AMFBacktraceSymbols) != 0)); + SymbolInfo symbolInfo; + + if (shouldLookupSymbols && Symbols.LookupSymbol((uint64_t)amd->Backtrace[j], symbolInfo) && + (symbolInfo.filePath[0] || symbolInfo.function[0])) { + if (symbolInfo.filePath[0]) + snprintf( + buffer, + OVR_ARRAY_COUNT(buffer), + "%2u: %s(%d): %s\n", + (unsigned)j, + symbolInfo.filePath, + symbolInfo.fileLineNumber, + symbolInfo.function[0] ? symbolInfo.function : "(unknown function)"); + else + snprintf( + buffer, + OVR_ARRAY_COUNT(buffer), + "%2u: 0x%p (unknown source file): %s\n", + (unsigned)j, + amd->Backtrace[j], + symbolInfo.function); + } else { + snprintf( + buffer, + OVR_ARRAY_COUNT(buffer), + "%2u: 0x%p (symbols unavailable)\n", + (unsigned)j, + amd->Backtrace[j]); + } + + descriptionString += buffer; + } + + descriptionString.erase( + descriptionString.size() - 1); // Remove the last newline. We may add back below. + } + + for (size_t i = 0; i < appendedNewlineCount; ++i) + descriptionString += '\n'; + + return OVR_strlcpy(description, descriptionString.c_str(), descriptionCapacity); +} + +size_t Allocator::TraceTrackedAllocations(AllocationTraceCallback callback, uintptr_t context) { + const bool symbolLookupWasInitialized = SymbolLookup::IsInitialized(); + const bool symbolLookupAvailable = SymbolLookup::Initialize(); + + if (!symbolLookupWasInitialized) // If SymbolLookup::Initialize was the first time being + // initialized, we need to refresh the Symbols view of modules, + // etc. + Symbols.Refresh(); + + // If we're dumping while LibOVR is running, then we should hold the lock. + Allocator* pAlloc = Allocator::GetInstance(); + + // It's possible this is being called after the Allocator was shut down, at which + // point we assume we are the only instance that can be executing at his time. + Lock* lock = pAlloc ? &pAlloc->TrackLock : nullptr; + if (lock) + lock->DoLock(); + + size_t measuredLeakCount = 0; + size_t reportedLeakCount = + 0; // = realLeakCount minus leaks we ignore (e.g. C++ runtime concurrency leaks). + const size_t leakReportBufferSize = 8192; + char* leakReportBuffer = nullptr; + + // Print out detail for each leaked pointer, but filtering away some that we ignore. + for (TrackedAllocMap::const_iterator it = AllocationMap.begin(); it != AllocationMap.end(); + ++it) { + const TrackedAllocMap::value_type& v = *it; + const void* p = v.first; + const AllocMetadata& amd = v.second; + + measuredLeakCount++; + + if (!leakReportBuffer) // Lazy allocate this, as it wouldn't be needed unless we had a leak, + // which we aim to be an unusual case. + { + leakReportBuffer = static_cast(SafeMMapAlloc(leakReportBufferSize)); + if (!leakReportBuffer) + break; + } + leakReportBuffer[0] = '\0'; + + char line[2048]; + snprintf( + line, + OVR_ARRAY_COUNT(line), + "\n0x%p, size: %u, tag: %.64s\n", + p, + (unsigned)amd.AllocSize, + amd.Tag ? amd.Tag : "none"); // Limit the tag length so that this can't exhaust the dest + // buffer. We need more dest buffer space below. + size_t currentStrlen = OVR_strlcat(leakReportBuffer, line, leakReportBufferSize); + + if (amd.Backtrace.empty()) { + snprintf(line, OVR_ARRAY_COUNT(line), "(backtrace unavailable)\n"); + OVR_strlcat(leakReportBuffer, line, leakReportBufferSize); + } else { + size_t remainingCapacity = (leakReportBufferSize - currentStrlen); + DescribeAllocation( + &amd, + (AMFBacktrace | AMFBacktraceSymbols), + leakReportBuffer + currentStrlen, + remainingCapacity, + 1); + + // There are some leaks that aren't real because they are allocated by the Standard Library at + // runtime but aren't freed until shutdown. We don't want to report those, and so we filter + // them out here. + const char* ignoredPhrases[] = {"Concurrency::details" /*add any additional strings here*/}; + + for (size_t j = 0; j < OVR_ARRAY_COUNT(ignoredPhrases); ++j) { + if (strstr(leakReportBuffer, ignoredPhrases[j])) // If we should ignore this leak... + { + leakReportBuffer[0] = '\0'; + } + } + } + + if (leakReportBuffer[0]) // If we are to report this as a bonafide leak... + { + ++reportedLeakCount; + + // We cannot use normal logging system here because it will allocate more memory! + if (callback) + callback(context, leakReportBuffer); + else + OVR_DEBUG_TRACE(leakReportBuffer); + } + } + + char summaryBuffer[128]; + snprintf( + summaryBuffer, + OVR_ARRAY_COUNT(summaryBuffer), + "Measured leak count: %llu, Reported leak count: %llu\n", + (unsigned long long)measuredLeakCount, + (unsigned long long)reportedLeakCount); + + if (callback) + callback(context, summaryBuffer); + else + OVR_DEBUG_TRACE(summaryBuffer); + + if (leakReportBuffer) { + SafeMMapFree(leakReportBuffer, leakReportBufferSize); + leakReportBuffer = nullptr; + } + + if (lock) + lock->Unlock(); + + if (symbolLookupAvailable) + SymbolLookup::Shutdown(); + + return reportedLeakCount; +} + +//------------------------------------------------------------------------ +// ***** HeapIterationFilterRPN +// + +HeapIterationFilterRPN::HeapIterationFilterRPN() + : AllocatorInstance(nullptr), + Filter(nullptr), + Instructions{}, + CurrentHeapTimeNs(Allocator::GetCurrentHeapTimeNs()) {} + +bool HeapIterationFilterRPN::SetFilter(Allocator* allocator, const char* filter) { + AllocatorInstance = allocator; + Filter = filter; + return Compile(filter); +} + +const AllocMetadata* HeapIterationFilterRPN::IterateHeapBegin() { + const AllocMetadata* amd = AllocatorInstance->IterateHeapBegin(); + + while (amd && !Evaluate(amd)) + amd = AllocatorInstance->IterateHeapNext(); + + return amd; +} + +const AllocMetadata* HeapIterationFilterRPN::IterateHeapNext() { + const AllocMetadata* amd = AllocatorInstance->IterateHeapNext(); + + while (amd && !Evaluate(amd)) + amd = AllocatorInstance->IterateHeapNext(); + + return amd; +} + +void HeapIterationFilterRPN::IterateHeapEnd() { + AllocatorInstance->IterateHeapEnd(); +} + +bool HeapIterationFilterRPN::Compile(const char* filter) { + bool success = true; // To consider: We can report syntax errors and associated line numbers. + + static_assert( + std::is_standard_layout::value, "Instructions is presumed to be a POD here."); + memset(Instructions, 0, sizeof(Instructions)); + + for (size_t instructionCount = 0; success && (instructionCount < OVR_ARRAY_COUNT(Instructions)); + ++instructionCount) // While reading each line until the end of the text... + { + while (isspace(*filter)) // Move past whitespace. Currently we need this only because of our + // isOperandLine check below. + ++filter; + + Instruction instruction{}; + char tempDataType[12], tempCompare[8], tempComparand[256], tempOperation[8], *nextChar; + size_t i; + bool isOperandLine = OVR_strnicmp(filter, "and", 3) && + OVR_strnicmp(filter, "or", 2); // To consider: Find a cleaner way to discern which of the + // two kinds of lines this is (operand or operation). + + if ((*filter == '\r') || (*filter == '\n') || (*filter == '/')) { + // Ignore lines that are empty or begin with / + } else if ( + isOperandLine && +#if defined(_MSC_VER) + (sscanf_s( + filter, + "%11s %7s %255[^;]s", + tempDataType, + (unsigned)sizeof(tempDataType), + tempCompare, + (unsigned)sizeof(tempCompare), + tempComparand, + (unsigned)sizeof(tempComparand)) == + 3)) // If this line looks like an operand (e.g. AllocSize > 100)... +#else + (sscanf(filter, "%11s %7s %255[^;]s", tempDataType, tempCompare, tempComparand) == + 3)) // If this line looks like an operand (e.g. AllocSize > 100)... +#endif + { + static_assert( + sizeof(tempComparand) == 256, + "The format string here assumes 256. Fix the format string and this assert if tempComparand changes."); + + struct OperandTypePair { + const char* str; + AllocMetadataFlags value; + } operandTypeMap[] = {{"File", AMFFile}, + {"Line", AMFLine}, + {"Time", AMFTime}, + {"Count", AMFCount}, + {"Size", AMFAllocSize}, + {"AllocSize", AMFAllocSize}, + {"BlockSize", AMFBlockSize}, + {"Tag", AMFTag}, + {"ThreadId", AMFThreadId}, + {"ThreadName", AMFThreadName}}; + + // Read the operand (e.g. size) + for (i = 0; + i < OVR_ARRAY_COUNT(operandTypeMap) && (instruction.operand.metadataType == AMFNone); + ++i) { + if (OVR_stricmp(tempDataType, operandTypeMap[i].str) == 0) + instruction.operand.metadataType = operandTypeMap[i].value; + } + success = success && + (instruction.operand.metadataType != AMFNone); // Successful if a match was found. + + // Read the compare type (e.g. >=) + struct CompareTypePair { + const char* str; + Comparison value; + } compareTypeMap[] = { + {"==", CmpE}, {"<", CmpL}, {"<=", CmpLE}, {">", CmpG}, {">=", CmpGE}, {"has", CmpHas}}; + + for (i = 0; + i < OVR_ARRAY_COUNT(compareTypeMap) && (instruction.operand.comparison == CmpNone); + ++i) { + if (OVR_stricmp(tempCompare, compareTypeMap[i].str) == 0) + instruction.operand.comparison = compareTypeMap[i].value; + } + success = success && + (instruction.operand.comparison != CmpNone); // Successful if a match was found. + + // Read the comparand (e.g. 4096) + instruction.operand.numValue = + strtoll(tempComparand, &nextChar, 10); // Just read it as both types here; we'll + strcpy(instruction.operand.strValue, tempComparand); // decide at execution time which to use. + + if (instruction.operand.metadataType == AMFTime) { + if (*nextChar == + 's') // If the filter is specifying time in seconds instead of nanoseconds... + instruction.operand.numValue *= 1000000000; // convert numValue from seconds to + // nanoseconds (which is what we + // internally use). + if (instruction.operand.numValue < + 0) // Handle the case that a negative time was passed, which + instruction.operand.numValue += + CurrentHeapTimeNs; // means to refer to time relative to current time. + } else if ( + (instruction.operand.metadataType == AMFCount) && + (instruction.operand.numValue < + 0)) // Handle the case that a negative count was passed, which + instruction.operand.numValue += + AllocatorInstance->GetCounter(); // means to refer to the last N allocations. + } +#if defined(_MSC_VER) + else if ( + sscanf_s(filter, "%7[^;]s", tempOperation, (unsigned)sizeof(tempOperation)) == + 1) // If this line looks like an operation (e.g. And or Or). +#else + else if (sscanf(filter, "%7[^;]s", tempOperation) == 1) // If this line looks like an operation +// (e.g. And or Or). +#endif + { + if (OVR_stricmp(tempOperation, "and") == 0) + instruction.operation = OpAnd; + else if (OVR_stricmp(tempOperation, "or") == 0) + instruction.operation = OpOr; + else + success = false; + } else + success = false; + + if (success) { + if (instructionCount < OVR_ARRAY_COUNT(Instructions)) + Instructions[instructionCount] = instruction; + else + success = false; // Out of space. + } + + // Move to the start of the next statement (delimited by ; or \n) + filter = strpbrk(filter, ";\n"); + if (filter) + filter++; + else + break; + } + + return success; +} + +// Evaluates an individual operand, such as (AllocSize < 32). +bool HeapIterationFilterRPN::EvaluateOperand(const Operand& operand, const AllocMetadata* amd) + const { + switch ((int)operand.metadataType) // Cast to int in order to avoid compiler warnings about + // unhandled enumerants. + { + case AMFFile: + case AMFTag: + case AMFThreadName: // String-based operands + { + const char* p; + + switch ((int)operand.metadataType) { + default: + case AMFFile: + p = amd->File; + break; + case AMFTag: + p = amd->Tag; + break; + case AMFThreadName: + p = amd->ThreadName; + break; + } + + switch ((int)operand.comparison) { + case CmpE: + return (OVR_stricmp(p, operand.strValue) == 0); + case CmpHas: + return (OVR_stristr(p, operand.strValue) != nullptr); + } + } + + case AMFLine: + case AMFTime: + case AMFCount: + case AMFAllocSize: + case AMFBlockSize: + case AMFThreadId: // Integer-based operands + { + int64_t n; + + switch ((int)operand.metadataType) { + default: + case AMFLine: + n = amd->Line; + break; + case AMFTime: + n = amd->TimeNs; + break; + case AMFCount: + n = amd->Count; + break; + case AMFAllocSize: + n = amd->AllocSize; + break; + case AMFBlockSize: + n = amd->BlockSize; + break; + case AMFThreadId: + n = amd->ThreadId; + break; + } + + switch ((int)operand.comparison) { + case CmpE: + return (n == operand.numValue); + case CmpL: + return (n < operand.numValue); + case CmpLE: + return (n <= operand.numValue); + case CmpG: + return (n > operand.numValue); + case CmpGE: + return (n >= operand.numValue); + } + } + } + + return false; +} + +bool HeapIterationFilterRPN::Evaluate(const AllocMetadata* amd) { + // We execute an RPN (a.k.a. postfix) stack here. Because our language here involves + // only logical operations, our stack need be only a stack of bool. + struct Stack { + bool data[32]; + size_t size; + + void PopAndSet(bool value) { + memmove(&data[1], &data[2], sizeof(data) - (2 * sizeof(bool))); + data[0] = value; + size -= 1; + } + void Push(bool value) { + memmove(&data[1], &data[0], sizeof(data) - (1 * sizeof(bool))); + data[0] = value; + size += 1; + } + } stack{{true}, 1}; // By default the state is true. An empty instruction set evaluates as true. + + for (size_t i = 0; (i < OVR_ARRAY_COUNT(Instructions)) && + ((Instructions[i].operation != OpNone) || (Instructions[i].operand.comparison != CmpNone)); + ++i) { + if (Instructions[i].operation != OpNone) // if this is an operation... + { + if (Instructions[i].operation == OpAnd) + stack.PopAndSet(stack.data[0] && stack.data[1]); + else + stack.PopAndSet(stack.data[0] || stack.data[1]); + } else // Else this is an operand push. + stack.Push(EvaluateOperand(Instructions[i].operand, amd)); + } + + return stack.data[0]; +} + +void HeapIterationFilterRPN::TraceTrackedAllocations( + Allocator* allocator, + const char* filter, + Allocator::AllocationTraceCallback callback, + uintptr_t context) { + OVR::HeapIterationFilterRPN hifRPN; + + hifRPN.SetFilter(allocator, filter); + + for (const OVR::AllocMetadata* amd = hifRPN.IterateHeapBegin(); amd; + amd = hifRPN.IterateHeapNext()) { + char description[16384]; + allocator->DescribeAllocation(amd, 0xffff, description, sizeof(description), 0); + callback(context, description); + } + + hifRPN.IterateHeapEnd(); +} + +//------------------------------------------------------------------------ +// ***** DefaultHeap +// + +bool DefaultHeap::Init() { + // Nothing to do. + return true; +} + +void DefaultHeap::Shutdown() { + // Nothing to do. +} + +void* DefaultHeap::Alloc(size_t size) { + void* p = malloc(size); + + return p; +} + +void* DefaultHeap::AllocAligned(size_t size, size_t align) { +#if defined(_MSC_VER) + void* p = _aligned_malloc(size, align); +#else + void* p; + int result = posix_memalign(&p, align, size); + (void)result; // To do. +#endif + + return p; +} + +size_t DefaultHeap::GetAllocSize(const void* p) const { +#if defined(_MSC_VER) + return _msize(const_cast(p)); +#elif defined(__APPLE__) + return malloc_size(p); +#else + return malloc_usable_size(const_cast(p)); +#endif +} + +size_t DefaultHeap::GetAllocAlignedSize(const void* p, size_t align) const { +#if defined(_MSC_VER) + return _aligned_msize(const_cast(p), align, 0); +#elif defined(__APPLE__) + OVR_UNUSED(align); + return malloc_size(p); +#else + OVR_UNUSED(align); + return malloc_usable_size(const_cast(p)); +#endif +} + +void DefaultHeap::Free(void* p) { + free(p); +} + +void DefaultHeap::FreeAligned(void* p) { +#if defined(_MSC_VER) + _aligned_free(p); +#else + free(p); // No special function required. +#endif +} + +void* DefaultHeap::Realloc(void* p, size_t newSize) { + void* newP = realloc(p, newSize); + + return newP; +} + +void* DefaultHeap::ReallocAligned(void* p, size_t newSize, size_t newAlign) { +#if defined(_MSC_VER) + void* pNew = _aligned_realloc(p, newSize, newAlign); +#else + OVR_UNUSED(newAlign); + void* pNew = realloc(p, newSize); // We expect the implementation to know its alignment. There is +// no standard posix_memalign_realloc. +#endif + + return pNew; +} + +//------------------------------------------------------------------------ +// ***** OSHeap +// + +OSHeap::OSHeap() : Heap(nullptr) {} + +OSHeap::~OSHeap() { + OSHeap::Shutdown(); +} + +bool OSHeap::Init() { +#if defined(_WIN32) + Heap = GetProcessHeap(); // This never fails. +#endif + return true; +} + +void OSHeap::Shutdown() { + // Do not free this heap. Its lifetime is maintained by the OS. + Heap = nullptr; +} + +void* OSHeap::Alloc(size_t size) { +#if defined(_WIN32) + return HeapAlloc(Heap, 0, size); +#else + return malloc(size); +#endif +} + +void* OSHeap::AllocAligned(size_t size, size_t align) { +#if defined(_WIN32) + (void)align; + // We need to solve this if we are to support aligned memory. We'll need to allocate exta memory + // up front, return an internal pointer, and store info to find the base pointer. + OVR_FAIL_M("OSHeap::AllocAligned not yet supported."); + return HeapAlloc(Heap, 0, size); +#else + void* p; + int result = posix_memalign(&p, align, size); + (void)result; + return p; +#endif +} + +size_t OSHeap::GetAllocSize(const void* p) const { +#if defined(_WIN32) + return HeapSize(Heap, 0, p); +#elif defined(__APPLE__) + return malloc_size(p); +#else + return malloc_usable_size(const_cast(p)); +#endif +} + +size_t OSHeap::GetAllocAlignedSize(const void* p, size_t /*align*/) const { +#if defined(_WIN32) + // We need to solve this if we are to support aligned memory. + OVR_FAIL_M("OSHeap::AllocAligned not yet supported."); + return HeapSize(Heap, 0, p); +#elif defined(__APPLE__) + return malloc_size(p); +#else + return malloc_usable_size(const_cast(p)); +#endif +} + +void OSHeap::Free(void* p) { +#if defined(_WIN32) + BOOL result = HeapFree(Heap, 0, p); + OVR_ASSERT_AND_UNUSED(result, result); +#else + free(p); +#endif +} + +void OSHeap::FreeAligned(void* p) { +#if defined(_WIN32) + OVR_FAIL_M("OSHeap::AllocAligned not yet supported."); + BOOL result = HeapFree(Heap, 0, p); + OVR_ASSERT_AND_UNUSED(result, result); +#else + free(p); +#endif +} + +void* OSHeap::Realloc(void* p, size_t newSize) { +#if defined(_WIN32) + return HeapReAlloc(Heap, 0, p, newSize); +#else + return realloc(p, newSize); +#endif +} + +void* OSHeap::ReallocAligned(void* p, size_t newSize, size_t /*newAlign*/) { +#if defined(_WIN32) + // We need to solve this if we are to support aligned memory. + return HeapReAlloc(Heap, 0, p, newSize); +#else + OVR_FAIL(); // This isn't supported properly currently. + return realloc(p, newSize); +#endif +} + +//------------------------------------------------------------------------ +// ***** SafeMMapAlloc / SafeMMapFree +// + +void* SafeMMapAlloc(size_t size) { +#if defined(_WIN32) + return VirtualAlloc( + nullptr, + size, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE); // size is rounded up to a page. // Returned memory is 0-filled. + +#elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) +#if !defined(MAP_FAILED) +#define MAP_FAILED ((void*)-1) +#endif + + void* result = mmap( + nullptr, + size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, + -1, + 0); // Returned memory is 0-filled. + if (result == MAP_FAILED) // mmap returns MAP_FAILED (-1) upon failure. + result = nullptr; + return result; +#endif +} + +void SafeMMapFree(const void* memory, size_t size) { +#if defined(_WIN32) + OVR_UNUSED(size); + VirtualFree(const_cast(memory), 0, MEM_RELEASE); + +#elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) + size_t pageSize = getpagesize(); + size = (((size + (pageSize - 1)) / pageSize) * pageSize); + munmap(const_cast(memory), size); // Must supply the size to munmap. +#endif +} + +//------------------------------------------------------------------------ +// ***** DebugPageHeap + +static size_t AlignSizeUp(size_t value, size_t alignment) { + return ((value + (alignment - 1)) & ~(alignment - 1)); +} + +static size_t AlignSizeDown(size_t value, size_t alignment) { + return (value & ~(alignment - 1)); +} + +template +Pointer AlignPointerUp(Pointer p, size_t alignment) { + return reinterpret_cast( + ((reinterpret_cast(p) + (alignment - 1)) & ~(alignment - 1))); +} + +template +Pointer AlignPointerDown(Pointer p, size_t alignment) { + return reinterpret_cast(reinterpret_cast(p) & ~(alignment - 1)); +} + +const size_t kFreedBlockArrayMaxSizeDefault = 16384; + +DebugPageHeap::DebugPageHeap() + : FreedBlockArray(nullptr), + FreedBlockArrayMaxSize(0), + FreedBlockArraySize(0), + FreedBlockArrayOldest(0), + AllocationCount(0), + OverrunPageEnabled(true) +#if defined(OVR_BUILD_DEBUG) + , + OverrunGuardBytesEnabled(true) +#else + , + OverrunGuardBytesEnabled(false) +#endif + // PageSize(0) + , + Lock() { +#if OVR_HUNT_UNTRACKED_ALLOCS + _CrtSetAllocHook(HuntUntrackedAllocHook); +#endif + +#if defined(_WIN32) + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + PageSize = (size_t)systemInfo.dwPageSize; +#else + PageSize = 4096; +#endif + + SetMaxDelayedFreeCount(kFreedBlockArrayMaxSizeDefault); +} + +DebugPageHeap::~DebugPageHeap() { + Shutdown(); +} + +bool DebugPageHeap::Init() { + // Nothing to do. + return true; +} + +void DebugPageHeap::Shutdown() { + Lock::Locker autoLock(&Lock); + + for (size_t i = 0; i < FreedBlockArraySize; i++) { + if (FreedBlockArray[i].BlockPtr) { + FreePageMemory(FreedBlockArray[i].BlockPtr, FreedBlockArray[i].BlockSize); + FreedBlockArray[i].Clear(); + } + } + + SetMaxDelayedFreeCount(0); + FreedBlockArraySize = 0; + FreedBlockArrayOldest = 0; +} + +void DebugPageHeap::EnableOverrunDetection( + bool enableOverrunDetection, + bool enableOverrunGuardBytes) { + // Assert that no allocations have been made, which is a requirement for changing these + // properties. Otherwise future deallocations of these allocations can fail to work properly + // because these settings have changed behind their back. + OVR_ASSERT_M( + AllocationCount == 0, + "DebugPageHeap::EnableOverrunDetection called when DebugPageHeap is not in a newly initialized state."); + + OverrunPageEnabled = enableOverrunDetection; + OverrunGuardBytesEnabled = + (enableOverrunDetection && enableOverrunGuardBytes); // Set OverrunGuardBytesEnabled to false + // if enableOverrunDetection is false. +} + +void DebugPageHeap::SetMaxDelayedFreeCount(size_t maxDelayedFreeCount) { + if (FreedBlockArray) { + SafeMMapFree(FreedBlockArray, FreedBlockArrayMaxSize * sizeof(Block)); + FreedBlockArrayMaxSize = 0; + } + + if (maxDelayedFreeCount) { + FreedBlockArray = (Block*)SafeMMapAlloc(maxDelayedFreeCount * sizeof(Block)); + OVR_ASSERT(FreedBlockArray); + + if (FreedBlockArray) { + FreedBlockArrayMaxSize = maxDelayedFreeCount; +#if defined(OVR_BUILD_DEBUG) + memset(FreedBlockArray, 0, maxDelayedFreeCount * sizeof(Block)); +#endif + } + } +} + +size_t DebugPageHeap::GetMaxDelayedFreeCount() const { + return FreedBlockArrayMaxSize; +} + +void* DebugPageHeap::Alloc(size_t size) { +#if defined(_WIN32) + return AllocAligned(size, DefaultAlignment); +#else + return malloc(size); +#endif +} + +void* DebugPageHeap::AllocAligned(size_t size, size_t align) { +#if defined(_WIN32) + OVR_ASSERT(align <= PageSize); + + Lock::Locker autoLock(&Lock); + + if (align < DefaultAlignment) + align = DefaultAlignment; + + // The actual needed size may be a little less than this, but it's hard to tell how the size and + // alignments will play out. + size_t maxRequiredSize = AlignSizeUp(size, align) + SizeStorageSize; + + if (align > SizeStorageSize) { + // Must do: more sophisticated fitting, as maxRequiredSize is potentially too small. + OVR_ASSERT(SizeStorageSize <= align); + } + + size_t blockSize = AlignSizeUp(maxRequiredSize, PageSize); + + if (OverrunPageEnabled) + blockSize += PageSize; // We add another page which will be uncommitted, so any read or write + // with it will except. + + void* pBlockPtr; + + if ((FreedBlockArraySize == FreedBlockArrayMaxSize) && + FreedBlockArrayMaxSize && // If there is an old block we can recycle... + (FreedBlockArray[FreedBlockArrayOldest].BlockSize == blockSize)) // We require it to be the + // exact size, as there would + // be some headaches for us + // if it was over-sized. + { + pBlockPtr = EnablePageMemory( + FreedBlockArray[FreedBlockArrayOldest].BlockPtr, + blockSize); // Convert this memory from PAGE_NOACCESS back to PAGE_READWRITE. + FreedBlockArray[FreedBlockArrayOldest].Clear(); + + if (++FreedBlockArrayOldest == FreedBlockArrayMaxSize) + FreedBlockArrayOldest = 0; + } else { + pBlockPtr = AllocCommittedPageMemory( + blockSize); // Allocate a new block of one or more pages (via VirtualAlloc). + } + + if (pBlockPtr) { + void* pUserPtr = GetUserPosition(pBlockPtr, blockSize, size, align); + size_t* pSizePos = GetSizePosition(pUserPtr); + + pSizePos[UserSizeIndex] = size; + pSizePos[BlockSizeIndex] = blockSize; + AllocationCount++; + + return pUserPtr; + } + + return nullptr; +#else + OVR_ASSERT_AND_UNUSED(align <= DefaultAlignment, align); + return DebugPageHeap::Alloc(size); +#endif +} + +size_t DebugPageHeap::GetUserSize(const void* p) { +#if defined(_WIN32) + return GetSizePosition(p)[UserSizeIndex]; +#elif defined(__APPLE__) + return malloc_size(p); +#else + return malloc_usable_size(const_cast(p)); +#endif +} + +size_t DebugPageHeap::GetBlockSize(const void* p) { +#if defined(_WIN32) + return GetSizePosition(p)[BlockSizeIndex]; +#else + OVR_UNUSED(p); + return 0; +#endif +} + +size_t* DebugPageHeap::GetSizePosition(const void* p) { + // No thread safety required as per our design, as we assume that anybody + // who owns a pointer returned by Alloc cannot have another thread take it away. + + // We assume the pointer is a valid pointer allocated by this allocator. + // We store some size values into the memory returned to the user, a few bytes before it. + size_t value = reinterpret_cast(p); + size_t valuePos = (value - SizeStorageSize); + size_t* pSize = reinterpret_cast(valuePos); + + return pSize; +} + +void* DebugPageHeap::Realloc(void* p, size_t newSize) { +#if defined(_WIN32) + return ReallocAligned(p, newSize, DefaultAlignment); +#else + return realloc(p, newSize); +#endif +} + +void* DebugPageHeap::ReallocAligned(void* p, size_t newSize, size_t newAlign) { +#if defined(_WIN32) + // The ISO C99 standard states: + // The realloc function deallocates the old object pointed to by ptr and + // returns a pointer to a new object that has the size specified by size. + // The contents of the new object shall be the same as that of the old + // object prior to deallocation, up to the lesser of the new and old sizes. + // Any bytes in the new object beyond the size of the old object have + // indeterminate values. + // + // If ptr is a null pointer, the realloc function behaves like the malloc + // function for the specified size. Otherwise, if ptr does not match a + // pointer earlier returned by the calloc, malloc, or realloc function, + // or if the space has been deallocated by a call to the free or realloc + // function, the behavior is undefined. If memory for the new object + // cannot be allocated, the old object is not deallocated and its value + // is unchanged. + // + // The realloc function returns a pointer to the new object (which may have + // the same value as a pointer to the old object), or a null pointer if + // the new object could not be allocated. + + // A mutex lock isn't required, as the functions below will handle it internally. + // But having it here is a little more efficient because it woudl otherwise be + // locked and unlocked multiple times below, with possible context switches in between. + Lock::Locker autoLock(&Lock); + + void* pReturn = nullptr; + + if (p) { + if (newSize) { + pReturn = AllocAligned(newSize, newAlign); + + if (pReturn) { + size_t prevSize = GetUserSize(p); + + if (newSize > prevSize) + newSize = prevSize; + + memcpy(pReturn, p, newSize); + Free(p); + } // Else fall through, leaving p's memory unmodified and returning nullptr. + } else { + Free(p); + } + } else if (newSize) { + pReturn = AllocAligned(newSize, newAlign); + } + + return pReturn; +#else + OVR_ASSERT_AND_UNUSED(newAlign <= DefaultAlignment, newAlign); + return DebugPageHeap::Realloc(p, newSize); +#endif +} + +void DebugPageHeap::Free(void* p) { +#if defined(_WIN32) + if (p) { + // Creating a scope for the lock + { + Lock::Locker autoLock(&Lock); + + if (FreedBlockArrayMaxSize) // If we have a delayed free list... + { + // We don't free the page(s) associated with this but rather put them in the FreedBlockArray + // in an inaccessible state for later freeing. We do this because we don't want those pages + // to be available again in the near future, so we can detect use-after-free misakes. + Block* pBlockNew; + + if (FreedBlockArraySize == FreedBlockArrayMaxSize) // If we have reached freed block + // capacity... we can start purging old + // elements from it as a circular queue. + { + pBlockNew = &FreedBlockArray[FreedBlockArrayOldest]; + + // The oldest element in the container is FreedBlockArrayOldest. + if (pBlockNew->BlockPtr) // Currently this should always be true. + { + FreePageMemory(pBlockNew->BlockPtr, pBlockNew->BlockSize); + pBlockNew->Clear(); + } + + if (++FreedBlockArrayOldest == FreedBlockArrayMaxSize) + FreedBlockArrayOldest = 0; + } else // Else we are still building the container and not yet treating it a circular. + { + pBlockNew = &FreedBlockArray[FreedBlockArraySize++]; + } + + pBlockNew->BlockPtr = GetBlockPtr(p); + pBlockNew->BlockSize = GetBlockSize(p); + +#if defined(OVR_BUILD_DEBUG) + if (OverrunGuardBytesEnabled) // If we have extra bytes at the end of the user's allocation + // between it and an inaccessible guard page... + { + const size_t userSize = GetUserSize(p); + const uint8_t* pUserEnd = (static_cast(p) + userSize); + const uint8_t* pPageEnd = AlignPointerUp(pUserEnd, PageSize); + + while (pUserEnd != pPageEnd) { + if (*pUserEnd++ != GuardFillByte) { + OVR_FAIL(); + break; + } + } + } +#endif + + DisablePageMemory(pBlockNew->BlockPtr, pBlockNew->BlockSize); // Make it so that future + // attempts to use this memory + // result in an exception. + } else { + FreePageMemory(GetBlockPtr(p), GetBlockSize(p)); + } + + AllocationCount--; + } + } +#else + return free(p); +#endif +} + +void DebugPageHeap::FreeAligned(void* p) { + return Free(p); +} + +// Converts a user pointer to the beginning of its page. +void* DebugPageHeap::GetBlockPtr(void* p) { + // We store size info before p in memory, and this will, by design, be always somewhere within + // the first page of a block of pages. So just align down to the beginning of its page. + return AlignPointerDown(GetSizePosition(p), PageSize); +} + +void* DebugPageHeap::GetUserPosition( + void* pPageMemory, + size_t blockSize, + size_t userSize, + size_t userAlignment) { + uint8_t* pUserPosition; + + if (OverrunPageEnabled) { + // We need to return the highest position within the page memory that fits the user size while + // being aligned to userAlignment. + const size_t pageEnd = reinterpret_cast(pPageMemory) + + (blockSize - PageSize); // pageEnd points to the beginning of the final guard page. + const size_t userPosition = AlignSizeDown(pageEnd - userSize, userAlignment); + pUserPosition = reinterpret_cast(userPosition); + OVR_ASSERT((userPosition + userSize) <= pageEnd); + +// If userSize is not a multiple of userAlignment then there will be (userAlignment - userSize) +// bytes of unused memory between the user allocated space and the end of the page. There is no way +// around having this. For example, a user allocation of 3 bytes with 8 byte alignment will leave 5 +// unused bytes at the end of the page. We optionally fill those unused bytes with a pattern and +// upon Free verify that the pattern is undisturbed. This won't detect reads or writes in that area +// immediately as with reads or writes beyond that, but it will at least detect them at some point +// (e.g. upon Free). +#if defined(OVR_BUILD_DEBUG) + if (OverrunGuardBytesEnabled) { + uint8_t* const pUserEnd = (pUserPosition + userSize); + const size_t remainingByteCount = (reinterpret_cast(pageEnd) - pUserEnd); + if (remainingByteCount) // If there are any left-over bytes... + memset(pUserEnd, GuardFillByte, remainingByteCount); + } +#endif + } else { + // We need to return the first position in the first page after SizeStorageSize bytes which is + // aligned to userAlignment. + const size_t lowestPossiblePos = reinterpret_cast(pPageMemory) + SizeStorageSize; + const size_t userPosition = AlignSizeUp(lowestPossiblePos, userAlignment); + pUserPosition = reinterpret_cast(userPosition); + OVR_ASSERT((userPosition + userSize) <= (reinterpret_cast(pPageMemory) + blockSize)); + } + + // Assert that the returned user pointer (actually the size info before it) will be within the + // first page. This is important because it verifieds that we haven't wasted memory and because + // our functionality for telling the start of the page block depends on it. + OVR_ASSERT(AlignPointerDown(GetSizePosition(pUserPosition), PageSize) == pPageMemory); + + return pUserPosition; +} + +void* DebugPageHeap::AllocCommittedPageMemory(size_t blockSize) { +#if defined(_WIN32) + void* p; + + if (OverrunPageEnabled) { + // We need to make it so that last page is MEM_RESERVE and the previous pages are MEM_COMMIT + + // PAGE_READWRITE. + OVR_ASSERT(blockSize > PageSize); // There should always be at least one extra page. + + // Reserve blockSize amount of pages. + // We could possibly use PAGE_GUARD here for the last page. This differs from simply leaving it + // reserved because the OS will generate a one-time-only gaurd page exception. We probabl don't + // want this, as it's more useful for maintaining your own stack than for catching unintended + // overruns. + p = VirtualAlloc(nullptr, blockSize, MEM_RESERVE, PAGE_READWRITE); + + if (p) { + // Commit all but the last page. Leave the last page as merely reserved so that reads from or + // writes to it result in an immediate exception. + p = VirtualAlloc(p, blockSize - PageSize, MEM_COMMIT, PAGE_READWRITE); + } + } else { + // We need to make it so that all pages are MEM_COMMIT + PAGE_READWRITE. + p = VirtualAlloc(nullptr, blockSize, MEM_COMMIT, PAGE_READWRITE); + } + +#if defined(OVR_BUILD_DEBUG) + if (!p) { + // To consider: Make a generic OVRKernel function for formatting system errors. We could move + // the OVRError GetSysErrorCodeString from LibOVR/OVRError.h to LibOVRKernel/OVR_DebugHelp.h + DWORD dwLastError = GetLastError(); + WCHAR osError[256]; + DWORD osErrorBufferCapacity = OVR_ARRAY_COUNT(osError); + CHAR reportedError[384]; + DWORD length = FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + (DWORD)dwLastError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + osError, + osErrorBufferCapacity, + nullptr); + + if (length) { + std::string errorBuff = UCSStringToUTF8String(osError, length + 1); + snprintf( + reportedError, + OVR_ARRAY_COUNT(reportedError), + "DebugPageHeap: VirtualAlloc failed with error: %s", + errorBuff.c_str()); + } else { + snprintf( + reportedError, + OVR_ARRAY_COUNT(reportedError), + "DebugPageHeap: VirtualAlloc failed with error: %d.", + (int)dwLastError); + } + + // LogError("%s", reportedError); Disabled because this call turns around and allocates memory, + // yet we may be in a broken or exhausted memory situation. + OVR_FAIL_M(reportedError); + } +#endif + + return p; +#else + OVR_UNUSED2(blockSize, OverrunPageEnabled); + return nullptr; +#endif +} + +// We convert disabled page memory (see DisablePageMemory) to enabled page memory. The output is the +// same as with AllocPageMemory. +void* DebugPageHeap::EnablePageMemory(void* pPageMemory, size_t blockSize) { +#if defined(_WIN32) + // Make sure the entire range of memory is of type PAGE_READWRITE. + DWORD dwPrevAccess = 0; + BOOL result = VirtualProtect( + pPageMemory, + OverrunPageEnabled ? (blockSize - PageSize) : blockSize, + PAGE_READWRITE, + &dwPrevAccess); + OVR_ASSERT_AND_UNUSED(result, result); +#else + OVR_UNUSED3(pPageMemory, blockSize, OverrunPageEnabled); +#endif + + return pPageMemory; +} + +void DebugPageHeap::DisablePageMemory(void* pPageMemory, size_t blockSize) { +#if defined(_WIN32) + // Disable access to the page(s). It's faster for us to change the page access than it is to + // decommit or free the pages. However, this results in more committed physical memory usage than + // we would need if we instead decommitted the memory. + DWORD dwPrevAccesss = 0; + BOOL result = VirtualProtect( + pPageMemory, + OverrunPageEnabled ? (blockSize - PageSize) : blockSize, + PAGE_NOACCESS, + &dwPrevAccesss); + OVR_ASSERT_AND_UNUSED(result, result); +#else + OVR_UNUSED2(pPageMemory, blockSize); +#endif +} + +void DebugPageHeap::FreePageMemory(void* pPageMemory, size_t /*blockSize*/) { +#if defined(_WIN32) + BOOL result = VirtualFree(pPageMemory, 0, MEM_RELEASE); + OVR_ASSERT_AND_UNUSED(result, result); +#else + OVR_UNUSED(pPageMemory); +#endif +} + +//------------------------------------------------------------------------ +// ***** Allocator debug commands +// +//------------------------------------------------------------------------ + +// AllocatorTraceDbgCmd +const char* allocatorTraceDbgCmdName = "Allocator.Trace"; +const char* allocatorTraceDbgCmdUsage = " [filter specification]"; +const char* allocatorTraceDbgCmdDesc = + "Triggers the logging of the default allocator heap, with an optional filter."; +const char* allocatorTraceDbgCmdDoc = + "Triggers the logging of the default allocator heap, with an optional filter.\n" + "The filter is a string which accepts a set of comparisons expressed in postfix (RPN).\n" + "Stack traces will be symbolized if the symbol files are present; otherwise they will be missing.\n" + "The ability to trace heaps can be enabled in release builds by setting the appropriate\n" + "registry key before starting OVRServer:\n" + " HKEY_LOCAL_MACHINE\\SOFTWARE\\Oculus\\HeapTrackingEnabled, REG_DWORD of 0 or 1.\n" + "The enabling of the debug page heap can be enabled in release builds by setting:\n" + " HKEY_LOCAL_MACHINE\\SOFTWARE\\Oculus\\DebugPageHeapEnabled, REG_DWORD of 0 or 1.\n" + "Allocation tracking and tracing will have more results if malloc tracking is enabled.\n" + " HKEY_LOCAL_MACHINE\\SOFTWARE\\Oculus\\MallocRedirectEnabled, REG_DWORD of 0 or 1.\n" + "Use Allocator.ReportState to tell what the current settings are.\n" + "\n" + "Example usage:\n" + " Allocator.Trace C:\\temp\\trace.txt Trace the entire heap\n" + " Allocator.Trace C:\\temp\\trace.txt \"size > 1024\" Trace only allocations > 1024 bytes\n" + " Allocator.Trace C:\\temp\\trace.txt \"size > 1024; size < 2048; and\" Trace allocations between 1024 and 2048\n" + " Allocator.Trace C:\\temp\\trace.txt \"time > -10s\" Trace allocations done in the last 10 seconds\n" + " Allocator.Trace C:\\temp\\trace.txt \"time > 50000\" Trace allocations done in the first 50000 nanoseconds\n" + " Allocator.Trace C:\\temp\\trace.txt \"tag == geometry\" Trace only allocations tagged as geometry\n" + " Allocator.Trace C:\\temp\\trace.txt \"ThreadName has vision\" Trace only allocations from threads with \"vision\" in the name\n"; +int AllocatorTraceDbgCmd(const std::vector& args, std::string* output) { + OVR_DISABLE_MSVC_WARNING(4996) // 4996: This function or variable may be unsafe. + + OVR::Allocator* allocator = OVR::Allocator::GetInstance(false); + if (allocator) { + std::stringstream strStream; + + if (!allocator->IsTrackingEnabled()) { + output->append( + "Allocator tracking is not enabled. To enable, use the Allocator.EnableTracking command or set the DWORD HKEY_LOCAL_MACHINE\\SOFTWARE\\Oculus\\HeapTrackingEnabled reg key before starting the application."); + return -1; // Exit because even if tracking was enabled at some point earlier, all records + // would have been cleared with it was disabled. + } + + if (args.size() < 2) { + output->append( + "Filepath first argument is required but was not supplied. See example usage."); + return -1; + } + + std::string filePath = args[1]; + FILE* file; + +#if defined(_WIN32) + errno_t err = 0; + err = fopen_s(&file, filePath.c_str(), "w"); +#else + file = fopen(filePath.c_str(), "w"); + int err = file ? 0 : -1; +#endif + + if (err || !file) { + strStream << "Failed to open " << filePath; + *output = strStream.str(); + return -1; + } + + struct Context { + FILE* file; + uint64_t allocationCount; + } context = {file, 0}; + + OVR::HeapIterationFilterRPN::TraceTrackedAllocations( + allocator, + (args.size() >= 3) ? args[2].c_str() : "", + [](uintptr_t contextStruct, const char* text) -> void { + Context* pContext = reinterpret_cast(contextStruct); + pContext->allocationCount++; + fwrite(text, 1, strlen(text), pContext->file); + fwrite("\n\n", 1, 2, pContext->file); + }, + (uintptr_t)&context); + strStream << context.allocationCount << " allocations reported to " << filePath; + + std::string str = strStream.str(); + output->append(str.data(), str.length()); // We don't directly assign string objects because + // currently we are crossing a DLL boundary between + // these two strings. + + fclose(file); + return 0; + } + + output->append("Allocator not found."); + return -1; + + OVR_RESTORE_MSVC_WARNING() +} + +// AllocatorEnableTrackingDbgCmd +const char* allocatorEnableTrackingDbgCmdName = "Allocator.EnableTracking"; +const char* allocatorEnableTrackingDbgCmdUsage = "(no arguments)"; +const char* allocatorEnableTrackingDbgCmdDesc = "Enables heap tracking."; +const char* allocatorEnableTrackingDbgCmdDoc = + "Enables heap tracking, in any build. This allows for heap tracing (e.g. Allocator.Trace cmd)\n" + "Has no effect and reports success if there is no change.\n" + "Debug builds by default already have tracking enabled. Use Allocator.ReportState to tell.\n" + "Currently the enabling of tracking results in the recording only allocations made after tracking is started.\n" + "Example usage:\n" + " Allocator.EnableTracking\n" + " ... (wait for some time)\n" + " Allocator.Trace C:\\temp\\trace.txt\n"; + +int AllocatorEnableTrackingDbgCmd(const std::vector&, std::string* output) { + OVR::Allocator* allocator = OVR::Allocator::GetInstance(false); + if (allocator) { + if (allocator->EnableTracking(true)) + output->append("Allocator tracking enabled."); + else + output->append( + "Allocator tracking couldn't be enabled due to an allocator settings conflict."); + } else + output->append("Allocator not found."); + + return (allocator ? 0 : -1); +} + +// AllocatorDisableTrackingDbgCmd +const char* allocatorDisableTrackingDbgCmdName = "Allocator.DisableTracking"; +const char* allocatorDisableTrackingDbgCmdUsage = "(no arguments)"; +const char* allocatorDisableTrackingDbgCmdDesc = "Disables heap tracking."; +const char* allocatorDisableTrackingDbgCmdDoc = + "Disables heap tracking, in any build.\n" + "Has no effect and reports success if there is no change.\n" + "Example usage:\n" + " Allocator.DisableTracking\n"; +int AllocatorDisableTrackingDbgCmd(const std::vector&, std::string* output) { + OVR::Allocator* allocator = OVR::Allocator::GetInstance(false); + + if (allocator) { + if (allocator->EnableTracking(false)) + output->append("Allocator tracking disabled."); + else + output->append( + "Allocator tracking couldn't be disabled due to an allocator settings conflict."); + } else + output->append("Allocator not found."); + + return (allocator ? 0 : -1); +} + +// AllocatorReportStateDbgCmd +const char* allocatorReportStateDbgCmdName = "Allocator.ReportState"; +const char* allocatorReportStateDbgCmdUsage = "(no arguments)"; +const char* allocatorReportStateDbgCmdDesc = + "Reports the general state and settings of the global Allocator."; +const char* allocatorReportStateDbgCmdDoc = + "Reports the general state and settings of the global Allocator.\n" + "Example usage:\n" + " Allocator.ReportState\n"; +int AllocatorReportStateDbgCmd(const std::vector&, std::string* output) { + OVR::Allocator* allocator = OVR::Allocator::GetInstance(false); + + if (allocator) { + bool trackingEnabled = allocator->IsTrackingEnabled(); + bool debugPageHeapEnabled = allocator->IsDebugPageHeapEnabled(); + bool osHeapEnabled = allocator->IsOSHeapEnabled(); + bool mallocRedirectEnabled = allocator->IsMallocRedirectEnabled(); + bool traceOnShutdownEnabled = allocator->IsAllocationTraceOnShutdownEnabled(); + uint64_t heapTimeNs = allocator->GetCurrentHeapTimeNs(); + uint64_t heapCounter = allocator->GetCounter(); + uint64_t heapTrackedCount = 0; + uint64_t heapTrackedVolume = 0; + + // We could report more detail that the following if desired. The following blocks the heap + // briefly for other threads. + for (const OVR::AllocMetadata* amd = allocator->IterateHeapBegin(); amd; + amd = allocator->IterateHeapNext()) { + heapTrackedCount++; + heapTrackedVolume += amd->BlockSize; + } + allocator->IterateHeapEnd(); +#if defined(_DLL) + const char* crtName = "DLL CRT"; +#else + const char* crtName = "static CRT"; +#endif + +#if defined(_DEBUG) + const char* buildName = "debug build"; +#else + const char* buildName = "release build"; +#endif + + std::stringstream strStream; + + strStream << "Memory tracking: " << (trackingEnabled ? "enabled." : "disabled.") << std::endl; + strStream << "Underlying heap: " + << (debugPageHeapEnabled ? "debug page heap." + : (osHeapEnabled ? "os heap." : "malloc-based heap.")) + << std::endl; + strStream << "malloc redirection: " << (mallocRedirectEnabled ? "" : "not ") << "enabled." + << std::endl; + strStream << "Shutdown trace: " << (traceOnShutdownEnabled ? "" : "not ") << "enabled." + << std::endl; + strStream << "Heap time (ns): " << heapTimeNs << std::endl; + strStream << "Heap counter: " << heapCounter << std::endl; + strStream << "Heap allocated count: " << heapTrackedCount << std::endl; + strStream << "Heap allocated volume: " << heapTrackedVolume << std::endl; + strStream << "CRT type: " << crtName << std::endl; + strStream << "Build type: " << buildName << std::endl; + + std::string str = strStream.str(); + output->append(str.data(), str.length()); // We don't directly assign string objects because + // currently we are crossing a DLL boundary between + // these two strings. + } else + output->append("Allocator not found."); + + return (allocator ? 0 : -1); +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Allocator.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Allocator.h new file mode 100644 index 0000000..91fc142 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Allocator.h @@ -0,0 +1,1453 @@ +/************************************************************************************ + +Filename : OVR_Allocator.h +Content : Installable memory allocator +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Allocator_h +#define OVR_Allocator_h + +#include "OVR_Atomic.h" +#include "OVR_Std.h" +#include "OVR_Types.h" +#include "stdint.h" +#include "stdlib.h" + +OVR_DISABLE_ALL_MSVC_WARNINGS() +#include +#include +#include +#include +#include +#include +#include +#include +OVR_RESTORE_ALL_MSVC_WARNINGS() +#if defined(_WIN32) +#include "OVR_Win32_IncludeWindows.h" +#endif + +//----------------------------------------------------------------------------------- +// ***** Disable template-unfriendly MS VC++ warnings +// +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4503) // Pragma to prevent long name warnings in VC++ +#pragma warning(disable : 4786) +#pragma warning(disable : 4345) // In MSVC 7.1, warning about placement new POD default initializer +#pragma warning(disable : 4351) // new behavior: elements of array will be default initialized +#endif + +// Un-define new so that placement new works +#undef new + +//------------------------------------------------------------------------ +// ***** Macros to redefine class new/delete operators +// +// Types specifically declared to allow disambiguation of address in +// class member operator new. This is intended to be used with a +// macro like OVR_CHECK_DELETE(class_name, p) in the example below. +// +// Example usage: +// class Widget +// { +// public: +// Widget(); +// +// #ifdef OVR_BUILD_DEBUG +// #define OVR_MEMORY_CHECK_DELETE(class_name, p) \ +// do { if (p) checkInvalidDelete((class_name*)p); } while(0) +// #else +// #define OVR_MEMORY_CHECK_DELETE(class_name, p) +// #endif +// +// OVR_MEMORY_REDEFINE_NEW_IMPL(Widget, OVR_MEMORY_CHECK_DELETE) +// }; +// + +#define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete) \ + void* operator new(size_t sz) { \ + void* p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); \ + if (!p) \ + throw OVR::bad_alloc(); \ + return p; \ + } \ + \ + void* operator new(size_t sz, const char* file, int line) { \ + OVR_UNUSED2(file, line); \ + void* p = OVR_ALLOC_DEBUG(sz, file, line); \ + if (!p) \ + throw OVR::bad_alloc(); \ + return p; \ + } \ + \ + void operator delete(void* p) { \ + if (p) { \ + check_delete(class_name, p); \ + OVR_FREE(p); \ + } \ + } \ + \ + void operator delete(void* p, const char*, int) { \ + if (p) { \ + check_delete(class_name, p); \ + OVR_FREE(p); \ + } \ + } + +// Used by OVR_MEMORY_REDEFINE_NEW +#define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p) + +// Redefine 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 { + +// Our thread identifier type. May not be identical to OVR::ThreadId from OVR_Threads.h +#if defined(_WIN32) +typedef uint32_t AllocatorThreadId; // Same as DWORD +#else +typedef uintptr_t AllocatorThreadId; // Same as void* +#endif + +// We subclass std::bad_alloc for the purpose of overriding the 'what' function +// to provide additional information about the exception, such as context about +// how or where the exception occurred in our code. We subclass std::bad_alloc +// instead of creating a new type because it's intended to override std::bad_alloc +// and be caught by code that uses catch(std::bad_alloc&){}. Also, the std::bad_alloc +// constructor actually attempts to allocate memory! + +struct bad_alloc : public std::bad_alloc { + bad_alloc(const char* description = "OVR::bad_alloc") OVR_NOEXCEPT; + + bad_alloc(const bad_alloc& oba) OVR_NOEXCEPT { + OVR_strlcpy(Description, oba.Description, sizeof(Description)); + } + + bad_alloc& operator=(const bad_alloc& oba) OVR_NOEXCEPT { + OVR_strlcpy(Description, oba.Description, sizeof(Description)); + return *this; + } + + virtual const char* what() const OVR_NOEXCEPT { + return Description; + } + + char Description[256]; // Fixed size because we cannot allocate memory. +}; + +//----------------------------------------------------------------------------------- +// ***** Construct / Destruct + +// Construct/Destruct functions are useful when new is redefined, as they can +// be called instead of placement new constructors. + +template +OVR_FORCE_INLINE T* Construct(void* p) { + return ::new (p) T(); +} + +template +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 +OVR_FORCE_INLINE T* ConstructAlt(void* p, const S& source) { + return ::new (p) T(source); +} + +template +OVR_FORCE_INLINE T* ConstructAlt(void* p, const S1& src1, const S2& src2) { + return ::new (p) T(src1, src2); +} + +// Note: These ConstructArray functions don't properly support the case of a C++ exception occurring +// midway during construction, as they don't deconstruct the successfully constructed array elements +// before returning. +template +OVR_FORCE_INLINE void ConstructArray(void* p, size_t count) { + uint8_t* pdata = (uint8_t*)p; + for (size_t i = 0; i < count; ++i, pdata += sizeof(T)) { + Construct(pdata); + } +} + +template +OVR_FORCE_INLINE void ConstructArray(void* p, size_t count, const T& source) { + uint8_t* pdata = (uint8_t*)p; + for (size_t i = 0; i < count; ++i, pdata += sizeof(T)) { + Construct(pdata, source); + } +} + +template +OVR_FORCE_INLINE void Destruct(T* pobj) { + pobj->~T(); + OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning. +} + +template +OVR_FORCE_INLINE void DestructArray(T* pobj, size_t count) { + for (size_t i = 0; i < count; ++i, ++pobj) + pobj->~T(); +} + +//----------------------------------------------------------------------------------- +// ***** SysMemAlloc / SysMemFree +// +// System memory allocation functions. Cannot use the C runtime library. Must be able +// to execute before the C runtime library has initialized or after it has shut down. +// +void* SysMemAlloc(size_t n); +void SysMemFree(void* p, size_t n); + +//----------------------------------------------------------------------------------- +// ***** StdAllocatorSysMem +// +// Defines a C++ std allocator, suitable for using with C++ containers. +// This version by design uses system memory APIs instead of C++ memory APIs. +// +// Example usage: +// using namespace std; +// typedef vector> IntArray; +// typedef basic_string, StdAllocatorSysMem> CharString; +// typedef list> IntList; +// typedef map, StdAllocatorSysMem> IntMap; +// typedef multimap, StdAllocatorSysMem> IntMultiMap; +// typedef set, StdAllocatorSysMem> IntSet; +// typedef multiset, StdAllocatorSysMem> IntMultiSet; +// typedef unordered_map, equal_to, StdAllocatorSysMem> +// IntHashMap; +// typedef unordered_multimap, equal_to, StdAllocatorSysMem> +// IntHashMultiMap; +// typedef unordered_set, equal_to, StdAllocatorSysMem> IntHashSet; +// typedef unordered_multiset, equal_to, StdAllocatorSysMem> +// IntHashMultiSet; +// typedef deque> IntDequeue; +// typedef queue> > IntQueue; +// +template +class StdAllocatorSysMem { + public: + typedef StdAllocatorSysMem this_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef void* void_pointer; + typedef const void* const_void_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef std::false_type propagate_on_container_copy_assignment; + typedef std::false_type propagate_on_container_move_assignment; + typedef std::false_type propagate_on_container_swap; + + this_type select_on_container_copy_construction() const { + return *this; + } + + template + struct rebind { + typedef StdAllocatorSysMem other; + }; + + pointer address(reference ref) const { + return std::addressof(ref); + } + + const_pointer address(const_reference ref) const { + return std::addressof(ref); + } + + StdAllocatorSysMem() {} + + StdAllocatorSysMem(const this_type&) {} + + template + StdAllocatorSysMem(const StdAllocatorSysMem&) {} + + template + this_type& operator=(const StdAllocatorSysMem&) { + return *this; + } + + bool operator==(const this_type&) const { + return true; + } + + bool operator!=(const this_type&) const { + return false; + } + + void deallocate(pointer p, size_type n) const { + if (p) + SysMemFree(p, n); + } + + pointer allocate(size_type n) const { + void* pVoid = SysMemAlloc(n * sizeof(T)); + if (!pVoid) + throw ::std::bad_alloc(); + return (pointer)pVoid; + } + + pointer allocate(size_type n, const void*) const { + return allocate(n); + } + + void construct(T* p) const { + ::new ((void*)p) T(); + } + + void construct(T* p, const T& value) const { + ::new ((void*)p) T(value); + } + + template + void construct(U* pU, Types&&... args) const { + ::new ((void*)pU) U(std::forward(args)...); + } + + template + void destroy(U* pU) const { + pU->~U(); + OVR_UNUSED(pU); // VC++ mistakenly claims it's unused unless we do this. + } + + size_t max_size() const { + return ((size_t)(-1) / sizeof(T)); + } +}; + +//------------------------------------------------------------------------ +// ***** Heap +// +// Declares a minimal interface for a memory heap. +// Implementations of this Heap interface are expected to handle thread safety +// themselves. +// +class Heap { + public: + virtual ~Heap() {} + + virtual bool Init() = 0; + virtual void Shutdown() = 0; + + virtual void* Alloc(size_t size) = 0; + virtual void* AllocAligned(size_t size, size_t align) = 0; + virtual size_t GetAllocSize(const void* p) const = 0; + virtual size_t GetAllocAlignedSize(const void* p, size_t align) const = 0; + virtual void Free(void* p) = 0; + virtual void FreeAligned(void* p) = 0; + virtual void* Realloc(void* p, size_t newSize) = 0; + virtual void* ReallocAligned(void* p, size_t newSize, size_t newAlign) = 0; +}; + +class InterceptCRTMalloc; + +//------------------------------------------------------------------------ +// ***** SysAllocatedPointerVector, etc. +// +// We use these in our allocator functionality here. +// +typedef std::vector> SysAllocatedPointerVector; +typedef std::basic_string, StdAllocatorSysMem> + SysAllocatedString; +typedef std::vector> + SysAllocatedStringVector; + +//----------------------------------------------------------------------------------- +// ***** AllocMetadata +// +// Stores info about an allocation. +// +struct AllocMetadata { + const void* Alloc; // The allocation itself. + SysAllocatedPointerVector Backtrace; // Array of void* + SysAllocatedStringVector BacktraceSymbols; // Array of string. + const char* File; // __FILE__ of application allocation site. + int Line; // __LINE__ of application allocation site. + uint64_t TimeNs; // Allocator time in Nanoseconds. See GetCurrentHeapTimeNs. + uint64_t Count; // Nth allocation in this heap. Ever increasing. Starts with 0, so the first + // allocation is the 0th allocation. + uint64_t AllocSize; // Size the user requested. + uint64_t BlockSize; // Size that was actually needed from the underlying memory. + const char* Tag; // Should this instead be a char array? + AllocatorThreadId ThreadId; // ThreadId at the time of the allocation. May potentially be stale if + // the thread has exited. + char ThreadName[32]; // Thread name at the time of the allocation. + + AllocMetadata() + : Alloc(nullptr), + Backtrace(), + File(nullptr), + Line(0), + TimeNs(0), + Count(0), + AllocSize(0), + BlockSize(0), + Tag(nullptr), + ThreadId(0) { + ThreadName[0] = '\0'; + } +}; + +// This is used to identify fields from AllocMetadata. For example, when printing out +// AllocMetadata you can use these flags to specify which fields you are interested in. +enum AllocMetadataFlags { + AMFNone = 0x0000, + AMFAlloc = 0x0001, + AMFBacktrace = 0x0002, + AMFBacktraceSymbols = 0x0004, + AMFFile = 0x0008, + AMFLine = 0x0010, + AMFTime = 0x0020, + AMFCount = 0x0040, + AMFAllocSize = 0x0080, + AMFBlockSize = 0x0100, + AMFTag = 0x0200, + AMFThreadId = 0x0400, + AMFThreadName = 0x0800 +}; + +//----------------------------------------------------------------------------------- +// ***** Allocator +// +class Allocator { + public: + // Returns the pointer to the default Allocator instance. + // This pointer is used for most of the memory allocations. + // If the instance is not yet created, this function isn't thread safe + // about creating it. + static Allocator* GetInstance(bool create = true); + + // Explicitly destroys the default Allocator instance. + static void DestroyInstance(); + + public: + Allocator(const char* allocatorName = nullptr); + ~Allocator(); + + bool Init(); + void Shutdown(); + + // 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. + void* Alloc(size_t size, const char* tag); + + // Allocate zero-initialized memory of specified count and size with default alignment. + // Alloc of size==0 will allocate a tiny block & return a valid pointer; + // this makes it suitable for new operator. + void* Calloc(size_t count, size_t size, const char* tag); + + // Allocate memory of specified alignment. + // Memory allocated with AllocAligned MUST be freed with FreeAligned. + void* AllocAligned(size_t size, size_t align, const char* tag); + + // Same as Alloc, but provides an option of passing file/line data. + void* AllocDebug(size_t size, const char* tag, const char* file, unsigned line); + + // Same as Calloc, but provides an option of passing file/line data. + void* CallocDebug(size_t count, size_t size, const char* tag, const char* file, unsigned line); + + // Same as Alloc, but provides an option of passing file/line data. + void* + AllocAlignedDebug(size_t size, size_t align, const char* tag, const char* file, unsigned line); + + // Returns the size of the allocation. + size_t GetAllocSize(const void* p) const; + + // Returns the size of the aligned allocation. + size_t GetAllocAlignedSize(const void* p, size_t align) const; + + // Frees memory allocated by Alloc/Realloc. + // Free of null pointer is valid and will do nothing. + void Free(void* p); + + // Frees memory allocated with AllocAligned. + void FreeAligned(void* p); + + // 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 (as per the C99 Standard). + // Realloc to decrease size will never fail. + // Realloc of pointer == NULL is equivalent to Alloc + // Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free. + void* Realloc(void* p, size_t newSize); + + // Like realloc but also zero-initializes the newly added space. + void* Recalloc(void* p, size_t count, size_t size); + + // Reallocates memory allocated with AllocAligned. + void* ReallocAligned(void* p, size_t newSize, size_t newAlign); + + void* RecallocAligned(void* p, size_t count, size_t newSize, size_t newAlign); + + // Same as Realloc, but provides an option of passing file/line data. + void* ReallocDebug(void* p, size_t newSize, const char* file, unsigned line); + + // Like ReallocDebug but also zero-initializes the newly added space. + void* RecallocDebug(void* p, size_t count, size_t newSize, const char* file, unsigned line); + + // Same as ReallocAligned, but provides an option of passing file/line data. + void* + ReallocAlignedDebug(void* p, size_t newSize, size_t newAlign, const char* file, unsigned line); + + void* RecallocAlignedDebug( + void* p, + size_t count, + size_t newSize, + size_t newAlign, + const char* file, + unsigned line); + + // Returns the underlying Heap implementation. + const Heap* GetHeap() const { + return Heap; + } + + public: + // Names the Allocator. Useful for identifying one of multiple Allocators within a process. + // The name is copied from the allocatorName argument. + void SetAllocatorName(const char* allocatorName); + + const char* GetAllocatorName() const; + + // If enabled then allocation tracking is done, which enables leak reports, double-free detection, + // etc. Must be called before the Init function. + bool EnableTracking(bool enable); + + bool IsTrackingEnabled() const { + return TrackingEnabled; + } + + // If enabled then the debug page is used. + // Must be called before the Init function. + bool EnableDebugPageHeap(bool enable); + + bool IsDebugPageHeapEnabled() const { + return DebugPageHeapEnabled; + } + + bool IsOSHeapEnabled() const { + return OSHeapEnabled; + } + + // If enabled then a debug trace of existing allocations occurs on destruction of this Allocator. + bool EnableAllocationTraceOnShutdown(bool enable) { + TraceAllocationsOnShutdown = enable; + return true; + } + + bool IsAllocationTraceOnShutdownEnabled() const { + return TraceAllocationsOnShutdown; + } + + bool EnableMallocRedirect(); + + bool IsMallocRedirectEnabled() const { + return MallocRedirectEnabled; + } + + static bool IsHeapTrackingRegKeyEnabled(bool defaultValue); + + // IterateHeapBegin succeeds only if tracking is enabled. + // Once IterateHeapBegin is called, the heap is thread-locked until IterateHeapEnd is called. + // If the heap has no allocations, IterateHeapBegin returns nullptr. + // You must always call IterateHeapEnd if you call IterateHeapBegin, regardless of the return + // value of IterateHeapBegin. For a given thread, IterataHeapBegin must be followed by + // IterateHeapEnd before any new call to IterateHeapBegin. + // + // Example usage: + // for(const OVR::AllocMetadata* amd = allocator->IterateHeapBegin(); amd; amd = + // allocator->IterateHeapNext()) + // { ... } + // allocator->IterateHeapEnd(); + const AllocMetadata* IterateHeapBegin(); + const AllocMetadata* IterateHeapNext(); + void IterateHeapEnd(); + + // Given an AllocationMetaData, this function writes it to a string description. + // For amdFlags, see AllocMetadataFlags. + // Returns the required strlen of the description (like the strlcpy function, etc.) + size_t DescribeAllocation( + const AllocMetadata* amd, + int amdFlags, + char* description, + size_t descriptionCapacity, + size_t appendedNewlineCount); + + // Displays information about outstanding allocations, typically for the + // purpose of reporting leaked memory on application or module shutdown. + // This should be used instead of, for example, VC++ _CrtDumpMemoryLeaks + // because it allows us to dump additional information about our allocations. + // Returns the number of currently outstanding heap allocations. + // If the callback is valid, this function iteratively calls the callback with + // output. If the callback is nullptr then this function debug-traces the output. + // The callback context is an arbitrary user-supplied value. + // + // Example usage: + // void AllocationTraceCallback(uintptr_t context, const char* text) + // { printf("%s", text); } + // allocator->TraceTrackedAllocations(AllocationTraceCallback, 0); + // + typedef void (*AllocationTraceCallback)(uintptr_t context, const char* text); + size_t TraceTrackedAllocations(AllocationTraceCallback callback, uintptr_t context); + + public: + // Returns the current heap time in nanoseconds. The returned time is with respect + // to first heap startup, which in practice equates to the application start time. + static uint64_t GetCurrentHeapTimeNs(); + + // Returns the allocation counter, which indicates the historical count of calls + // to allocation functions. This is an ever-increasing number and not the count + // of outstanding allocations. To get the count of outstanding allocations, use the + // heap iteration functionality. + uint64_t GetCounter() const { + return CurrentCounter; + } + + uint64_t GetAndUpdateCounter() { + return CurrentCounter++; + } // Post-increment here is by design. + + protected: + void SetNewBlockMetadata( + Allocator* allocator, + AllocMetadata& amd, + const void* alloc, + uint64_t allocSize, + uint64_t blockSize, + const char* file, + int line, + const char* tag, + void** backtraceArray, + size_t backtraceArraySize); + + // Add the allocation & the callstack to the tracking database. + void TrackAlloc(const void* p, size_t size, const char* tag, const char* file, int line); + + // Remove the allocation from the tracking database (if tracking is enabled). + // Returns true if p appears to be valid or if tracking is disabled. + // Returns false for NULL and for values not found in our tracking map. + bool UntrackAlloc(const void* p); + + // Returns true if the allocation is being tracked. + // Returns true if p appears to be valid or if tracking is disabled. + // Returns false for NULL and for values not found in our tracking map. + bool IsAllocTracked(const void* p); + + // Returns a copy of the AllocMetadata. + bool GetAllocMetadata(const void* p, AllocMetadata& metadata); + + public: + // Tag push/pop API + + // Every PushTag must be matched by a PopTag. It's easiest to do this via the AllocatorTagScope + // utility class. + void PushTag(const char* tag); + + // Matches a PushTag. + void PopTag(); + + // Gets the current tag for the current thread. + // Returns a default string if there is no current tag set for the current thread. + const char* GetTag(const char* defaultTag = nullptr); + + protected: + // This is called periodically to purge the map of elements that correspond to threads that no + // longer exist. + void PurgeTagMap(); + + protected: +// Tracked allocations +#if defined(OVR_BUILD_DEBUG) + typedef std::map< + const void*, + AllocMetadata, + std::less, // map is slower but in debug builds we can read its sorted contents + // easier. + StdAllocatorSysMem>> + TrackedAllocMap; +#else + typedef std::unordered_map< + const void*, + AllocMetadata, + std::hash, + std::equal_to, + StdAllocatorSysMem>> + TrackedAllocMap; +#endif + + // Per-thread tag stack + typedef std::vector> ConstCharVector; +#if defined(OVR_BUILD_DEBUG) + typedef std::map< + AllocatorThreadId, + ConstCharVector, + std::less, + StdAllocatorSysMem>> + ThreadIdToTagVectorMap; +#else + typedef std::unordered_map< + AllocatorThreadId, + ConstCharVector, + std::hash, + std::equal_to, + StdAllocatorSysMem>> + ThreadIdToTagVectorMap; +#endif + + char AllocatorName[64]; // The name of this allocator. Useful because we could have multiple + // instances within a process. + Heap* Heap; // The underlying heap we are using. + bool DebugPageHeapEnabled; // If enabled then we use our DebugPageHeap instead of DefaultHeap or + // OSheap. + bool OSHeapEnabled; // If enabled then we use our OSHeap instead of DebugPageHeap or DefaultHeap. + bool MallocRedirectEnabled; // If enabled then we redirect CRT malloc to ourself (only if we are + // the default global allocator). + InterceptCRTMalloc* MallocRedirect; // + bool TrackingEnabled; // + bool TraceAllocationsOnShutdown; // If true then we do a debug trace of allocations on our + // shutdown. + OVR::Lock TrackLock; // Thread-exclusive access to AllocationMap. + TrackedAllocMap::const_iterator + TrackIterator; // Valid only between IterateHeapBegin and IterateHeapEnd. + TrackedAllocMap AllocationMap; // + SysAllocatedPointerVector DelayedFreeList; // Used when we are overriding CRT malloc and need to + // call CRT free on some pointers after we've restored + // it. + SysAllocatedPointerVector DelayedAlignedFreeList; // " + std::atomic_ullong CurrentCounter; // Ever-increasing count of allocation requests. + bool SymbolLookupEnabled; // + ThreadIdToTagVectorMap TagMap; // + OVR::Lock TagMapLock; // Thread-exclusive access to TagMap. + static Allocator* DefaultAllocator; // Default instance. + static uint64_t ReferenceHeapTimeNs; // The time that GetCurrentHeapTimeNs reports relative to. In + // practice this is the time of application startup. + + public: + // The following functions are deprecated and will be removed in the future. Use the member + // functions instead. + static void SetLeakTracking(bool enabled) { + GetInstance()->EnableTracking(enabled); + } + + static bool IsTrackingLeaks() { + return GetInstance()->IsTrackingEnabled(); + } + + static int DumpMemory() { + return (int)GetInstance()->TraceTrackedAllocations(nullptr, 0); + } +}; + +// This allows for providing an intelligent filter for heap iteration. +// It provides an RPN (a.k.a. postfix) language for executing a filter of ORs and ANDs. +// We have this RPN language because implementing a string parsing system +// is currently outside the complexity scope of this module. An RPN scheme +// can be implemented in just 100 lines or code or so. +// +// An RPN language works by having a list of instructions which cause pushes +// and pops of data on a stack. In our case the stack consists only of bools. +// We want to evaluate expressions such as the following: +// (Size > 10) +// (Size > 10) && (Size < 32) +// ((Size > 10) && (Size < 32)) || (Time > 100) +// ((Size > 10) && (Size < 32)) || ((Time > 100) && (Time < 200)) +// +// The user specifies the instructions via newline-delimited strings. Here are +// examples for each of the above. +// Example 1: +// (Size > 10) +// -> +// "Size > 10" Push the result of this on the stack. +// +// Example 2: +// (Size > 10) && (Size < 32) +// -> +// "Size > 10\n Push the result of this on the stack. +// Size < 32\n Push the result of this on the stack. +// and" Pop the two (AllocSize results), push the result the the AND of +// the two. +// +// Example 3: +// ((Size > 10) && (Size < 32)) || (Time > 100) +// -> +// "Size > 10\n Push the result of this on the stack. +// Size < 32\n Push the result of this on the stack. +// and\n Pop the two (AllocSize results), push the result the the AND of +// the two. Time > 100s\n Push the result of this on the stack. or" +// Pop the two (AllocSize AND result and Time result), push the result of the OR of the two. +// +// Example 4: +// ((Size > 10) && (Size < 32)) || ((Time > 100) && (Time < 200)) +// -> +// "Size > 10\n Push the result of this on the stack. +// Size < 32\n Push the result of this on the stack. +// and\n Pop the two (AllocSize results), push the result the the AND of +// the two. Time > 100s\n Push the result of this on the stack. Time < 200s\n +// Push the result of this on the stack. and\n Pop the two (Time +// results), push the result the the AND of the two. or" Pop the two +// (AllocSize AND result and Time AND result), push the result of the OR of the two. +// +// The operands available and their forms are: +// Operand Compare Comparand Notes +// ------------------------------------------------------------------------ +// File ==,has case-insensitive. has means +// substring check. Line ==,<,<=,>,>= Time +// ==,<,<=,>,>= [s] time in nanoseconds (or seconds if followed by s). A +// negative time means relative to now. Count ==,<,<=,>,>= +// A negative count means to return the last nth allocation(s). AllocSize (or just Size) +// ==,<,<=,>,>= BlockSize ==,<,<=,>,>= Tag +// ==,has case insensitive. has means substring check. ThreadId +// ==,<,<=,>,>= <,<=,>,>= are usually useless but provided for consistency +// with other integer types. ThreadName ==,has case +// insensitive. has means substring check. +// +struct HeapIterationFilterRPN { + HeapIterationFilterRPN(); + + bool SetFilter(Allocator* allocator, const char* filter); + + // This is the same as Allocator::IterateHeapBegin, except it returns only + // values that match the filter specification. + const AllocMetadata* IterateHeapBegin(); + const AllocMetadata* IterateHeapNext(); + void IterateHeapEnd(); + + // This is a one-shot filtered tracing function. + // Example usage: + // auto printfCallback = [](uintptr_t, const char* text)->void{ printf("%s\n", text); }; + // HeapIterationFilterRPN::TraceTrackedAllocations(&allocator, "Count < 400", printfCallback, + // 0); + static void TraceTrackedAllocations( + Allocator* allocator, + const char* filter, + Allocator::AllocationTraceCallback callback, + uintptr_t context); + + protected: + enum Operation { OpNone, OpAnd, OpOr }; + enum Comparison { CmpNone, CmpE, CmpL, CmpLE, CmpG, CmpGE, CmpHas }; + + struct Operand { + AllocMetadataFlags metadataType; // e.g. AMFAllocSize + Comparison comparison; // e.g. CmpLE + int64_t numValue; // Applies to numeric AllocMetadataFlags types. + char strValue[256]; // Applies to string AllocMetadataFlags types. + + Operand() : metadataType(AMFNone), comparison(CmpNone), numValue(0), strValue{} {} + }; + + // An instruction is either an operation or an operand. We could use a union to represent + // that but it would complicate our declarations here. Instead we declare both types one + // after the other. If the operation type is none, then this entry is an operand instead + // of an operation. + struct Instruction { + Operation operation; + Operand operand; + }; + + bool Compile(const char* filter); // Returns false upon syntax error. + bool Evaluate(const AllocMetadata* amd); // Returns true if amd matches the filter. + bool EvaluateOperand(const Operand& operand, const AllocMetadata* amd) const; + + protected: + Allocator* AllocatorInstance; // The Allocator we execute the filter against. + const char* Filter; // The string-based filter gets converted into the Instructions, which can be + // executed per alloc. + Instruction Instructions[32]; // Array of instructions to execute. 0-terminated. + uint64_t CurrentHeapTimeNs; // The time at the start of evaluation. Used for time comparisons. +}; + +//------------------------------------------------------------------------ +// ***** DefaultHeap +// +// Delegates to malloc. +// This heap is created and used if no other heap is installed. +// +class DefaultHeap : public Heap { + public: + virtual bool Init(); + virtual void Shutdown(); + + virtual void* Alloc(size_t size); + virtual void* AllocAligned(size_t size, size_t align); + virtual size_t GetAllocSize(const void* p) const; + virtual size_t GetAllocAlignedSize(const void* p, size_t align) const; + virtual void Free(void* p); + virtual void FreeAligned(void* p); + virtual void* Realloc(void* p, size_t newSize); + virtual void* ReallocAligned(void* p, size_t newSize, size_t newAlign); +}; + +//------------------------------------------------------------------------ +// ***** OSHeap +// +// Delegates to OS heap functions instead of malloc/free/new/delete. +// +class OSHeap : public Heap { + public: + OSHeap(); + ~OSHeap(); + + virtual bool Init(); + virtual void Shutdown(); + + virtual void* Alloc(size_t size); + virtual void* AllocAligned(size_t size, size_t align); + virtual size_t GetAllocSize(const void* p) const; + virtual size_t GetAllocAlignedSize(const void* p, size_t align) const; + virtual void Free(void* p); + virtual void FreeAligned(void* p); + virtual void* Realloc(void* p, size_t newSize); + virtual void* ReallocAligned(void* p, size_t newSize, size_t newAlign); + + protected: +#if defined(_WIN32) + HANDLE Heap; // Windows heap handle. +#else + void* Heap; +#endif +}; + +//------------------------------------------------------------------------ +// ***** DebugPageHeap +// +// Implements a page-protected heap: +// Detects use-after-free and memory overrun bugs immediately at the time of usage via an +// exception. Can detect a memory read or write beyond the valid memory immediately at the +// time of usage via an exception (if EnableOverrunDetection is enabled). +// This doesn't replace valgrind but implements a subset of its functionality +// in a way that performs well enough to avoid interfering with app execution. +// The point of this is that immediately detects these two classes of errors while +// being much faster than external tools such as valgrind, etc. This is at a cost of +// as much as a page of extra bytes per allocation (two if EnableOverrunDetection is enabled). +// On Windows the Alloc and Free functions average about 12000 cycles each. This isn't small but +// it should be low enough for many testing circumstances with apps that are prudent with +// memory allocation volume. +// The amount of system memory needed for this isn't as high as one might initially guess, as it +// takes hundreds of thousands of memory allocations in order to make a dent in the gigabytes +// of memory most computers have. +// +// +// Technical design for the Windows platform: +// Every Alloc is satisfied via a VirtualAlloc return of a memory block of one or more pages; +// the minimum needed to satisy the user's size and alignment requirements. +// Upon Free the memory block (which is one or more pages) is not passed to VirtualFree but rather +// is converted to PAGE_NOACCESS and put into a delayed free list (FreedBlockArray) to be +// passed to VirtualFree later. The result of this is that any further attempts to read or +// write the memory will result in an exception. +// The delayed-free list increases each time Free is called until it reached maximum capacity, +// at which point the oldest memory block in the list is passed to VirtualFree and its +// entry in the list is filled with this newly Freed (PAGE_NOACCESS) memory block. +// Once the delayed-free list reaches maximum capacity it thus acts as a ring buffer of blocks. +// The maximum size of this list is currently determined at compile time as a constant. +// The EnableOverrunDetection is an additional feature which allows reads or writes beyond valid +// memory to be detected as they occur. This is implemented by adding an allocating an +// additional page of memory at the end of the usual pages and leaving it uncommitted +// (MEM_RESERVE). When this option is used, we return a pointer to the user that's at the end +// of the valid memory block as opposed to at the beginning. This is so that the space right +// after the user space is invalid. If there are some odd bytes remaining between the end of +// the user's space and the page (due to alignment requirements), we optionally fill these +// with guard bytes. We do not currently support memory underrun detection, which could be +// implemented via an extra un-accessible page before the user page(s). In practice this is +// rarely needed. +// Currently the choice to use EnableOverrunDetection must be done before any calls to Alloc, etc. +// as the logic is simpler and faster if we don't have to dynamically handle either case at +// runtime. +// We store within the memory block the size of the block and the size of the original user Alloc +// request. This is done as two size_t values written before the memory returned to the user. +// Thus the pointer returned to the user will never be at the very beginning of the memory +// block, because there will be two size_t's before it. +// This class itself allocates no memory, as that could interfere with its ability to supply +// memory, especially if the global malloc and new functions are replaced with this class. +// We could in fact support this class allocating memory as long as it used a system allocator +// and not malloc, new, etc. +// As of this writing we don't do debug fill patterns in the returned memory, because we mostly +// don't need it because memory exceptions take the place of unexpected fill value validation. +// However, there is some value in doing a small debug fill of the last few bytes after the +// user's bytes but before the next page, which will happen for odd sizes passed to Alloc. +// +// Technical design for Mac and Linux platforms: +// Apple's XCode malloc functionality includes something called MallocGuardEdges which is similar +// to DebugPageHeap, though it protects only larger sized allocations and not smaller ones. +// Our approach for this on Mac and Linux is to use mmap and mprotect in a way similar to +// VirtualAlloc and +// VirtualProtect. Unix doesn't have the concept of Windows MEM_RESERVE vs. MEM_COMMIT, but we +// can simulate MEM_RESERVE by having an extra page that's PROT_NONE instead of MEM_RESERVE. +// Since Unix platforms don't commit pages pages to physical memory until they are first +// accessed, this extra page will in practice act similar to Windows MEM_RESERVE at runtime. +// +// Allocation inteface: +// Alloc sizes can be any size_t >= 0. +// An alloc size of 0 returns a non-nullptr. +// Alloc functions may fail (usually due to insufficent memory), in which case they return +// nullptr. All returned allocations are aligned on a power-of-two boundary of at least +// DebugPageHeap::DefaultAlignment. AllocAligned supports any alignment power-of-two value from 1 +// to 256. Other values result in undefined behavior. AllocAligned may return a pointer that's +// aligned greater than the requested alignment. Realloc acts as per the C99 Standard realloc. +// Free requires the supplied pointer to be a valid pointer returned by this allocator's Alloc +// functions, else the behavior is undefined. You may not Free a pointer a second time, else the +// behavior is undefined. Free otherwise always succeeds. Allocations made with AllocAligned or +// ReallocAligned must be Freed via FreeAligned, as per the base class requirement. +// + +class DebugPageHeap : public Heap { + public: + DebugPageHeap(); + virtual ~DebugPageHeap(); + + bool Init(); + void Shutdown(); + + void SetMaxDelayedFreeCount(size_t delayedFreeCount); // Sets how many freed blocks we should save + // before purging the oldest of them. + size_t GetMaxDelayedFreeCount() const; // Returns the max number of delayed free allocations + // before the oldest ones are purged (finally freed). + void EnableOverrunDetection( + bool enableOverrunDetection, + bool enableOverrunGuardBytes); // enableOverrunDetection is by default. + // enableOverrunGuardBytes is enabled by default in debug + // builds. + + void* Alloc(size_t size); + void* AllocAligned(size_t size, size_t align); + size_t GetAllocSize(const void* p) const { + return GetUserSize(p); + } + size_t GetAllocAlignedSize(const void* p, size_t /*align*/) const { + return GetUserSize(p); + } + void* Realloc(void* p, size_t newSize); + void* ReallocAligned(void* p, size_t newSize, size_t newAlign); + void Free(void* p); + void FreeAligned(void* p); + size_t GetPageSize() const { + return PageSize; + } + + protected: + struct Block { + void* BlockPtr; // The pointer to the first page of the contiguous set of pages that make up + // this block. + size_t BlockSize; // (page size) * (page count). Will be >= (SizeStorageSize + UserSize). + + void Clear() { + BlockPtr = nullptr; + BlockSize = 0; + } + }; + + Block* FreedBlockArray; // Currently a very simple array-like container that acts as a ring buffer + // of delay-freed (but inaccessible) blocks. + size_t FreedBlockArrayMaxSize; // The max number of Freed blocks to put into FreedBlockArray + // before they start getting purged. Must be <= + // kFreedBlockArrayCapacity. + size_t FreedBlockArraySize; // The amount of valid elements within FreedBlockArray. Increases as + // elements are added until it reaches kFreedBlockArrayCapacity. Then + // stays that way until Shutdown. + size_t FreedBlockArrayOldest; // The oldest entry in the FreedBlockArray ring buffer. + size_t AllocationCount; // Number of currently live Allocations. Incremented by successful calls + // to Alloc (etc.) Decremented by successful calss to Free. + bool OverrunPageEnabled; // If true then we implement memory overrun detection, at the cost of an + // extra page per user allocation. + bool OverrunGuardBytesEnabled; // If true then any remaining bytes between the end of the user's + // allocation and the end of the page are filled with guard bytes + // and verified upon Free. Valid only if OverrunPageEnabled is + // true. + size_t PageSize; // The current default platform memory page size (e.g. 4096). We allocated blocks + // in multiples of pages. + OVR::Lock Lock; // Mutex which allows an instance of this class to be used by multiple threads + // simultaneously. + + public: +#if defined(_WIN64) || defined(_M_IA64) || defined(__LP64__) || defined(__LP64__) || \ + defined(__arch64__) || defined(__APPLE__) + static const size_t DefaultAlignment = 16; // 64 bit platforms and all Apple platforms. +#else + static const size_t DefaultAlignment = 8; // 32 bit platforms. We want DefaultAlignment as low as +// possible because that means less unused bytes between +// a user allocation and the end of the page. +#endif +#if defined(_WIN32) + static const size_t MaxAlignment = 2048; // Half a page size. +#else + static const size_t MaxAlignment = DefaultAlignment; // Currently a low limit because we don't +// have full page allocator support yet. +#endif + + protected: + static const size_t SizeStorageSize = DefaultAlignment; // Where the user size and block size is + // stored. Needs to be at least 2 * + // sizeof(size_t). + static const size_t UserSizeIndex = + 0; // We store block sizes within the memory itself, and this serves to identify it. + static const size_t BlockSizeIndex = 1; + static const uint8_t GuardFillByte = 0xfd; // Same value VC++ uses for heap guard bytes. + + static size_t GetUserSize( + const void* p); // Returns the size that the user requested in Alloc, etc. + static size_t GetBlockSize(const void* p); // Returns the actual number of bytes in the returned + // block. Will be a multiple of PageSize. + static size_t* GetSizePosition(const void* p); // We store the user and block size as two size_t + // values within the returned memory to the user, + // before the user pointer. This gets that + // location. + + void* GetBlockPtr(void* p); + void* GetUserPosition(void* pPageMemory, size_t blockSize, size_t userSize, size_t userAlignment); + void* AllocCommittedPageMemory(size_t blockSize); + void* EnablePageMemory(void* pPageMemory, size_t blockSize); + void DisablePageMemory(void* pPageMemory, size_t blockSize); + void FreePageMemory(void* pPageMemory, size_t blockSize); +}; + +///------------------------------------------------------------------------ +/// ***** AllocatorTagScope +/// +/// Implements automated setting of a current tag for an allocator. +/// This allows for easier tagging of memory by subsystem usage. +/// +/// Example usage: +/// void Geometry::GenerateGeometry() +/// { +/// AllocatorTagScope tagScope("geometry"); // Registers a tag with the default allocator. +/// Will unregister it at function exit. +/// +/// Indices.push_back(1234); // The allocation that results from each of these +/// MemberPtr = OVR_ALLOC(1234); // calls will be tagged with "geometry". +/// } +/// +class AllocatorTagScope { + public: + AllocatorTagScope(const char* tag = nullptr, Allocator* allocator = nullptr) { + Tag = tag; + + if (!allocator) + allocator = Allocator::GetInstance(false); + + Allocator = allocator; + + if (Allocator) + Allocator->PushTag(tag); + } + + ~AllocatorTagScope() { + if (Allocator) + Allocator->PopTag(); + } + + const char* GetTag() const { + return Tag; + } + + protected: + const char* Tag; + Allocator* Allocator; +}; + +// AllocatorTraceDbgCmd +// +// This is a debug command that lets you dump a heap trace into a file, with a given filter +// specification. +// +extern const char* allocatorTraceDbgCmdName; +extern const char* allocatorTraceDbgCmdUsage; +extern const char* allocatorTraceDbgCmdDesc; +extern const char* allocatorTraceDbgCmdDoc; +extern int AllocatorTraceDbgCmd(const std::vector& args, std::string* output); + +// AllocatorEnableTrackingDbgCmd +// +// This is a debug command that lets you enable tracing in the Allocator. +// +extern const char* allocatorEnableTrackingDbgCmdName; +extern const char* allocatorEnableTrackingDbgCmdUsage; +extern const char* allocatorEnableTrackingDbgCmdDesc; +extern const char* allocatorEnableTrackingDbgCmdDoc; +extern int AllocatorEnableTrackingDbgCmd(const std::vector&, std::string* output); + +// AllocatorDisableTrackingDbgCmd +// +// This is a debug command that lets you disable tracing in the Allocator. +// +extern const char* allocatorDisableTrackingDbgCmdName; +extern const char* allocatorDisableTrackingDbgCmdUsage; +extern const char* allocatorDisableTrackingDbgCmdDesc; +extern const char* allocatorDisableTrackingDbgCmdDoc; +extern int AllocatorDisableTrackingDbgCmd(const std::vector&, std::string* output); + +// AllocatorReportStateDbgCmd +// +// This is a debug command that lets you report the current general state of the default allocator. +// +extern const char* allocatorReportStateDbgCmdName; +extern const char* allocatorReportStateDbgCmdUsage; +extern const char* allocatorReportStateDbgCmdDesc; +extern const char* allocatorReportStateDbgCmdDoc; +extern int AllocatorReportStateDbgCmd(const std::vector&, std::string* output); + +///------------------------------------------------------------------------ +/// ***** OVR_malloca / OVR_freea +/// +/// Implements a safer version of alloca. However, see notes below. +/// +/// Allocates memory from the stack via alloca (or similar) for smaller +/// allocation sizes, else falls back to operator new. This is very similar +/// to the Microsoft _malloca and _freea functions, and the implementation +/// is nearly the same aside from using operator new instead of malloc. +/// +/// Unlike alloca, calls to OVR_malloca must be matched by calls to OVR_freea, +/// and the OVR_freea call must be in the same function scope as the original +/// call to OVR_malloca. +/// +/// Note: +/// While this function reduces the likelihood of a stack overflow exception, +/// it cannot guarantee it, as even small allocation sizes done by alloca +/// can exhaust the stack when it is nearly full. However, the majority of +/// stack overflows due to alloca usage are due to large allocation size +/// requests. +/// +/// Declarations: +/// void* OVR_malloca(size_t size); +/// void OVR_freea(void* p); +/// +/// Example usage: +/// void TestMalloca() +/// { +/// char* charArray = (char*)OVR_malloca(37000); +/// +/// if(charArray) +/// { +/// // +/// OVR_freea(charArray); +/// } +/// } +/// +#if !defined(OVR_malloca) +#define OVR_MALLOCA_ALLOCA_ID UINT32_C(0xcccccccc) +#define OVR_MALLOCA_MALLOC_ID UINT32_C(0xdddddddd) +#define OVR_MALLOCA_ID_SIZE \ + 16 // Needs to be at least 2 * sizeof(uint32_t) and at least the minimum alignment for malloc on +// the platform. 16 works for all platforms. +#if defined(_MSC_VER) +#define OVR_MALLOCA_SIZE_THRESHOLD 8192 +#else +#define OVR_MALLOCA_SIZE_THRESHOLD \ + 1024 // Non-Microsoft platforms tend to exhaust stack space sooner due to non-automatic stack +// expansion. +#endif + +#define OVR_malloca(size) \ + ((((size) + OVR_MALLOCA_ID_SIZE) < OVR_MALLOCA_SIZE_THRESHOLD) \ + ? OVR::malloca_SetId( \ + static_cast(alloca((size) + OVR_MALLOCA_ID_SIZE)), OVR_MALLOCA_ALLOCA_ID) \ + : OVR::malloca_SetId( \ + static_cast(new char[(size) + OVR_MALLOCA_ID_SIZE]), OVR_MALLOCA_MALLOC_ID)) + +inline void* malloca_SetId(char* p, uint32_t id) { + if (p) { + *reinterpret_cast(p) = id; + p = reinterpret_cast(p) + OVR_MALLOCA_ID_SIZE; + } + + return p; +} +#endif + +#if !defined(OVR_freea) +#define OVR_freea(p) OVR::freea_Impl(reinterpret_cast(p)) + +inline void freea_Impl(char* p) { + if (p) { + // We store the allocation type id at the first uint32_t in the returned memory. + static_assert( + OVR_MALLOCA_ID_SIZE >= sizeof(uint32_t), "Insufficient OVR_MALLOCA_ID_SIZE size."); + p -= OVR_MALLOCA_ID_SIZE; + uint32_t id = *reinterpret_cast(p); + + if (id == OVR_MALLOCA_MALLOC_ID) + delete[] p; +#if defined(OVR_BUILD_DEBUG) + else if (id != OVR_MALLOCA_ALLOCA_ID) + OVR_FAIL_M("OVR_freea memory corrupt or not allocated by OVR_alloca."); +#endif + } +} +#endif + +///------------------------------------------------------------------------ +/// ***** OVR_newa / OVR_deletea +/// +/// Implements a C++ array version of OVR_malloca/OVR_freea. +/// Expresses failure via a nullptr return value and not via a C++ exception. +/// If a handled C++ exception occurs midway during construction in OVR_newa, +/// there is no automatic destruction of the successfully constructed elements. +/// +/// Declarations: +/// T* OVR_newa(T, size_t count); +/// void OVR_deletea(T, T* pTArray); +/// +/// Example usage: +/// void TestNewa() +/// { +/// Widget* pWidgetArray = OVR_newa(Widget, 37000); +/// +/// if(pWidgetArray) +/// { +/// // +/// OVR_deletea(Widget, pWidgetArray); +/// } +/// } +/// +#if !defined(OVR_newa) +#define OVR_newa(T, count) \ + OVR::newa_Impl(static_cast(OVR_malloca(count * sizeof(T))), count) +#endif + +template +T* newa_Impl(char* pTArray, size_t count) { + if (pTArray) { + OVR::ConstructArray(pTArray, count); + + // We store the count at the second uint32_t in the returned memory. + static_assert( + OVR_MALLOCA_ID_SIZE >= (2 * sizeof(uint32_t)), "Insufficient OVR_MALLOCA_ID_SIZE size."); + reinterpret_cast((reinterpret_cast(pTArray) - OVR_MALLOCA_ID_SIZE))[1] = + (uint32_t)count; + } + return reinterpret_cast(pTArray); +} + +#if !defined(OVR_deletea) +#define OVR_deletea(T, pTArray) OVR::deletea_Impl(pTArray) +#endif + +template +void deletea_Impl(T* pTArray) { + if (pTArray) { + uint32_t count = + reinterpret_cast((reinterpret_cast(pTArray) - OVR_MALLOCA_ID_SIZE))[1]; + OVR::DestructArray(pTArray, count); + OVR_freea(pTArray); + } +} + +//------------------------------------------------------------------------ +// ***** OVR_DEBUG_HEAP_FILE_LINE_ENABLED +// +// Defined as 0 or 1. +// This is controlled by a #define because if we always compiled this code +// then release builds would have lots of file names in the binaries. +// +#ifndef OVR_DEBUG_HEAP_FILE_LINE_ENABLED +#if defined(OVR_BUILD_DEBUG) +#define OVR_DEBUG_HEAP_FILE_LINE_ENABLED 1 +#else +#define OVR_DEBUG_HEAP_FILE_LINE_ENABLED 0 +#endif +#endif + +//------------------------------------------------------------------------ +// ***** 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, size) OVR::Allocator::GetInstance()->Realloc((p), (size)) +#define OVR_FREE(p) OVR::Allocator::GetInstance()->Free((p)) +#define OVR_FREE_ALIGNED(p) OVR::Allocator::GetInstance()->FreeAligned((p)) + +#if OVR_DEBUG_HEAP_FILE_LINE_ENABLED +#define OVR_ALLOC_TAGGED(size, tag) \ + OVR::Allocator::GetInstance()->AllocDebug((size), (tag), __FILE__, __LINE__) +#define OVR_ALLOC(size) \ + OVR::Allocator::GetInstance()->AllocDebug((size), nullptr, __FILE__, __LINE__) +#define OVR_ALLOC_ALIGNED_TAGGED(size, align, tag) \ + OVR::Allocator::GetInstance()->AllocAlignedDebug((size), (align), (tag), __FILE__, __LINE__) +#define OVR_ALLOC_ALIGNED(size, align) \ + OVR::Allocator::GetInstance()->AllocAlignedDebug((size), (align), nullptr, __FILE__, __LINE__) +#define OVR_ALLOC_DEBUG(size, file, line) \ + OVR::Allocator::GetInstance()->AllocDebug((size), nullptr, (file), (line)) +#define OVR_ALLOC_DEBUG_TAGGED(size, tag, file, line) \ + OVR::Allocator::GetInstance()->AllocDebug((size), (tag), (file), (line)) +#else +#define OVR_ALLOC_TAGGED(size, tag) OVR::Allocator::GetInstance()->Alloc((size), (tag)) +#define OVR_ALLOC(size) OVR::Allocator::GetInstance()->Alloc((size), nullptr) +#define OVR_ALLOC_ALIGNED_TAGGED(size, align, tag) \ + OVR::Allocator::GetInstance()->AllocAligned((size), (align), (tag)) +#define OVR_ALLOC_ALIGNED(size, align) \ + OVR::Allocator::GetInstance()->AllocAligned((size), (align), nullptr) +#define OVR_ALLOC_DEBUG(size, file, line) OVR::Allocator::GetInstance()->Alloc((size), nullptr) +#define OVR_ALLOC_DEBUG_TAGGED(size, tag, file, line) \ + OVR::Allocator::GetInstance()->Alloc((size), (tag)) +#endif + +//------------------------------------------------------------------------ +// ***** NewOverrideBase +// +// 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) +}; + +//------------------------------------------------------------------------ +// ***** Mapped memory allocation +// +// Equates to VirtualAlloc/VirtualFree on Windows, mmap/munmap on Unix. +// These are useful for when you need system-supplied memory pages. +// These are also useful for when you need to allocate memory in a way +// that doesn't affect the application heap. + +void* SafeMMapAlloc(size_t size); +void SafeMMapFree(const void* memory, size_t size); + +} // namespace OVR + +//------------------------------------------------------------------------ +// ***** OVR_DEFINE_NEW +// +// Redefine operator 'new' if necessary. +// This allows us to remap all usage of new to something different. +// +#if defined(OVR_DEFINE_NEW) +#define new OVR_DEFINE_NEW +#endif + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#endif // OVR_Allocator_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Array.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Array.h new file mode 100644 index 0000000..997fc7c --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Array.h @@ -0,0 +1,854 @@ +/************************************************************************************ + +Filename : OVR_Array.h +Content : Template implementation for Array +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#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) {} + + size_t GetMinCapacity() const { + return 0; + } + size_t GetGranularity() const { + return 4; + } + bool NeverShrinking() const { + return 1; + } + + size_t GetCapacity() const { + return Capacity; + } + void SetCapacity(size_t capacity) { + Capacity = capacity; + } + + private: + size_t Capacity; +}; + +//----------------------------------------------------------------------------------- +// ***** ArrayConstPolicy +// +// Statically parametrized resizing behavior: +// MinCapacity, Granularity, and Shrinking flag. +template +struct ArrayConstPolicy { + typedef ArrayConstPolicy SelfType; + + ArrayConstPolicy() : Capacity(0) {} + ArrayConstPolicy(const SelfType&) : Capacity(0) {} + + size_t GetMinCapacity() const { + return MinCapacity; + } + size_t GetGranularity() const { + return Granularity; + } + bool NeverShrinking() const { + return NeverShrink; + } + + size_t GetCapacity() const { + return Capacity; + } + void SetCapacity(size_t capacity) { + Capacity = capacity; + } + + private: + size_t Capacity; +}; + +//----------------------------------------------------------------------------------- +// ***** ArrayDataBase +// +// Basic operations with array data: Reserve, Resize, Free, ArrayPolicy. +// For internal use only: ArrayData,ArrayDataCC and others. +template +struct ArrayDataBase { + typedef T ValueType; + typedef Allocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayDataBase SelfType; + + ArrayDataBase() : Data(0), Size(0), Policy() {} + + ArrayDataBase(const SizePolicy& p) : Data(0), Size(0), Policy(p) {} + + ~ArrayDataBase() { + if (Data) { + Allocator::DestructArray(Data, Size); + Allocator::Free(Data); + } + } + + size_t GetCapacity() const { + return Policy.GetCapacity(); + } + + void ClearAndRelease() { + if (Data) { + Allocator::DestructArray(Data, Size); + Allocator::Free(Data); + Data = 0; + } + Size = 0; + Policy.SetCapacity(0); + } + + void Reserve(size_t 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 { + size_t 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); + size_t 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(size_t newSize) { + size_t 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; + size_t Size; + SizePolicy Policy; +}; + +//----------------------------------------------------------------------------------- +// ***** ArrayData +// +// General purpose array data. +// For internal use only in Array, ArrayLH, ArrayPOD and so on. +template +struct ArrayData : ArrayDataBase { + typedef T ValueType; + typedef Allocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayDataBase BaseType; + typedef ArrayData SelfType; + + ArrayData() : BaseType() {} + + ArrayData(size_t size) : BaseType() { + Resize(size); + } + + ArrayData(const SelfType& a) : BaseType(a.Policy) { + Append(a.Data, a.Size); + } + + void Resize(size_t newSize) { + size_t 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); + OVR_ASSERT(this->Data != NULL); + Allocator::Construct(this->Data + this->Size - 1, val); + } + + template + 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[], size_t count) { + if (count) { + size_t 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 +struct ArrayDataCC : ArrayDataBase { + typedef T ValueType; + typedef Allocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayDataBase BaseType; + typedef ArrayDataCC SelfType; + + ArrayDataCC(const ValueType& defval) : BaseType(), DefaultValue(defval) {} + + ArrayDataCC(const ValueType& defval, size_t size) : BaseType(), DefaultValue(defval) { + Resize(size); + } + + ArrayDataCC(const SelfType& a) : BaseType(a.Policy), DefaultValue(a.DefaultValue) { + Append(a.Data, a.Size); + } + + void Resize(size_t newSize) { + size_t 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 + 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[], size_t count) { + if (count) { + size_t 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 ArrayBase { + public: + typedef typename ArrayData::ValueType ValueType; + typedef typename ArrayData::AllocatorType AllocatorType; + typedef typename ArrayData::SizePolicyType SizePolicyType; + typedef ArrayBase 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(size_t size) : Data(size) {} + ArrayBase(const SelfType& a) : Data(a.Data) {} + + ArrayBase(const ValueType& defval) : Data(defval) {} + ArrayBase(const ValueType& defval, size_t 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(); + } + size_t GetSize() const { + return Data.Size; + } + int GetSizeI() const { + return (int)Data.Size; + } + bool IsEmpty() const { + return Data.Size == 0; + } + size_t GetCapacity() const { + return Data.GetCapacity(); + } + size_t GetNumBytes() const { + return Data.GetCapacity() * sizeof(ValueType); + } + + void ClearAndRelease() { + Data.ClearAndRelease(); + } + void Clear() { + Data.Resize(0); + } + void Resize(size_t newSize) { + Data.Resize(newSize); + } + + // Reserve can only increase the capacity + void Reserve(size_t newCapacity) { + if (newCapacity > Data.GetCapacity()) + Data.Reserve(newCapacity); + } + + // Basic access. + ValueType& At(size_t index) { + OVR_ASSERT( + (Data.Data) && + (index < Data.Size)); // Asserting that Data.Data is valid helps static analysis tools. + return Data.Data[index]; + } + const ValueType& At(size_t index) const { + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; + } + + ValueType ValueAt(size_t index) const { + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; + } + + // Basic access. + ValueType& operator[](size_t index) { + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; + } + const ValueType& operator[](size_t index) const { + OVR_ASSERT((Data.Data) && (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 + void PushBackAlt(const S& val) { + Data.PushBackAlt(val); + } + + // Remove the last element. + void PopBack(size_t count = 1) { + OVR_ASSERT(Data.Size >= count); + Data.Resize(Data.Size - count); + } + + ValueType& PushDefault() { + Data.PushBack(ValueType()); + return Back(); + } + + ValueType Pop() { + OVR_ASSERT((Data.Data) && (Data.Size > 0)); + 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()); + OVR_ASSERT((Data.Data != NULL) || (Data.Size == 0)); + for (size_t i = 0; i < Data.Size; i++) { + *(Data.Data + i) = a[i]; + } + return *this; + } + + // Removing multiple elements from the array. + void RemoveMultipleAt(size_t index, size_t 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. + // If order of elements in the array is not important then use + // RemoveAtUnordered, that could be much faster than the regular + // RemoveAt. + void RemoveAt(size_t index) { + OVR_ASSERT((Data.Data) && (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; + } + } + + // Removes an element from the array without respecting of original order of + // elements for better performance. Do not use on array where order of elements + // is important, otherwise use it instead of regular RemoveAt(). + void RemoveAtUnordered(size_t index) { + OVR_ASSERT((Data.Data) && (index < Data.Size)); + if (Data.Size == 1) { + Clear(); + } else { + // copy the last element into the 'index' position + // and decrement the size (instead of moving all elements + // in [index + 1 .. size - 1] range). + const size_t lastElemIndex = Data.Size - 1; + if (index < lastElemIndex) { + AllocatorType::Destruct(Data.Data + index); + AllocatorType::Construct(Data.Data + index, Data.Data[lastElemIndex]); + } + AllocatorType::Destruct(Data.Data + lastElemIndex); + --Data.Size; + } + } + + // Insert the given object at the given index shifting all the elements up. + void InsertAt(size_t 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(size_t index, size_t 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 (size_t 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[], size_t count) { + Data.Append(other, count); + } + + class Iterator { + SelfType* pArray; + intptr_t CurIndex; + + public: + Iterator() : pArray(0), CurIndex(-1) {} + Iterator(SelfType* parr, intptr_t 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 < (intptr_t)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); + } + intptr_t 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); + } + + intptr_t GetIndex() const { + return CurIndex; + } + }; + + Iterator Begin() { + return Iterator(this); + } + Iterator End() { + return Iterator(this, (intptr_t)GetSize()); + } + Iterator Last() { + return Iterator(this, (intptr_t)GetSize() - 1); + } + + class ConstIterator { + const SelfType* pArray; + intptr_t CurIndex; + + public: + ConstIterator() : pArray(0), CurIndex(-1) {} + ConstIterator(const SelfType* parr, intptr_t 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); + } + intptr_t 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(); + } + + intptr_t GetIndex() const { + return CurIndex; + } + }; + ConstIterator Begin() const { + return ConstIterator(this); + } + ConstIterator End() const { + return ConstIterator(this, (intptr_t)GetSize()); + } + ConstIterator Last() const { + return ConstIterator(this, (intptr_t)GetSize() - 1); + } + + // C++11 ranged-based for loop support. + Iterator begin() { + return Begin(); + } + Iterator end() { + return End(); + } + ConstIterator begin() const { + return Begin(); + } + ConstIterator end() const { + return End(); + } + + protected: + ArrayData Data; +}; + +//----------------------------------------------------------------------------------- +// ***** Array +// +// General purpose array for movable objects that require explicit +// construction/destruction. +template +class Array : public ArrayBase, SizePolicy>> { + public: + typedef T ValueType; + typedef ContainerAllocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef Array SelfType; + typedef ArrayBase, SizePolicy>> BaseType; + + Array() : BaseType() {} + explicit Array(size_t 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 ArrayPOD : public ArrayBase, SizePolicy>> { + public: + typedef T ValueType; + typedef ContainerAllocator_POD AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayPOD SelfType; + typedef ArrayBase, SizePolicy>> BaseType; + + ArrayPOD() : BaseType() {} + explicit ArrayPOD(size_t 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 ArrayCPP : public ArrayBase, SizePolicy>> { + public: + typedef T ValueType; + typedef ContainerAllocator_CPP AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayCPP SelfType; + typedef ArrayBase, SizePolicy>> BaseType; + + ArrayCPP() : BaseType() {} + explicit ArrayCPP(size_t 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 ArrayCC : public ArrayBase, SizePolicy>> { + public: + typedef T ValueType; + typedef ContainerAllocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayCC SelfType; + typedef ArrayBase, SizePolicy>> BaseType; + + ArrayCC(const ValueType& defval) : BaseType(defval) {} + ArrayCC(const ValueType& defval, size_t 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; + } +}; + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.cpp new file mode 100644 index 0000000..f3de0ee --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.cpp @@ -0,0 +1,67 @@ +/************************************************************************************ + +Filename : OVR_Atomic.cpp +Content : Contains atomic operations and inline fastest locking + functionality. Will contain #ifdefs for OS efficiency. + Have non-thread-safe implementation if not available. +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Atomic.h" +#include "OVR_Allocator.h" + +#ifdef OVR_ENABLE_THREADS + +// Include Windows 8-Metro compatible Synchronization API +#if defined(OVR_OS_MS) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) +#include +#endif + +namespace OVR { + +// ***** Windows Lock implementation + +#if defined(OVR_OS_MS) + +// ***** Standard Win32 Lock implementation + +// Constructors +Lock::Lock(unsigned spinCount) { +#if defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) + // On Windows 8 we use InitializeCriticalSectionEx due to Metro-Compatibility + InitializeCriticalSectionEx( + &cs, (DWORD)spinCount, OVR_DEBUG_SELECT(NULL, CRITICAL_SECTION_NO_DEBUG_INFO)); +#else + ::InitializeCriticalSectionAndSpinCount( + &cs, (DWORD)spinCount); // This is available with WindowsXP+. +#endif +} + +Lock::~Lock() { + DeleteCriticalSection(&cs); +} + +#endif + +} // namespace OVR + +#endif // OVR_ENABLE_THREADS diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.h new file mode 100644 index 0000000..d4d2c3b --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Atomic.h @@ -0,0 +1,196 @@ +/************************************************************************************ + +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 (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Atomic_h +#define OVR_Atomic_h + +#include "OVR_Types.h" + +#include + +// Include System thread functionality. +#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) +#include "OVR_Win32_IncludeWindows.h" +#else +#include +#endif + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** Lock + +// Lock is a simplest and most efficient mutual-exclusion lock class. +// Unlike Mutex, it cannot be waited on. + +class Lock { +#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_MS) + + CRITICAL_SECTION cs; + + public: + Lock(unsigned spinCount = 10000); // Mutexes with non-zero spin counts usually result in better + // performance. + ~Lock(); + // Locking functions. + inline void DoLock() { + ::EnterCriticalSection(&cs); + } + inline void Unlock() { + ::LeaveCriticalSection(&cs); + } + inline bool TryLock() { + return (::TryEnterCriticalSection(&cs) == TRUE); + } +#else + pthread_mutex_t mutex; + + public: + static pthread_mutexattr_t RecursiveAttr; + static bool RecursiveAttrInit; + + Lock(unsigned spinCount = 0) // To do: Support spin count, probably via a custom lock + // implementation. + { + OVR_UNUSED(spinCount); + 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); + } + inline bool TryLock() { + return (pthread_mutex_trylock(&mutex) == 0); + } + +#endif // OVR_ENABLE_THREDS + + public: + // Locker class, used for automatic locking + class Locker { + Lock* pLock; + + public: + Locker(Lock* plock) { + pLock = plock; + if (plock) + pLock->DoLock(); + } + ~Locker() { + Release(); + } + + void Release() { + if (pLock) + pLock->Unlock(); + pLock = nullptr; + } + }; + + // Unlocker class, used for automatic unlocking + class Unlocker { + // OVR_NON_COPYABLE(Unlocker); + Lock* mLock; + + public: + Unlocker(Lock* lock) : mLock(lock) {} + ~Unlocker() { + Release(); + } + void Release() { + if (mLock) + mLock->Unlock(); + mLock = nullptr; + } + }; +}; + +//------------------------------------------------------------------------------------- +// Thin locking wrapper around data + +template +class LockedData { + public: + LockedData(Lock& lock) : TheLock(lock) {} + LockedData& operator=(const LockedData& /*rhs*/) { + OVR_ASSERT(false); + return *this; + } + + T Get() { + Lock::Locker locker(&TheLock); + return Instance; + } + + void Set(const T& value) { + Lock::Locker locker(&TheLock); + Instance = value; + } + + // Returns true if the value has changed. + // Returns false if the value has not changed. + bool GetIfChanged(T& value) { + Lock::Locker locker(&TheLock); + + if (value != Instance) { + value = Instance; + return true; + } + + return false; + } + + protected: + T Instance; + Lock& TheLock; +}; + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Callbacks.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Callbacks.cpp new file mode 100644 index 0000000..0ae91f8 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Callbacks.cpp @@ -0,0 +1,42 @@ +/************************************************************************************ + +PublicHeader: Kernel +Filename : OVR_Callbacks.cpp +Content : Callback library +Created : Nov 17, 2014 +Author : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Callbacks.h" + +namespace OVR { + +// Global emitter lock +// +// Add/remove operations on callbacks happen infrequently, and are already fairly +// serialized in order of construction by design. Therefore contention for this +// lock between call()/shutdown() is the main concern and is also rare. +Lock* CallbackEmitterBase::GetEmitterLock() { + static Lock lock; + return &lock; +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Callbacks.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Callbacks.h new file mode 100644 index 0000000..afb265c --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Callbacks.h @@ -0,0 +1,282 @@ +/************************************************************************************ + +PublicHeader: Kernel +Filename : OVR_Callbacks.h +Content : Callback library +Created : June 20, 2014 +Author : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Callbacks_h +#define OVR_Callbacks_h + +#include "OVR_CallbacksInternal.h" + +#include "OVR_Hash.h" // For CallbackHash +#include "OVR_String.h" // For CallbackHash + +namespace OVR { + +//----------------------------------------------------------------------------- +// CallbackEmitter +// +// Emitter of callbacks. +// Thread-safety: All public members may be safely called concurrently. +template +class CallbackEmitter : public NewOverrideBase { + public: + CallbackEmitter(); + ~CallbackEmitter(); + + // Add a listener. + bool AddListener(CallbackListener* listener); + + // Get the current number of listeners. Note that this can change as other threads + // add listeners to the emitter. + int GetListenerCount() const; + + bool HasListeners() const { + return Emitter->HasListeners(); + } + + void Call() { + Emitter->Call(); + } + template + void Call(Param1* p1) { + Emitter->Call(p1); + } + template + void Call(Param1& p1) { + Emitter->Call(p1); + } + template + void Call(Param1* p1, Param2* p2) { + Emitter->Call(p1, p2); + } + template + void Call(Param1& p1, Param2& p2) { + Emitter->Call(p1, p2); + } + template + void Call(Param1* p1, Param2* p2, Param3* p3) { + Emitter->Call(p1, p2, p3); + } + template + void Call(Param1& p1, Param2& p2, Param3& p3) { + Emitter->Call(p1, p2, p3); + } + + // Remove all listeners and prevent further listeners from being added. + void Shutdown(); + + protected: + Ptr> Emitter; +}; + +//----------------------------------------------------------------------------- +// CallbackListener +// +// Listener for callbacks. +// Thread-safety: Operations on a listener are not thread-safe. +// The listener may only listen to *one emitter* at a time. +template +class CallbackListener : public NewOverrideBase { + friend class CallbackEmitter; + + public: + CallbackListener(); + ~CallbackListener(); + + // Stop listening to callbacks. + // And set a new handler for callbacks. + void SetHandler(DelegateT handler); + + // Is listening to an emitter at this instant? + // If the Emitter has shutdown, then this may inaccurately return true. + bool IsListening() const; + + // Stops listening to callbacks. + void Cancel(); + + protected: + /// Internal data: + + // Reference to the associated listener. + Ptr> FloatingListener; + + // Reference to the associated emitter. + Ptr> FloatingEmitter; + + DelegateT Handler; +}; + +//----------------------------------------------------------------------------- +// Template Implementation: CallbackEmitter + +template +CallbackEmitter::CallbackEmitter() { + Emitter = *new FloatingCallbackEmitter; +} + +template +CallbackEmitter::~CallbackEmitter() { + Emitter->Shutdown(); + // Emitter goes out of scope here. +} + +template +bool CallbackEmitter::AddListener(CallbackListener* listener) { + // The listener object can only be attached to one emitter at a time. + // The caller should explicitly Cancel() a listener before listening + // to a new emitter, even if it is the same emitter. + OVR_ASSERT(!listener->FloatingEmitter && !listener->FloatingListener); + + if (listener->FloatingEmitter || listener->FloatingListener) { + // Cancel any previous listening + listener->Cancel(); + } + + // Set the floating listener and emitter + listener->FloatingListener = *new FloatingCallbackListener(listener->Handler); + listener->FloatingEmitter = Emitter.GetPtr(); + + // The remaining input checks are performed inside. + return Emitter->AddListener(listener->FloatingListener); +} + +template +int CallbackEmitter::GetListenerCount() const { + return Emitter->Listeners.GetSizeI(); +} + +template +void CallbackEmitter::Shutdown() { + Emitter->Shutdown(); +} + +//----------------------------------------------------------------------------- +// Template Implementation: CallbackListener + +template +CallbackListener::CallbackListener() { + // Listener is null until a handler is set. +} + +template +CallbackListener::~CallbackListener() { + Cancel(); +} + +template +void CallbackListener::Cancel() { + if (FloatingListener) { + FloatingListener->EnterCancelState(); + } + + if (FloatingEmitter) { + if (FloatingListener) { + FloatingEmitter->OnListenerCancel(FloatingListener); + } + } + + // FloatingEmitter goes out of scope here. + FloatingEmitter = nullptr; + + // FloatingListener goes out of scope here. + FloatingListener = nullptr; +} + +template +void CallbackListener::SetHandler(DelegateT handler) { + Cancel(); + + Handler = handler; +} + +template +bool CallbackListener::IsListening() const { + if (!FloatingListener.GetPtr()) { + return false; + } + + return FloatingListener->IsValid(); +} + +//----------------------------------------------------------------------------- +// CallbackHash +// +// A hash containing CallbackEmitters +template +class CallbackHash : public NewOverrideBase { + typedef Hash*, String::HashFunctor> HashTable; + + public: + ~CallbackHash() { + Clear(); + } + + void Clear() { + for (auto ii = Table.Begin(); ii != Table.End(); ++ii) { + delete ii->Second; + } + + Table.Clear(); + } + + CallbackEmitter* GetKey(String key) { + CallbackEmitter** emitter = Table.Get(key); + if (emitter) { + return *emitter; + } + return nullptr; + } + + void AddListener(String key, CallbackListener* listener) { + CallbackEmitter** pEmitter = Table.Get(key); + CallbackEmitter* emitter = nullptr; + + if (!pEmitter) { + emitter = new CallbackEmitter; + Table.Add(key, emitter); + } else { + emitter = *pEmitter; + } + + emitter->AddListener(listener); + } + + void RemoveKey(String key) { + CallbackEmitter** emitter = Table.Get(key); + + if (emitter) { + delete *emitter; + Table.Remove(key); + } + } + + protected: + HashTable Table; // Hash table +}; + +} // namespace OVR + +#endif // OVR_Callbacks_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_CallbacksInternal.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_CallbacksInternal.h new file mode 100644 index 0000000..bb45f55 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_CallbacksInternal.h @@ -0,0 +1,338 @@ +/************************************************************************************ + +PublicHeader: Kernel +Filename : OVR_CallbacksInternal.h +Content : Callback library +Created : Nov 11, 2014 +Author : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CallbacksInternal_h +#define OVR_CallbacksInternal_h + +#include "OVR_Array.h" +#include "OVR_Atomic.h" +#include "OVR_Delegates.h" +#include "OVR_RefCount.h" + +#if !defined(OVR_CC_MSVC) || (OVR_CC_VERSION > 1600) // Newer than VS2010 +#include +#endif + +namespace OVR { + +template +class FloatingCallbackEmitter; // Floating emitter object +template +class CallbackEmitter; +template +class FloatingCallbackListener; // Floating listener object +template +class CallbackListener; + +//----------------------------------------------------------------------------- +// FloatingCallbackEmitter +// +// The Call() function is not thread-safe. +// TBD: Should we add a thread-safe Call() option to constructor? + +class CallbackEmitterBase { + protected: + static Lock* GetEmitterLock(); +}; + +template +class FloatingCallbackEmitter : public CallbackEmitterBase, + public RefCountBase> { + friend class CallbackEmitter; + + FloatingCallbackEmitter() + : IsShutdown(false), +#if !defined(OVR_CC_MSVC) || (OVR_CC_VERSION > 1600) // Newer than VS2010 + ListenersExist(false), +#endif + DirtyListenersCache(0) { + } + + public: + typedef Array>> ListenerPtrArray; + + ~FloatingCallbackEmitter() { + OVR_ASSERT(Listeners.GetSizeI() == 0); + // ListenersCache will be emptied here. + } + + bool AddListener(FloatingCallbackListener* listener); + bool HasListeners() const { +#if !defined(OVR_CC_MSVC) || (OVR_CC_VERSION > 1600) // Newer than VS2010 + return ListenersExist.load(std::memory_order_relaxed); +#else + // This code still has a data race + return (Listeners.GetSizeI() > 0); +#endif + } + void Shutdown(); + + // Called from the listener object as it is transitioning to canceled state. + // The listener's mutex is not held during this call. + void OnListenerCancel(FloatingCallbackListener* listener); + + public: + void Call(); + + template + void Call(Param1* p1); + + template + void Call(Param1& p1); + + template + void Call(Param1* p1, Param2* p2); + + template + void Call(Param1& p1, Param2& p2); + + template + void Call(Param1* p1, Param2* p2, Param3* p3); + + template + void Call(Param1& p1, Param2& p2, Param3& p3); + + protected: + // Is the emitter shut down? This prevents more listeners from being added during shutdown. + bool IsShutdown; + + // Array of added listeners. + ListenerPtrArray Listeners; + +#if !defined(OVR_CC_MSVC) || (OVR_CC_VERSION > 1600) // Newer than VS2010 + std::atomic ListenersExist; +#endif + + // Is the cache dirty? This avoids locking and memory allocation in steady state. + std::atomic DirtyListenersCache = {0}; + + // Cache of listeners used by the Call() function. + ListenerPtrArray ListenersCacheForCalls; + + // Update the ListenersCache array in response to an insertion or removal. + // This is how AddListener() insertions get rolled into the listeners array. + // This is how RemoveListener() removals get purged from the cache. + void updateListenersCache() { + if (DirtyListenersCache != 0) { + Lock::Locker locker(GetEmitterLock()); + + // TBD: Should memory allocation be further reduced here? + ListenersCacheForCalls = Listeners; + DirtyListenersCache = 0; + } + } + + // Without holding a lock, find and remove the given listener from the array of listeners. + void noLockFindAndRemoveListener(FloatingCallbackListener* listener) { + const int count = Listeners.GetSizeI(); + for (int i = 0; i < count; ++i) { + if (Listeners[i] == listener) { + Listeners.RemoveAt(i); + + // After removing it from the array, set the dirty flag. + // Note: Because the flag is atomic, a portable memory fence is implied. + DirtyListenersCache = 1; + + break; + } + } +#if !defined(OVR_CC_MSVC) || (OVR_CC_VERSION > 1600) // Newer than VS2010 + if (Listeners.GetSizeI() < 1) { + ListenersExist.store(false, std::memory_order_relaxed); + } +#endif + } +}; + +//----------------------------------------------------------------------------- +// FloatingCallbackListener +// +// Internal implementation class for the CallbackListener. +// This can only be associated with one CallbackListener object for its lifetime. +template +class FloatingCallbackListener : public RefCountBase> { + public: + FloatingCallbackListener(DelegateT handler); + ~FloatingCallbackListener(); + + void EnterCancelState(); + + bool IsValid() const { + return Handler.IsValid(); + } + + // TBD: Should these be binned to reduce the lock count? + // Boost does not do that. And I am worried about deadlocks when misused. + mutable Lock ListenerLock; + + // Handler function + DelegateT Handler; +}; + +//----------------------------------------------------------------------------- +// Template Implementation: FloatingCallbackEmitter + +template +bool FloatingCallbackEmitter::AddListener( + FloatingCallbackListener* listener) { + Lock::Locker locker(GetEmitterLock()); + + if (IsShutdown) { + return false; + } + + // Add the listener to our list + Listeners.PushBack(listener); + + // After adding it to the array, set the dirty flag. + // Note: Because the flag is atomic, a portable memory fence is implied. + DirtyListenersCache = 1; + +#if !defined(OVR_CC_MSVC) || (OVR_CC_VERSION > 1600) // Newer than VS2010 + ListenersExist.store(true, std::memory_order_relaxed); +#endif + + return true; +} + +// Called from the listener object as it is transitioning to canceled state. +// The listener's mutex is not held during this call. +template +void FloatingCallbackEmitter::OnListenerCancel( + FloatingCallbackListener* listener) { + Lock::Locker locker(GetEmitterLock()); + + // If not shut down, + // Note that if it is shut down then there will be no listeners in the array. + if (!IsShutdown) { + // Remove it. + noLockFindAndRemoveListener(listener); + } +} + +template +void FloatingCallbackEmitter::Shutdown() { + Lock::Locker locker(GetEmitterLock()); + + IsShutdown = true; + + Listeners.ClearAndRelease(); + + // Note: Because the flag is atomic, a portable memory fence is implied. + DirtyListenersCache = 1; + +#if !defined(OVR_CC_MSVC) || (OVR_CC_VERSION > 1600) // Newer than VS2010 + ListenersExist.store(false, std::memory_order_relaxed); +#endif +} + +//----------------------------------------------------------------------------- +// Call function +// +// (1) Update the cache of listener references, if it has changed. +// (2) For each listener, +// (a) Hold ListenerLock. +// (b) If listener handler is valid, call the handler. +#define OVR_EMITTER_CALL_BODY(params) \ + updateListenersCache(); \ + if (IsShutdown) \ + return; /* Pure optimization. It is fine if this races. */ \ + const int count = ListenersCacheForCalls.GetSizeI(); \ + for (int i = 0; i < count; ++i) { \ + Lock::Locker locker(&ListenersCacheForCalls[i]->ListenerLock); \ + if (ListenersCacheForCalls[i]->Handler.IsValid()) { \ + ListenersCacheForCalls[i]->Handler params; /* Using a macro for this line. */ \ + } \ + } + +template +void FloatingCallbackEmitter::Call() { + OVR_EMITTER_CALL_BODY(()) +} + +template +template +void FloatingCallbackEmitter::Call(Param1* p1) { + OVR_EMITTER_CALL_BODY((p1)) +} + +template +template +void FloatingCallbackEmitter::Call(Param1& p1) { + OVR_EMITTER_CALL_BODY((p1)) +} + +template +template +void FloatingCallbackEmitter::Call(Param1* p1, Param2* p2) { + OVR_EMITTER_CALL_BODY((p1, p2)) +} + +template +template +void FloatingCallbackEmitter::Call(Param1& p1, Param2& p2) { + OVR_EMITTER_CALL_BODY((p1, p2)) +} + +template +template +void FloatingCallbackEmitter::Call(Param1* p1, Param2* p2, Param3* p3) { + OVR_EMITTER_CALL_BODY((p1, p2, p3)) +} + +template +template +void FloatingCallbackEmitter::Call(Param1& p1, Param2& p2, Param3& p3) { + OVR_EMITTER_CALL_BODY((p1, p2, p3)) +} + +#undef OVR_EMITTER_CALL_BODY + +//----------------------------------------------------------------------------- +// Template Implementation: FloatingCallbackListener + +template +FloatingCallbackListener::FloatingCallbackListener(DelegateT handler) + : Handler(handler) { + OVR_ASSERT(Handler.IsValid()); +} + +template +FloatingCallbackListener::~FloatingCallbackListener() { + OVR_ASSERT(!Handler.IsValid()); +} + +template +void FloatingCallbackListener::EnterCancelState() { + ListenerLock.DoLock(); + Handler.Invalidate(); + ListenerLock.Unlock(); +} + +} // namespace OVR + +#endif // OVR_CallbacksInternal_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Color.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Color.h new file mode 100644 index 0000000..fdbdb87 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Color.h @@ -0,0 +1,68 @@ +/************************************************************************************ + +Filename : OVR_Color.h +Content : Contains color struct. +Created : February 7, 2013 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ +#ifndef OVR_Color_h +#define OVR_Color_h + +#include "OVR_Types.h" + +namespace OVR { + +struct Color { + uint8_t R, G, B, A; + + Color() { +#if defined(OVR_BUILD_DEBUG) + R = G = B = A = 0; +#endif + } + + // Constructs color by channel. Alpha is set to 0xFF (fully visible) + // if not specified. + 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; + } +}; + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Compiler.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Compiler.h new file mode 100644 index 0000000..7374660 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Compiler.h @@ -0,0 +1,1525 @@ +/************************************************************************************ + +PublicHeader: OVR_Types.h +Filename : OVR_Compiler.h +Content : Compiler-specific feature identification and utilities +Created : June 19, 2014 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#pragma once + +// References +// https://gcc.gnu.org/projects/cxx0x.html +// https://gcc.gnu.org/projects/cxx1y.html +// http://clang.llvm.org/cxx_status.html +// http://msdn.microsoft.com/en-us/library/hh567368.aspx +// https://docs.google.com/spreadsheet/pub?key=0AoBblDsbooe4dHZuVTRoSTFBejk5eFBfVk1GWlE5UlE&output=html +// http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros + +//----------------------------------------------------------------------------------- +// ***** 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 +// MSVC 11.0 (VC2012) = 1700 +// MSVC 12.0 (VC2013) = 1800 +// MSVC 14.0 (VC2015) = 1900 +#define OVR_CC_MSVC _MSC_VER + +#if _MSC_VER == 0x1600 +#if _MSC_FULL_VER < 160040219 +#error "Oculus does not support VS2010 without SP1 installed." +#endif +#endif + +#elif defined(__GNUC__) +#define OVR_CC_GNU + +#elif defined(__clang__) +#define OVR_CC_CLANG + +#elif defined(__CC_ARM) +#define OVR_CC_ARM + +#else +#error "Oculus does not support this Compiler" +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CC_VERSION +// +// M = major version +// m = minor version +// p = patch release +// b = build number +// +// Compiler Format Example +// ---------------------------- +// OVR_CC_GNU Mmm 408 means GCC 4.8 +// OVR_CC_CLANG Mmm 305 means clang 3.5 +// OVR_CC_MSVC MMMM 1700 means VS2012 +// OVR_CC_ARM Mmpbbb 401677 means 4.0, patch 1, build 677 +// OVR_CC_INTEL MMmm 1210 means 12.10 +// OVR_CC_EDG Mmm 407 means EDG 4.7 +// +#if defined(OVR_CC_GNU) +#define OVR_CC_VERSION ((__GNUC__ * 100) + __GNUC_MINOR__) +#elif defined(OVR_CC_CLANG) +#define OVR_CC_VERSION ((__clang_major__ * 100) + __clang_minor__) +#elif defined(OVR_CC_MSVC) +#define OVR_CC_VERSION _MSC_VER // Question: Should we recognize _MSC_FULL_VER? +#elif defined(OVR_CC_ARM) +#define OVR_CC_VERSION __ARMCC_VERSION +#elif defined(OVR_CC_INTEL) +#if defined(__INTEL_COMPILER) +#define OVR_CC_VERSION __INTEL_COMPILER +#elif defined(__ICL) +#define OVR_CC_VERSION __ICL +#elif defined(__ICC) +#define OVR_CC_VERSION __ICC +#elif defined(__ECC) +#define OVR_CC_VERSION __ECC +#endif +#elif defined(OVR_CC_EDG) +#define OVR_CC_VERSION \ + __EDG_VERSION__ // This is a generic fallback for EDG-based compilers which aren't specified above +// (e.g. as OVR_CC_ARM) +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_DISABLE_OPTIMIZATION / OVR_RESTORE_OPTIMIZATION +// +// Allows for the dynamic disabling and restoring of compiler optimizations in code. +// This is useful for helping deal with potential compiler code generation problems. +// With VC++ the usage must be outside of function bodies. This can be used only to +// temporarily disable optimization for a block of code and not to temporarily enable +// optimization for a block of code. +// +// Clang doesn't support this as of June 2014, though function __attribute__((optimize(0)) +// is supposedly supported by clang in addition to GCC. To consider: Make a wrapper for +// this attribute-based functionality. +// +// Example usage: +// OVR_DISABLE_OPTIMIZATION() +// void Test() { ... } +// OVR_RESTORE_OPTIMIZATION() +// +#if !defined(OVR_DISABLE_OPTIMIZATION) +#if defined(OVR_CC_GNU) && (OVR_CC_VERSION > 404) && \ + (defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)) +#define OVR_DISABLE_OPTIMIZATION() _Pragma("GCC push_options") _Pragma("GCC optimize 0") +#elif defined(OVR_CC_MSVC) && !defined(__clang__) +#define OVR_DISABLE_OPTIMIZATION() __pragma(optimize("", off)) +#else +#define OVR_DISABLE_OPTIMIZATION() +#endif +#endif + +#if !defined(OVR_RESTORE_OPTIMIZATION) +#if defined(OVR_CC_GNU) && (OVR_CC_VERSION > 404) && \ + (defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)) +#define OVR_RESTORE_OPTIMIZATION() _Pragma("GCC pop_options") +#elif defined(OVR_CC_MSVC) && !defined(__clang__) +#define OVR_RESTORE_OPTIMIZATION() __pragma(optimize("", on)) +#else +#define OVR_RESTORE_OPTIMIZATION() +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_DISABLE_GNU_WARNING / OVR_RESTORE_GNU_WARNING +// +// Portable wrapper for disabling GCC compiler warnings, one at a time. See example +// usage for usage by example. +// +// Example usage: +// OVR_DISABLE_GNU_WARNING(-Wmissing-braces) // Only one warning per usage. +// OVR_DISABLE_GNU_WARNING(-Wunused-variable) +// +// OVR_RESTORE_GNU_WARNINGS() +// OVR_RESTORE_GNU_WARNINGS() // Must match each disable with a restore. +// +#if !defined(OVR_DISABLE_GNU_WARNING) +#if defined(OVR_CC_GNU) +#define ODGW1(x) #x +#define ODGW2(x) ODGW1(GCC diagnostic ignored x) +#define ODGW3(x) ODGW2(#x) +#endif + +#if defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 406) +#define OVR_DISABLE_GNU_WARNING(w) _Pragma("GCC diagnostic push") _Pragma(ODGW3(w)) +#elif defined(OVR_CC_GNU) && \ + (OVR_CC_VERSION >= \ + 404) // GCC 4.4 doesn't support diagnostic push, but supports disabling warnings. +#define OVR_DISABLE_GNU_WARNING(w) _Pragma(ODGW3(w)) +#else +#define OVR_DISABLE_GNU_WARNING(w) +#endif +#endif + +#if !defined(OVR_RESTORE_GNU_WARNING) +#if defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 4006) +#define OVR_RESTORE_GNU_WARNINGS() _Pragma("GCC diagnostic pop") +#else +#define OVR_RESTORE_GNU_WARNING() +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_DISABLE_CLANG_WARNING / OVR_RESTORE_CLANG_WARNING +// +// Portable wrapper for disabling GCC compiler warnings, one at a time. See example +// usage for usage by example. +// +// Example usage: +// OVR_DISABLE_CLANG_WARNING(-Wmissing-braces) // Only one warning per usage. +// OVR_DISABLE_CLANG_WARNING(-Wunused-variable) +// +// OVR_RESTORE_CLANG_WARNINGS() +// OVR_RESTORE_CLANG_WARNINGS() // Must match each disable with a restore. +// +// +#if !defined(OVR_DISABLE_CLANG_WARNING) +#if defined(OVR_CC_CLANG) +#define ODCW1(x) #x +#define ODCW2(x) ODCW1(clang diagnostic ignored x) +#define ODCW3(x) ODCW2(#x) + +#define OVR_DISABLE_CLANG_WARNING(w) _Pragma("clang diagnostic push") _Pragma(ODCW3(w)) +#else +#define OVR_DISABLE_CLANG_WARNING(w) +#endif +#endif + +#if !defined(OVR_RESTORE_CLANG_WARNING) +#if defined(OVR_CC_CLANG) +#define OVR_RESTORE_CLANG_WARNING() _Pragma("clang diagnostic pop") +#else +#define OVR_RESTORE_CLANG_WARNING() +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_DISABLE_MSVC_WARNING / OVR_RESTORE_MSVC_WARNING +// +// Portable wrapper for disabling VC++ compiler warnings. See example usage for usage +// by example. +// +// Example usage: +// OVR_DISABLE_MSVC_WARNING(4556 4782 4422) +// +// OVR_RESTORE_MSVC_WARNING() +// +#if !defined(OVR_DISABLE_MSVC_WARNING) +#if defined(OVR_CC_MSVC) +#define OVR_DISABLE_MSVC_WARNING(w) __pragma(warning(push)) __pragma(warning(disable : w)) +#else +#define OVR_DISABLE_MSVC_WARNING(w) +#endif +#endif + +#if !defined(OVR_RESTORE_MSVC_WARNING) +#if defined(OVR_CC_MSVC) +#define OVR_RESTORE_MSVC_WARNING() __pragma(warning(pop)) +#else +#define OVR_RESTORE_MSVC_WARNING() +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_SUPPRESS_MSVC_WARNING +// +// Portable wrapper for disabling a single warning on the next source code line. +// +// Example usage: +// OVR_SUPPRESS_MSVC_WARNING(4556) +// +// +#if !defined(OVR_SUPPRESS_MSVC_WARNING) +#if defined(OVR_CC_MSVC) +#define OVR_SUPPRESS_MSVC_WARNING(w) __pragma(warning(suppress : w)) +#else +#define OVR_SUPPRESS_MSVC_WARNING(w) +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_DISABLE_ALL_MSVC_WARNINGS / OVR_RESTORE_ALL_MSVC_WARNINGS +// +// Portable wrapper for disabling all VC++ compiler warnings. +// OVR_RESTORE_ALL_MSVC_WARNINGS restores warnings that were disabled by +// OVR_DISABLE_ALL_MSVC_WARNINGS. Any previously enabled warnings will still be +// enabled after OVR_RESTORE_ALL_MSVC_WARNINGS. +// +// Example usage: +// OVR_DISABLE_ALL_MSVC_WARNINGS() +// +// OVR_RESTORE_ALL_MSVC_WARNINGS() + +#if !defined(OVR_DISABLE_ALL_MSVC_WARNINGS) +#if defined(OVR_CC_MSVC) +#define OVR_DISABLE_ALL_MSVC_WARNINGS() \ + __pragma(warning(push, 0)) __pragma(warning(disable : 4263 4264 4265 4266)) +#else +#define OVR_DISABLE_ALL_MSVC_WARNINGS() +#endif +#endif + +#if !defined(OVR_RESTORE_ALL_MSVC_WARNINGS) +#if defined(OVR_CC_MSVC) +#define OVR_RESTORE_ALL_MSVC_WARNINGS() __pragma(warning(pop)) +#else +#define OVR_RESTORE_ALL_MSVC_WARNINGS() +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CC_HAS_FEATURE +// +// This is a portable way to use compile-time feature identification available +// with some compilers in a clean way. Direct usage of __has_feature in preprocessing +// statements of non-supporting compilers results in a preprocessing error. +// +// Example usage: +// #if OVR_CC_HAS_FEATURE(is_pod) +// if(__is_pod(T)) // If the type is plain data then we can safely memcpy it. +// memcpy(&destObject, &srcObject, sizeof(object)); +// #endif +// +#if !defined(OVR_CC_HAS_FEATURE) +#if defined(__clang__) // http://clang.llvm.org/docs/LanguageExtensions.html#id2 +#define OVR_CC_HAS_FEATURE(x) __has_feature(x) +#else +#define OVR_CC_HAS_FEATURE(x) 0 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CC_HAS_BUILTIN +// +// +// This is a portable way to use compile-time builtin identification available +// with some compilers in a clean way. Direct usage of __has_builtin in preprocessing +// statements of non-supporting compilers results in a preprocessing error. +// +// Example usage: +// #if OVR_CC_HAS_BUILTIN(__builtin_trap) +// #define DEBUG_BREAK __builtin_trap +// #endif +// +#if !defined(OVR_CC_HAS_BUILTIN) +#if defined(__clang__) +#define OVR_CC_HAS_BUILTIN(x) \ + __has_builtin(x) // http://clang.llvm.org/docs/LanguageExtensions.html#id2 +#else +#define OVR_CC_HAS_BUILTIN(x) 0 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP11_ENABLED / OVR_CPP_CPP14_ENABLED +// +// Defined as 1 if the compiler has its available C++11 support enabled, else undefined. +// This does not mean that all of C++11 or any particular feature of C++11 is supported +// by the compiler. It means that whatever C++11 support the compiler has is enabled. +// This also includes existing and older compilers that still identify C++11 as C++0x. +// +#if !defined(OVR_CPP11_ENABLED) && defined(__cplusplus) +#if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) +#define OVR_CPP11_ENABLED 1 +#elif defined(_MSC_VER) && \ + (_MSC_VER >= 1500) // VS2010+, the first version with any significant C++11 support. +#define OVR_CPP11_ENABLED 1 +#elif (__cplusplus >= 201103L) // 201103 is the first C++11 version. +#define OVR_CPP11_ENABLED 1 +#else +// Leave undefined +#endif +#endif + +#if !defined(OVR_CPP_CPP14_ENABLED) && defined(__cplusplus) +#if defined(_MSC_VER) && \ + (_MSC_VER >= 1800) // VS2013+, the first version with any significant C++14 support. +#define OVR_CPP_CPP14_ENABLED 1 +#elif (__cplusplus > 201103L) +#define OVR_CPP_CPP14_ENABLED 1 +#else +// Leave undefined +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_EXCEPTIONS / OVR_CPP_NO_UNWIND +// +// OVR_CPP_NO_EXCEPTIONS is defined as 1 if the compiler doesn't support C++ +// exceptions or is configured to disable support for them. Else not defined. +// If OVR_CPP_NO_EXCEPTIONS is defined then attempts to use try/catch +// related C++ statements result in a compilation error with many +// compilers. +// +// OVR_CPP_NO_UNWIND is defined as 1 if the compiler supports exceptions but +// doesn't support stack unwinding in the presence of an exception. Else not defined. +// For the Microsoft compiler, disabling exceptions means disabling stack unwinding +// and not disabling exceptions themselves. +// +// Example usage: +// void Test() { +// #if !defined(OVR_CPP_NO_EXCEPTIONS) +// try { +// #endif +// void* ptr = new Object; +// #if !defined(OVR_CPP_NO_EXCEPTIONS) +// catch(...) { ... } +// #endif + +#if !defined(OVR_CPP_NO_EXCEPTIONS) +#if defined(OVR_CPP_GNUC) && defined(_NO_EX) +#define OVR_CPP_NO_EXCEPTIONS 1 +#elif ( \ + defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) || defined(OVR_CC_INTEL) || \ + defined(OVR_CC_ARM)) && \ + !defined(__EXCEPTIONS) +#define OVR_CPP_NO_EXCEPTIONS 1 +#elif defined(OVR_CC_MSVC) && !defined(_CPPUNWIND) +#define OVR_CPP_NO_UNWIND 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_RTTI +// +// Defined as 1 if C++ run-time type information support is unavailable or disabled +// by the compiler. Else undefined. Allows you to write portable code in the face +// of the possibility that RTTI is disabled. +// +// Example usage: +// #if !OVR_CPP_NO_RTTI +// #include +// int x = std::dynamic_cast(3.4f); +// #endif + +#if defined(__clang__) && !OVR_CC_HAS_FEATURE(cxx_rtti) +#define OVR_CPP_NO_RTTI 1 +#elif defined(__GNUC__) && !defined(__GXX_RTTI) +#define OVR_CPP_NO_RTTI 1 +#elif defined(_MSC_VER) && !defined(_CPPRTTI) +#define OVR_CPP_NO_RTTI 1 +#elif defined(__CC_ARM) && defined(__TARGET_CPU_MPCORE) && !defined(__RTTI) +#define OVR_CPP_NO_RTTI 1 +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_STATIC_ASSERT +// +// Defined as 1 if C++ run-time type information support is available and enabled +// by the compiler. Else undefined. +// +// Example usage: +// #if OVR_CPP_NO_STATIC_ASSERT +// #define MY_ASSERT(x) { int zero = 0; switch(zero) {case 0: case (x):;} } +// #else +// #define MY_ASSERT(x) static_assert((x), #x) +// #endif + +#if !defined(OVR_CPP_NO_STATIC_ASSERT) +#if !( \ + defined(__GNUC__) && \ + (defined(__GXX_EXPERIMENTAL_CXX0X__) || \ + (defined(__cplusplus) && (__cplusplus >= 201103L)))) && \ + !(defined(__clang__) && defined(__cplusplus) && OVR_CC_HAS_FEATURE(cxx_static_assert)) && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(__cplusplus)) && /* VS2010+ */ \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) && \ + defined(OVR_CPP11_ENABLED)) /* EDG 4.1+ */ +#define OVR_CPP_NO_STATIC_ASSERT 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_NULLPTR +// +// Defined as 1 if the compiler doesn't support C++11 nullptr built in type. +// Otherwise undefined. Does not identify if the standard library defines +// std::nullptr_t, as some standard libraries are further behind in standardization +// than the compilers using them (e.g. Apple clang with the supplied libstdc++). +// +// OVR_Nullptr.h provides a portable nullptr and std::nullptr_t for when the +// compiler or standard library do not. + +#if !defined(OVR_CPP_NO_NULLPTR) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_nullptr)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ +#define OVR_CPP_NO_NULLPTR 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_RVALUE_REFERENCES +// +// Defined as 1 if the compiler doesn't support C++11 rvalue references and move semantics. +// Otherwise undefined. + +#if !defined(OVR_CPP_NO_RVALUE_REFERENCES) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_rvalue_references)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ +#define OVR_CPP_NO_RVALUE_REFERENCES 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_AUTO +// +// Defined as 1 if the compiler doesn't support C++11 auto keyword. Otherwise undefined. + +#if !defined(OVR_CPP_NO_AUTO) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_auto_type)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 309))) /* EDG 3.9+ */ +#define OVR_CPP_NO_AUTO 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_RANGE_BASED_FOR_LOOP +// +// Defined as 1 if the compiler doesn't support C++11 range-based for loops. +// Otherwise undefined. + +#if !defined(OVR_CPP_NO_RANGE_BASED_FOR_LOOP) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_range_for)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ +#define OVR_CPP_NO_RANGE_BASED_FOR_LOOP 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_CONSTEXPR / OVR_CPP_NO_RELAXED_CONSTEXPR +// +// OVR_CPP_NO_CONSTEXPR is defined as 1 if the compiler doesn't support C++11 constexpr. +// OVR_CPP_NO_RELAXED_CONSTEXPR is defined as 1 if the compiler doesn't support C++14 constexpr. +// Otherwise undefined. +// See the OVR_CONSTEXPR / OVR_CONSTEXPR_OR_CONST macros for portable wrappers of this +// functionality. + +#if !defined(OVR_CPP_NO_CONSTEXPR) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_constexpr)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ +// Not supported by VC++ through at least VS2013. +#define OVR_CPP_NO_CONSTEXPR 1 +#endif +#endif + +#if !defined(OVR_CPP_NO_RELAXED_CONSTEXPR) +#if !defined(OVR_CPP14_ENABLED) || \ + !(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_relaxed_constexpr)) /* clang */ +// Supported only by clang as of this writing. +#define OVR_CPP_NO_RELAXED_CONSTEXPR 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_LAMBDA_EXPRESSIONS +// +// Defined as 1 if the compiler doesn't support C++11 lambda expressions. Otherwise undefined. +// Some compilers have slightly crippled versions of this. + +#if !defined(OVR_CPP_NO_LAMBDA_EXPRESSIONS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_lambdas)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ +// Conversion of lambdas to function pointers is not supported until EDG 4.5. +#define OVR_CPP_NO_LAMBDA_EXPRESSIONS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_ALIGNOF +// +// Defined as 1 if the compiler supports C++11 alignof. Otherwise undefined. +// Some compilers support __alignof__ instead of alignof, so for portability you +// should use OVR_ALIGNOF instead of directly using C++11 alignof. + +#if !defined(OVR_CPP_NO_ALIGNOF) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 300)) /* Apple clang 3.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 401)) /* GCC 4.1+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2015+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 400))) /* EDG 4.0+ */ +#define OVR_CPP_NO_ALIGNOF 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_ALIGNAS +// +// Defined as 1 if the compiler supports C++11 alignas. Otherwise undefined. +// See the OVR_ALIGNAS for a portable wrapper for alignas functionality. + +#if !defined(OVR_CPP_NO_ALIGNAS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2015+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ +#define OVR_CPP_NO_ALIGNAS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_OVERRIDE +// +// Defined as 1 if the compiler doesn't support C++11 override. Otherwise undefined. +// See the OVR_OVERRIDE and OVR_FINALOVERRIDE macros for a portable wrapper. + +#if !defined(OVR_CPP_NO_OVERRIDE) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ +#define OVR_CPP_NO_OVERRIDE 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_FINAL +// +// Defined as 1 if the compiler doesn't support C++11 final attribute. Otherwise undefined. +// See the OVR_FINAL and OVR_FINALOVERRIDE macros for a portable wrapper. + +#if !defined(OVR_CPP_NO_FINAL) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ +#define OVR_CPP_NO_FINAL 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_EXTERN_TEMPLATE +// +// Defined as 1 if the compiler doesn't support C++11 extern template. +// Otherwise undefined. See OVR_EXTERN_TEMPLATE for wrapper macro. + +#if !defined(OVR_CPP_NO_EXTERN_TEMPLATE) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ +#define OVR_CPP_NO_EXTERN_TEMPLATE 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_VARIADIC_TEMPLATES +// +// Defined as 1 if the compiler doesn't support C++11 variadic templates. Otherwise undefined. + +#if !defined(OVR_CPP_NO_VARIADIC_TEMPLATES) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_variadic_templates)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ +#define OVR_CPP_NO_VARIADIC_TEMPLATES 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_NOEXCEPT +// +// Defined as 1 if the compiler supports C++11 noexcept. Otherwise undefined. +// http://en.cppreference.com/w/cpp/language/noexcept +// See OVR_NOEXCEPT / OVR_NOEXCEPT_IF / OVR_NOEXCEPT_EXPR for a portable wrapper +// for noexcept functionality. + +#if !defined(OVR_CPP_NO_NOEXCEPT) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_noexcept)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2015+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ +#define OVR_CPP_NO_NOEXCEPT 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_DECLTYPE +// +// Defined as 1 if the compiler doesn't support C++11 decltype. Otherwise undefined. +// Some compilers (e.g. VS2012) support most uses of decltype but don't support +// decltype with incomplete types (which is an uncommon usage seen usually in +// template metaprogramming). We don't include this support as a requirement for +// our definition of decltype support here. + +#if !defined(OVR_CPP_NO_DECLTYPE) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_decltype)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ +// VC++ fails to support decltype for incomplete types until VS2013. +// EDG fails to support decltype for incomplete types until v4.8. +#define OVR_CPP_NO_DECLTYPE 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_DEFAULTED_FUNCTIONS +// +// Defined as 1 if the compiler doesn't support C++11 defaulted functions. Otherwise undefined. +// Some compilers have slightly crippled versions of this. + +#if !defined(OVR_CPP_NO_DEFAULTED_FUNCTIONS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_defaulted_functions)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ +// Up through at least VS2013 it's unsupported for defaulted move constructors and move assignment +// operators. +// Until EDG 4.8 it's unsupported for defaulted move constructors and move assigment operators. +#define OVR_CPP_NO_DEFAULTED_FUNCTIONS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_DELETED_FUNCTIONS +// +// Defined as 1 if the compiler doesn't support C++11 deleted functions. Otherwise undefined. +// Some compilers have slightly crippled versions of this. + +#if !defined(OVR_CPP_NO_DELETED_FUNCTIONS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_defaulted_functions)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ +// Up through at least VS2013 it's unsupported for defaulted move constructors and move assignment +// operators. +// Until EDG 4.8 it's unsupported for defaulted move constructors and move assigment operators. +#define OVR_CPP_NO_DELETED_FUNCTIONS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_STANDARD_LAYOUT_TYPES +// +// Defined as 1 if the compiler doesn't support C++11 standard layout (relaxed POD). Otherwise +// undefined. +// http://en.cppreference.com/w/cpp/types/is_standard_layout + +#if !defined(OVR_CPP_NO_STANDARD_LAYOUT_TYPES) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ +#define OVR_CPP_NO_STANDARD_LAYOUT_TYPES 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_FORWARD_DECLARED_ENUMS +// +// Defined as 1 if the compiler doesn't support C++11 forward declared enums. Otherwise undefined. + +#if !defined(OVR_CPP_NO_FORWARD_DECLARED_ENUMS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ +#define OVR_CPP_NO_FORWARD_DECLARED_ENUMS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_STRONGLY_TYPED_ENUMS +// +// Defined as 1 if the compiler doesn't support C++11 strongly typed enums. Otherwise undefined. + +#if !defined(OVR_CPP_NO_STRONGLY_TYPED_ENUMS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_strong_enums)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 400))) /* EDG 4.0+ */ +#define OVR_CPP_NO_STRONGLY_TYPED_ENUMS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_TRAILING_RETURN_TYPES +// +// Defined as 1 if the compiler doesn't support C++11 trailing return types. Otherwise undefined. +// http://en.wikipedia.org/wiki/C%2B%2B11#Alternative_function_syntax + +#if !defined(OVR_CPP_NO_TRAILING_RETURN_TYPES) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_trailing_return)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ +#define OVR_CPP_NO_TRAILING_RETURN_TYPES 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_TEMPLATE_ALIASES +// +// Defined as 1 if the compiler doesn't support C++11 template aliases. Otherwise undefined. + +#if !defined(OVR_CPP_NO_TEMPLATE_ALIASES) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_alias_templates)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ +#define OVR_CPP_NO_TEMPLATE_ALIASES 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_INITIALIZER_LISTS +// +// Defined as 1 if the compiler doesn't support C++11 initializer lists. Otherwise undefined. +// This refers to the compiler support for this and not the Standard Library support for +// std::initializer_list, +// as a new compiler with an old standard library (e.g. Apple clang with libstdc++) may not support +// std::initializer_list. + +#if !defined(OVR_CPP_NO_INITIALIZER_LISTS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_generalized_initializers)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ +#define OVR_CPP_NO_INITIALIZER_LISTS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_NORETURN +// +// Defined as 1 if the compiler doesn't support the C++11 noreturn attribute. Otherwise undefined. +// http://en.cppreference.com/w/cpp/language/attributes +// +#if !defined(OVR_CPP_NO_NORETURN) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ +// Supported with VC++ only via __declspec(noreturn) (see OVR_NORETURN). +#define OVR_CPP_NO_NORETURN 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS +// +// Defined as 1 if the compiler doesn't support C++11 in-class non-static member initializers. +// Otherwise undefined. +// http://en.cppreference.com/w/cpp/language/data_members + +#if !defined(OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ +#define OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_DOUBLE_TEMPLATE_BRACKETS +// +// Defined as 1 if the compiler supports nested template declarations with >>, +// as supported by C++11. Otherwise undefined. + +#if !defined(OVR_CPP_NO_DOUBLE_TEMPLATE_ANGLE_BRACKETS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ +#define OVR_CPP_NO_DOUBLE_TEMPLATE_BRACKETS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_INHERITING_CONSTRUCTORS +// +// Defined as 1 if the compiler supports C++11 inheriting constructors. Otherwise undefined. +// Example usage: +// struct A { explicit A(int x){} }; +// struct B : public A { using A::A; }; // As if B redeclared A::A(int). + +#if !defined(OVR_CPP_NO_INHERITING_CONSTRUCTORS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_inheriting_constructors)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2015+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ +#define OVR_CPP_NO_INHERITING_CONSTRUCTORS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_DELEGATING_CONSTRUCTORS +// +// Defined as 1 if the compiler supports C++11 delegating constructors. Otherwise undefined. + +#if !defined(OVR_CPP_NO_DELEGATING_CONSTRUCTORS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ +#define OVR_CPP_NO_DELEGATING_CONSTRUCTORS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +// +// Defined as 1 if the compiler supports C++11 function template default arguments. Otherwise +// undefined. + +#if !defined(OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ +#define OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_UNRESTRICTED_UNIONS +// +// Defined as 1 if the compiler supports C++11 unrestricted unions. Otherwise undefined. + +#if !defined(OVR_CPP_NO_UNRESTRICTED_UNIONS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ +// Not supported by VC++ as of VS2013. +#define OVR_CPP_NO_UNRESTRICTED_UNIONS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_EXTENDED_SIZEOF +// +// Defined as 1 if the compiler supports C++11 class sizeof extensions (e.g. sizeof +// SomeClass::someMember). +// Otherwise undefined. + +#if !defined(OVR_CPP_NO_EXTENDED_SIZEOF) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2015+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ +#define OVR_CPP_NO_EXTENDED_SIZEOF 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_INLINE_NAMESPACES +// +// Defined as 1 if the compiler supports C++11 inlined namespaces. Otherwise undefined. +// http://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces + +#if !defined(OVR_CPP_NO_INLINE_NAMESPACES) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ +// Not supported by VC++ as of VS2013. +#define OVR_CPP_NO_INLINE_NAMESPACES 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS +// +// Defined as 1 if the compiler supports C++11 explicit conversion operators. Otherwise undefined. +// http://en.cppreference.com/w/cpp/language/explicit + +#if !defined(OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_explicit_conversions)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 404))) /* EDG 4.4+ */ +#define OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +// +// Defined as 1 if the compiler supports C++11 local class template parameters. Otherwise undefined. +// Example: +// void Test() { +// struct LocalClass{ }; +// SomeTemplateClass t; // Allowed only in C++11 +// } + +#if !defined(OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_local_type_template_args)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ +#define OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_NEW_CHARACTER_TYPES +// +// Defined as 1 if the compiler natively supports C++11 char16_t and char32_t. Otherwise undefined. +// VC++ through at least VS2013 defines char16_t as unsigned short in its standard library, +// but it is not a native type or unique type, nor can you for a string literal with it. + +#if !defined(OVR_CPP_NO_NEW_CHARACTER_TYPES) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_unicode_literals)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ +// Not supported by VC++ as of VS2013. +#define OVR_CPP_NO_NEW_CHARACTER_TYPES 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS +// +// Defined as 1 if the compiler supports C++11 \u and \U character literals for +// native char16_t and char32_t types. +// +#if !defined(OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ +// Not supported by VC++ as of VS2013. VC++'s existing \U and \u are non-conforming. +#define OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_USER_DEFINED_LITERALS +// +// Defined as 1 if the compiler supports C++11 user-defined literals. Otherwise undefined. + +#if !defined(OVR_CPP_NO_USER_DEFINED_LITERALS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ +// Not supported by VC++ as of VS2013. +#define OVR_CPP_NO_USER_DEFINED_LITERALS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_UNICODE_STRING_LITERALS +// +// Defined as 1 if the compiler supports C++11 Unicode string literals. Otherwise undefined. +// http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals + +#if !defined(OVR_CPP_NO_UNICODE_STRING_LITERALS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_unicode_literals)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ +// Not supported by VC++ as of VS2013. +#define OVR_CPP_NO_UNICODE_STRING_LITERALS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_RAW_STRING_LITERALS +// +// Defined as 1 if the compiler supports C++11 raw literals. Otherwise undefined. +// http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals + +#if !defined(OVR_CPP_NO_RAW_STRING_LITERALS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_raw_string_literals)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ +// Not supported by VC++ as of VS2013. +#define OVR_CPP_NO_RAW_STRING_LITERALS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX +// +// Defined as 1 if the compiler supports C++11 unified initialization. +// http://en.wikipedia.org/wiki/C%2B%2B11#Uniform_initialization + +#if !defined(OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_generalized_initializers)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ +#define OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS +// +// Defined as 1 if the compiler supports C++11 extended friends. + +#if !defined(OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ +#define OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_THREAD_LOCAL +// +// Defined as 1 if the compiler supports C++11 thread_local. Else undefined. Does not +// indicate if the compiler supports C thread-local compiler extensions such as __thread +// and declspec(thread). Use OVR_THREAD_LOCAL if you want to declare a thread-local +// variable that supports C++11 thread_local when available but the C extension when +// it's available. The primary difference between C++11 thread_local and C extensions is +// that C++11 thread_local supports non-PODs and calls their constructors and destructors. +// +// Note that thread_local requires both compiler and linker support, and so it's possible +// that the compiler may support thread_local but the linker does not. + +#if !defined(OVR_CPP_NO_THREAD_LOCAL) +#if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_thread_local)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ +#define OVR_CPP_NO_THREAD_LOCAL 1 +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_ALIGNAS / OVR_ALIGNOF +// +// OVR_ALIGNAS(n) // Specifies a size_t power of two alignment for a type or instance. +// OVR_ALIGNOF(type) // Returns the size_t alignment of a type or instance. +// +// Example usage: +// OVR_ALIGNAS(8) char c = 'c'; // Specifies that the instance c be aligned +// to an 8 byte boundary. +// typedef OVR_ALIGNAS(8) char C; // Specifies that the type C be aligned to +// an 8 byte boundary. +// struct OVR_ALIGNAS(64) S{ char array[16]; }; // Specfies that the struct S have a natural +// alignment of 64. +// OVR_ALIGNAS(32) S s; // Specifies that the instance s of struct S +// be aligned to an 32 byte boundary. +// OVR_ALIGNAS(32) struct T{ char array[16]; } t; // Specfies that the instance t of struct T +// have a natural alignment of 32. +// struct OVR_ALIGNAS(T) U{}; // Specifes that U be aligned the same as T. +// Supported only by C++11 compilers (see OVR_CPP_NO_ALIGNAS). +// +// size_t a = OVR_ALIGNOF(double); // Returns the natural alignment of the +// double type. +// size_t a = OVR_ALIGNOF(S); // Returns the natural alignment of the +// struct S type. +// +// Note: If C++11 alignas is supported, then alignas/OVR_ALIGNAS may take a const expression in +// addition to a constant. +// Note: The C11 Standard species the _Alignas keyword and alignas as a macro for it in + +#if !defined(OVR_ALIGNAS) +#if defined(OVR_CC_GNU) && !defined(OVR_CPP_NO_ALIGNAS) // If C++11 alignas is supported... +#define OVR_ALIGNAS(n) alignas(n) +#elif defined(__clang__) && !defined(OVR_CPP_NO_ALIGNAS) +#define OVR_ALIGNAS(n) alignas(n) +#elif defined(OVR_CC_GNU) || defined(__clang__) +#define OVR_ALIGNAS(n) __attribute__((aligned(n))) +#elif defined(OVR_CC_MSVC) || defined(OVR_CC_INTEL) +#define OVR_ALIGNAS(n) \ + __declspec(align(n)) // For Microsoft the alignment must be a literal integer. +#elif defined(OVR_CC_ARM) +#define OVR_ALIGNAS(n) __align(n) +#else +#error Need to define OVR_ALIGNAS +#endif +#endif + +#if !defined(OVR_ALIGNOF) +#if defined(OVR_CC_GNU) && !defined(OVR_CPP_NO_ALIGNOF) // If C++11 alignof is supported... +#define OVR_ALIGNOF(type) alignof(type) +#elif defined(__clang__) && !defined(OVR_CPP_NO_ALIGNOF) +#define OVR_ALIGNOF(type) alignof(type) +#elif defined(OVR_CC_GNU) || defined(__clang__) +#define OVR_ALIGNOF(type) ((size_t) __alignof__(type)) +#elif defined(OVR_CC_MSVC) || defined(OVR_CC_INTEL) +#define OVR_ALIGNOF(type) ((size_t) __alignof(type)) +#elif defined(OVR_CC_ARM) +#define OVR_ALIGNOF(type) ((size_t)__ALIGNOF__(type)) +#else +#error Need to define OVR_ALIGNOF +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_ASSUME / OVR_ANALYSIS_ASSUME +// +// This is a portable wrapper for VC++'s __assume and __analysis_assume. +// __analysis_assume is typically used to quell VC++ static analysis warnings. +// +// Example usage: +// void Test(char c){ +// switch(c){ +// case 'a': +// case 'b': +// case 'c': +// case 'd': +// break; +// default: +// OVR_ASSUME(0); // Unreachable code. +// } +// } +// +// size_t Test(char* str){ +// OVR_ANALYSIS_ASSUME(str != nullptr); +// return strlen(str); +// } + +#if !defined(OVR_ASSUME) +#if defined(OVR_CC_MSVC) +#define OVR_ASSUME(x) __assume(x) +#define OVR_ANALYSIS_ASSUME(x) __analysis_assume(!!(x)) +#else +#define OVR_ASSUME(x) +#define OVR_ANALYSIS_ASSUME(x) +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_RESTRICT +// +// Wraps the C99 restrict keyword in a portable way. +// C++11 and C++14 don't have restrict but this functionality is supported by +// all C++ compilers. +// +// Example usage: +// void* memcpy(void* OVR_RESTRICT s1, const void* OVR_RESTRICT s2, size_t n); + +#if !defined(OVR_RESTRICT) +#define OVR_RESTRICT __restrict // Currently supported by all compilers of significance to us. +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_NOEXCEPT / OVR_NOEXCEPT_IF(predicate) / OVR_NOEXCEPT_EXPR(expression) +// +// Implements a portable wrapper for C++11 noexcept. +// http://en.cppreference.com/w/cpp/language/noexcept +// +// Example usage: +// void Test() OVR_NOEXCEPT {} // This function doesn't throw. +// +// template +// void DoNothing() OVR_NOEXCEPT_IF(OVR_NOEXCEPT_EXPR(T())) // Throws an if and only if +// T::T(int) throws. +// { T t(3); } +// +#if !defined(OVR_NOEXCEPT) +#if defined(OVR_CPP_NO_NOEXCEPT) +#define OVR_NOEXCEPT +#define OVR_NOEXCEPT_IF(predicate) +#define OVR_NOEXCEPT_EXPR(expression) false +#else +#if defined(OVR_CC_MSVC) +// ignore warning C4577: 'noexcept' used with no exception handling mode specified; termination on +// exception is not guaranteed. Specify /EHsc +#pragma warning(disable : 4577) +#endif +#define OVR_NOEXCEPT noexcept +#define OVR_NOEXCEPT_IF(predicate) noexcept((predicate)) +#define OVR_NOEXCEPT_EXPR(expression) noexcept((expression)) +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_FINAL +// +// Wraps the C++11 final keyword in a portable way. +// http://en.cppreference.com/w/cpp/language/final +// +// Example usage: +// struct Test { virtual int GetValue() OVR_FINAL; }; + +#if !defined(OVR_FINAL) +#if defined(OVR_CC_MSVC) && (OVR_CC_VERSION < 1700) // VC++ 2012 and earlier +#define OVR_FINAL sealed +#elif defined(OVR_CPP_INHERITANCE_FINAL) +#define OVR_FINAL +#else +#define OVR_FINAL final +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_OVERRIDE +// +// Wraps the C++11 override keyword in a portable way. +// http://en.cppreference.com/w/cpp/language/override +// +// Example usage: +// struct Parent { virtual void Func(int); }; +// struct Child : public Parent { void Func(int) OVR_OVERRIDE; }; + +#if !defined(OVR_CPP11_ENABLED) +#define OVR_OVERRIDE +#elif !defined(OVR_OVERRIDE) +#if defined(OVR_CPP_OVERRIDE) +#define OVR_OVERRIDE +#else +#if (defined(_MSC_VER) && (_MSC_VER <= 1600)) +#pragma warning(disable : 4481) +#endif +#define OVR_OVERRIDE override +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_FINAL_OVERRIDE +// +// Wraps the C++11 final+override keywords (a common combination) in a portable way. +// +// Example usage: +// struct Parent { virtual void Func(); }; +// struct Child : public Parent { virtual void Func() OVR_FINAL_OVERRIDE; }; + +#if !defined(OVR_FINAL_OVERRIDE) +#define OVR_FINAL_OVERRIDE OVR_FINAL OVR_OVERRIDE +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_EXTERN_TEMPLATE +// +// Portable wrapper for C++11 extern template. This tells the compiler to not instantiate +// the template in the current translation unit, which can significantly speed up +// compilation and avoid problems due to two translation units compiling code with +// different settings. +// +// Example usage: +// OVR_EXTERN_TEMPLATE(class basic_string); // Nothing to do for non-C++11 compilers. + +#if !defined(OVR_EXTERN_TEMPLATE) +#if defined(OVR_CPP_EXTERN_TEMPLATE) +#define OVR_EXTERN_TEMPLATE(decl) +#else +#define OVR_EXTERN_TEMPLATE(decl) extern template decl +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_CONSTEXPR / OVR_CONSTEXPR_OR_CONST +// +// Portable wrapper for C++11 constexpr. Doesn't include C++14 relaxed constexpr, +// for which a different wrapper name is reserved. +// +// Example usage: +// OVR_CONSTEXPR int Test() { return 15; } // This can be optimized better by a C++11 +// compiler that supports constexpr. +// OVR_CONSTEXPR_OR_CONST float x = 3.14159f; // This can be optimized better by a C++11 +// compiler, but if not then at least make it const. + +#if !defined(OVR_CONSTEXPR) +#if defined(OVR_CPP_NO_CONSTEXPR) +#define OVR_CONSTEXPR +#else +#define OVR_CONSTEXPR constexpr +#endif +#endif + +#if !defined(OVR_CONSTEXPR_OR_CONST) +#if defined(OVR_CPP_NO_CONSTEXPR) +#define OVR_CONSTEXPR_OR_CONST const +#else +#define OVR_CONSTEXPR_OR_CONST constexpr +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_FUNCTION_DELETE / OVR_FUNCTION_DEFAULT +// +// Wraps the C++11 delete and default keywords in a way that allows for cleaner code +// while making for a better version of uncallable or default functions. +// +// Example usage: +// struct Test{ +// Test() OVR_FUNCTION_DEFAULT; // Non-C++11 compilers will require a separate +// definition for Test(). +// private: // Users should put OVR_FUNCTION_DELETE usage in a +// private +// void Uncallable() OVR_FUNCTION_DELETE; // area for compatibility with pre-C++11 +// compilers. +// }; + +#if defined(OVR_CPP_NO_DELETED_FUNCTIONS) +#define OVR_FUNCTION_DELETE +#else +#define OVR_FUNCTION_DELETE = delete +#endif + +#if defined(OVR_CPP_NO_DEFAULTED_FUNCTIONS) +#define OVR_FUNCTION_DEFAULT +#else +#define OVR_FUNCTION_DEFAULT = default +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_NON_COPYABLE +// +// Allows you to specify a class as being neither copy-constructible nor assignable, +// which is a commonly needed pattern in C++ programming. Classes with this declaration +// are required to be default constructible (as are most classes). For pre-C++11 +// compilers this macro declares a private section for the class, which will be +// inherited by whatever code is directly below the macro invocation by default. +// +// Example usage: +// struct Test { +// Test(); +// ... +// OVR_NON_COPYABLE(Test) +// }; + +#if !defined(OVR_NON_COPYABLE) +#if defined(OVR_CPP_NO_DELETED_FUNCTIONS) +#define OVR_NON_COPYABLE(Type) \ + private: \ + Type(const Type&); \ + void operator=(const Type&); +#else +#define OVR_NON_COPYABLE(Type) \ + Type(const Type&) = delete; \ + void operator=(const Type&) = delete; +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_BUILD_DEBUG +// +// Defines OVR_BUILD_DEBUG when the compiler default debug preprocessor is set. +// +// If you want to control the behavior of these flags, then explicitly define +// either -DOVR_BUILD_RELEASE or -DOVR_BUILD_DEBUG in the compiler arguments. + +#if !defined(OVR_BUILD_DEBUG) && !defined(OVR_BUILD_RELEASE) +#if defined(OVR_CC_MSVC) +#if defined(_DEBUG) +#define OVR_BUILD_DEBUG +#endif +#else +#if defined(DEBUG) +#define OVR_BUILD_DEBUG +#endif +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_popcnt +// +// Defines a C equivalent of the SSE4.2 _popcnt intrinsic, which is not available +// on older processors. These processors are not in our current recommended specificiation +// but we are seeing a number of users using them and encountering a crash on this. +// +inline int OVR_popcnt(unsigned int x) { + x = x - ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0F0F0F0F; + return (int)((x * 0x01010101) >> 24); +} diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ContainerAllocator.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ContainerAllocator.h new file mode 100644 index 0000000..8269501 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ContainerAllocator.h @@ -0,0 +1,244 @@ +/************************************************************************************ + +Filename : OVR_ContainerAllocator.h +Content : Template allocators and constructors for containers. +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_ContainerAllocator_h +#define OVR_ContainerAllocator_h + +#include +#include "OVR_Allocator.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(size_t size) { + return OVR_ALLOC(size); + } + + static void* Realloc(void* p, size_t 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 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 + static void ConstructAlt(void* p, const S& source) { + *(T*)p = source; + } + + static void ConstructArray(void*, size_t) {} + + static void ConstructArray(void* p, size_t count, const T& source) { + uint8_t* pdata = (uint8_t*)p; + for (size_t i = 0; i < count; ++i, pdata += sizeof(T)) + *(T*)pdata = source; + } + + static void ConstructArray(void* p, size_t count, const T* psource) { + memcpy(p, psource, sizeof(T) * count); + } + + static void Destruct(T*) {} + + static void DestructArray(T*, size_t) {} + + static void CopyArrayForward(T* dst, const T* src, size_t count) { + memmove(dst, src, count * sizeof(T)); + } + + static void CopyArrayBackward(T* dst, const T* src, size_t count) { + memmove(dst, src, count * sizeof(T)); + } + + static bool IsMovable() { + return true; + } +}; + +//----------------------------------------------------------------------------------- +// ***** ConstructorMov +// +// Correct C++ construction and destruction for movable objects +template +class ConstructorMov { + public: + static void Construct(void* p) { + OVR::Construct(p); + } + + static void Construct(void* p, const T& source) { + OVR::Construct(p, source); + } + + // Same as above, but allows for a different type of constructor. + template + static void ConstructAlt(void* p, const S& source) { + OVR::ConstructAlt(p, source); + } + + static void ConstructArray(void* p, size_t count) { + uint8_t* pdata = (uint8_t*)p; + for (size_t i = 0; i < count; ++i, pdata += sizeof(T)) + Construct(pdata); + } + + static void ConstructArray(void* p, size_t count, const T& source) { + uint8_t* pdata = (uint8_t*)p; + for (size_t i = 0; i < count; ++i, pdata += sizeof(T)) + Construct(pdata, source); + } + + static void ConstructArray(void* p, size_t count, const T* psource) { + uint8_t* pdata = (uint8_t*)p; + for (size_t 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, size_t count) { + for (size_t i = 0; i < count; ++i, ++p) + p->~T(); + } + + static void CopyArrayForward(T* dst, const T* src, size_t count) { + memmove(dst, src, count * sizeof(T)); + } + + static void CopyArrayBackward(T* dst, const T* src, size_t count) { + memmove(dst, src, count * sizeof(T)); + } + + static bool IsMovable() { + return true; + } +}; + +//----------------------------------------------------------------------------------- +// ***** ConstructorCPP +// +// Correct C++ construction and destruction for movable objects +template +class ConstructorCPP { + public: + static void Construct(void* p) { + OVR::Construct(p); + } + + static void Construct(void* p, const T& source) { + OVR::Construct(p, source); + } + + // Same as above, but allows for a different type of constructor. + template + static void ConstructAlt(void* p, const S& source) { + OVR::ConstructAlt(p, source); + } + + static void ConstructArray(void* p, size_t count) { + uint8_t* pdata = (uint8_t*)p; + for (size_t i = 0; i < count; ++i, pdata += sizeof(T)) + Construct(pdata); + } + + static void ConstructArray(void* p, size_t count, const T& source) { + uint8_t* pdata = (uint8_t*)p; + for (size_t i = 0; i < count; ++i, pdata += sizeof(T)) + Construct(pdata, source); + } + + static void ConstructArray(void* p, size_t count, const T* psource) { + uint8_t* pdata = (uint8_t*)p; + for (size_t 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, size_t count) { + for (size_t i = 0; i < count; ++i, ++p) + p->~T(); + } + + static void CopyArrayForward(T* dst, const T* src, size_t count) { + for (size_t i = 0; i < count; ++i) + dst[i] = src[i]; + } + + static void CopyArrayBackward(T* dst, const T* src, size_t count) { + for (size_t 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 +struct ContainerAllocator_POD : ContainerAllocatorBase, ConstructorPOD {}; +template +struct ContainerAllocator : ContainerAllocatorBase, ConstructorMov {}; +template +struct ContainerAllocator_CPP : ContainerAllocatorBase, ConstructorCPP {}; + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DLLHelper.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DLLHelper.h new file mode 100644 index 0000000..cd92b94 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DLLHelper.h @@ -0,0 +1,87 @@ +/************************************************************************************ +Filename : OVR_DLLHelper.h +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#pragma once + +#ifdef _WIN32 + +#include +#include + +namespace OVR { + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Example usage +// +// Write one of these for each of the modules (DLLs) you want to use functions from. +// The following class can be safely declared at global scope. +// class Kernel32API { +// public: +// decltype(GetModuleFileNameA)* getModuleFileNameA = dllHelper.Load("GetModuleFileNameA"); +// +// protected: +// DllHelper dllHelper{"Kernel32.dll"}; +// }; +// +// Use the class declared above: +// void main() { +// Kernel32API kernel32Api; +// +// if(kernel32Api.getModuleFileNameA) +// kernel32Api.getModuleFileNameA(NULL, path, sizeof(path)); +// } +/////////////////////////////////////////////////////////////////////////////////////////////////// + +// DllHelper instances can be declared at global scope in most cases. +class DllHelper { + public: + // Example moduleFileName: "kernel32.dll" + explicit DllHelper(const char* moduleFileName) : moduleHandle(::LoadLibraryA(moduleFileName)) {} + + ~DllHelper() { + ::FreeLibrary(moduleHandle); + } + + class ProcPtr { + public: + explicit ProcPtr(FARPROC ptr) : procPtr(ptr) {} + + template >> + operator T*() const { + return reinterpret_cast(procPtr); + } + + private: + FARPROC procPtr; + }; + + // Example proc name: "GetModuleFileName" + ProcPtr Load(const char* procName) const { + return ProcPtr(GetProcAddress(moduleHandle, procName)); + } + + protected: + HMODULE moduleHandle; +}; + +} // namespace OVR + +#endif // _WIN32 diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DebugHelp.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DebugHelp.cpp new file mode 100644 index 0000000..33108db --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DebugHelp.cpp @@ -0,0 +1,4036 @@ +/************************************************************************************ + +Filename : ExceptionHandler.cpp +Content : Platform-independent exception handling interface +Created : October 6, 2014 + +Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_DebugHelp.h" +#include "Logging/Logging_Library.h" +#include "OVR_Atomic.h" +#include "OVR_Std.h" +#include "OVR_SysFile.h" +#include "OVR_Types.h" +#include "OVR_UTF8Util.h" +#include "Util/Util_SystemGUI.h" + +#include +#include +#include + +#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) +#pragma warning(push, 0) +OVR_DISABLE_MSVC_WARNING(4091) // 'keyword' : ignored on left of 'type' when no variable is declared +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "OVR_Win32_IncludeWindows.h" +#pragma warning(pop) + +#pragma comment( \ + lib, "Psapi.lib") // To consider: It may be a problem to statically link to these libraries if +// the application at runtime intends to dynamically +#pragma comment( \ + lib, "ole32.lib") // link to a different version of the same library, and we are statically +// linked into that application instead of being a DLL. +#pragma comment(lib, "shell32.lib") +#pragma comment(lib, "Version.lib") + +// NtQueryInformation and THREAD_BASIC_INFORMATION are undocumented but frequently needed for +// digging into thread information. +typedef LONG(WINAPI* NtQueryInformationThreadFunc)(HANDLE, int, PVOID, ULONG, PULONG); + +struct THREAD_BASIC_INFORMATION { + LONG ExitStatus; + PVOID TebBaseAddress; + PVOID UniqueProcessId; + PVOID UniqueThreadId; + PVOID Priority; + PVOID BasePriority; +}; + +#ifndef UNW_FLAG_NHANDLER // Older Windows SDKs don't support this. +#define UNW_FLAG_NHANDLER 0 +#endif + +#elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) +#include +#include "sys/stat.h" +#if defined(OVR_OS_ANDROID) +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(OVR_OS_ANDROID) +#include +#endif +#include +//#include // Can't use this until we can ensure that we have an installed version of +// it. +#endif + +#if defined(OVR_OS_MAC) +#include // _NSGetExecutablePath +#endif + +#if !defined(MIN) +#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) +#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) +#endif + +OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized +OVR_DISABLE_MSVC_WARNING(4996) // This function or variable may be unsafe + +namespace OVR { + +void* GetInstructionAddress() { +#if defined(OVR_CC_MSVC) + return _ReturnAddress(); +#else // GCC, clang + return __builtin_return_address(0); +#endif +} + +// addressStrCapacity should be at least 2+16+1 = 19 characters. +static size_t SprintfAddress(char* addressStr, size_t addressStrCapacity, const void* pAddress) { +#if defined(OVR_CC_MSVC) +#if (OVR_PTR_SIZE >= 8) + return snprintf( + addressStr, + addressStrCapacity, + "0x%016I64x", + reinterpret_cast(pAddress)); // e.g. 0x0123456789abcdef +#else + return snprintf(addressStr, addressStrCapacity, "0x%08x", pAddress); // e.g. 0x89abcdef +#endif +#else +#if (OVR_PTR_SIZE >= 8) + return snprintf( + addressStr, addressStrCapacity, "%016lx", (uintptr_t)pAddress); // e.g. 0x0123456789abcdef +#else + return snprintf(addressStr, addressStrCapacity, "%08lx", (uintptr_t)pAddress); // e.g. 0x89abcdef +#endif +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +// GetMemoryAccess +// +// Returns MemoryAccess flags. Returns kMAUnknown for unknown access. +// +int GetMemoryAccess(const void* p) { + int memoryAccessFlags = 0; + +#if defined(_WIN32) + MEMORY_BASIC_INFORMATION mbi; + + if (VirtualQuery(p, &mbi, sizeof(mbi))) { + if (mbi.State == MEM_COMMIT) // If the memory page has been committed for use.... + { + if (mbi.Protect & PAGE_READONLY) + memoryAccessFlags |= kMARead; + if (mbi.Protect & PAGE_READWRITE) + memoryAccessFlags |= (kMARead | kMAWrite); + if (mbi.Protect & PAGE_EXECUTE) + memoryAccessFlags |= kMAExecute; + if (mbi.Protect & PAGE_EXECUTE_READ) + memoryAccessFlags |= (kMARead | kMAExecute); + if (mbi.Protect & PAGE_EXECUTE_READWRITE) + memoryAccessFlags |= (kMARead | kMAWrite | kMAExecute); + if (mbi.Protect & PAGE_EXECUTE_WRITECOPY) + memoryAccessFlags |= (kMAWrite | kMAExecute); + if (mbi.Protect & PAGE_WRITECOPY) + memoryAccessFlags |= kMAWrite; + } + } +#else + OVR_UNUSED(p); +#endif + + return memoryAccessFlags; +} + +/* Disabled until we can complete this, but leaving as a placeholder. + +/// Adds the given memory access flags to the existing access. +/// Size doesn't have to be in page-sized increments. +/// +bool AugmentMemoryAccess(const void* p, size_t size, int memoryAccessFlags) +{ + bool success = false; + + #ifdef _WIN32 + // This is tedious on Windows because it doesn't implement the memory access types as simple +flags. + // We have to deal with each of the types individually: + // 0, PAGE_NOACCESS, PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE, PAGE_EXECUTE_READ, + // PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY, PAGE_WRITECOPY + + MEMORY_BASIC_INFORMATION mbi; + + if(VirtualQuery(p, &mbi, sizeof(mbi))) + { + DWORD dwOldProtect = 0; + DWORD dwNewProtect = 0; + + (void)memoryAccessFlags; + + switch (mbi.Protect) + { + case 0: + break; + case PAGE_NOACCESS: + break; + case PAGE_READONLY: + break; + case PAGE_READWRITE: + break; + case PAGE_EXECUTE: + break; + case PAGE_EXECUTE_READ: + break; + case PAGE_EXECUTE_READWRITE: + break; + case PAGE_EXECUTE_WRITECOPY: + break; + case PAGE_WRITECOPY: + break; + } + + if(VirtualProtect(const_cast(p), size, dwNewProtect, &dwOldProtect)) + { + success = true; + } + } + #endif + + return success; +} +*/ + +// threadHandleStrCapacity should be at least 2+16+1 = 19 characters. +static size_t SprintfThreadHandle( + char* threadHandleStr, + size_t threadHandleStrCapacity, + const ThreadHandle& threadHandle) { + return SprintfAddress(threadHandleStr, threadHandleStrCapacity, threadHandle); +} + +// threadSysIdStrCapacity should be at least 20+4+16+2 = 42 characters. +static size_t SprintfThreadSysId( + char* threadSysIdStr, + size_t threadSysIdStrCapacity, + const ThreadSysId& threadSysId) { +#if defined(OVR_CC_MSVC) // Somebody could conceivably use VC++ with a different standard library + // that supports %ll. And VS2012+ also support %ll. + return snprintf( + threadSysIdStr, + threadSysIdStrCapacity, + "%I64u (0x%I64x)", + (uint64_t)threadSysId, + (uint64_t)threadSysId); // e.g. 5642 (0x160a) +#else + return snprintf( + threadSysIdStr, + threadSysIdStrCapacity, + "%llu (0x%llx)", + (unsigned long long)threadSysId, + (unsigned long long)threadSysId); +#endif +} + +void GetThreadStackBounds(void*& pStackBase, void*& pStackLimit, ThreadHandle threadHandle) { +#if defined(OVR_OS_WIN64) || defined(OVR_OS_WIN32) + ThreadSysId threadSysIdCurrent = (ThreadSysId)GetCurrentThreadId(); + ThreadSysId threadSysId; + NT_TIB* pTIB = nullptr; + + if (threadHandle == OVR_THREADHANDLE_INVALID) + threadSysId = threadSysIdCurrent; + else + threadSysId = ConvertThreadHandleToThreadSysId(threadHandle); + + if (threadSysId == threadSysIdCurrent) { +#if (OVR_PTR_SIZE == 4) + // Need to use __asm__("movl %%fs:0x18, %0" : "=r" (pTIB) : : ); under gcc/clang. + __asm { + mov eax, fs:[18h] + mov pTIB, eax + } +#else + pTIB = (NT_TIB*)NtCurrentTeb(); +#endif + } else { +#if (OVR_PTR_SIZE == 4) + // It turns out we don't need to suspend the thread when getting SegFs/SegGS, as that's + // constant per thread and doesn't require the thread to be suspended. + // SuspendThread((HANDLE)threadHandle); + + CONTEXT context; + memset(&context, 0, sizeof(context)); + context.ContextFlags = CONTEXT_SEGMENTS; + + if (::GetThreadContext( + (HANDLE)threadHandle, &context)) // Requires THREAD_QUERY_INFORMATION privileges. + { + LDT_ENTRY ldtEntry; + if (GetThreadSelectorEntry( + threadHandle, context.SegFs, &ldtEntry)) // Requires THREAD_QUERY_INFORMATION + pTIB = (NT_TIB*)((ldtEntry.HighWord.Bits.BaseHi << 24 ) | (ldtEntry.HighWord.Bits.BaseMid << 16) | ldtEntry.BaseLow); + } + +// ResumeThread((HANDLE)threadHandle); +#else + // We cannot use GetThreadSelectorEntry or Wow64GetThreadSelectorEntry on Win64. + // We need to read the SegGs qword at offset 0x30. We can't use pTIB = + // (NT_TIB*)__readgsqword(0x30) because that reads only the current setGs offset. + // mov rax, qword ptr gs:[30h] + // mov qword ptr [pTIB],rax + // In the meantime we rely on the NtQueryInformationThread function. + + static NtQueryInformationThreadFunc spNtQueryInformationThread = nullptr; + + if (!spNtQueryInformationThread) { + HMODULE hNTDLL = GetModuleHandleW(L"ntdll.dll"); + spNtQueryInformationThread = (NtQueryInformationThreadFunc)(uintptr_t)GetProcAddress( + hNTDLL, "NtQueryInformationThread"); + } + + if (spNtQueryInformationThread) { + THREAD_BASIC_INFORMATION tbi; + + memset(&tbi, 0, sizeof(tbi)); + LONG result = spNtQueryInformationThread( + threadHandle, + 0, + &tbi, + sizeof(tbi), + nullptr); // Requires THREAD_QUERY_INFORMATION privileges + if (result == 0) + pTIB = (NT_TIB*)tbi.TebBaseAddress; + } +#endif + } + + if (pTIB && (GetMemoryAccess(pTIB) & kMARead)) { + pStackBase = (void*)pTIB->StackBase; + pStackLimit = (void*)pTIB->StackLimit; + } else { + pStackBase = nullptr; + pStackLimit = nullptr; + } + +#elif defined(OVR_OS_APPLE) + if (!threadHandle) + threadHandle = pthread_self(); + + pStackBase = pthread_get_stackaddr_np((pthread_t)threadHandle); + size_t stackSize = pthread_get_stacksize_np((pthread_t)threadHandle); + pStackLimit = (void*)((size_t)pStackBase - stackSize); + +#elif defined(OVR_OS_UNIX) + pStackBase = nullptr; + pStackLimit = nullptr; + + pthread_attr_t threadAttr; + pthread_attr_init(&threadAttr); + +#if defined(OVR_OS_LINUX) + int result = pthread_getattr_np((pthread_t)threadHandle, &threadAttr); +#else + int result = pthread_attr_get_np((pthread_t)threadHandle, &threadAttr); +#endif + + if (result == 0) { + size_t stackSize = 0; + result = pthread_attr_getstack(&threadAttr, &pStackLimit, &stackSize); + + if (result == 0) + pStackBase = + (void*)((uintptr_t)pStackLimit + stackSize); // We assume the stack grows downward. + } + +#endif +} + +bool KillCdeclFunction( + void* pFunction, + int32_t functionReturnValue, + SavedFunction* pSavedFunction) { +#if defined(OVR_OS_MS) + // The same implementation works for both 32 bit x86 and 64 bit x64. + DWORD dwOldProtect; + const uint8_t size = + ((functionReturnValue == 0) + ? 3 + : ((functionReturnValue == 1) + ? 5 + : 6)); // This is the number of instruction bytes we overwrite below. + + if (VirtualProtect(pFunction, size, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { + if (pSavedFunction) // If the user wants to save the implementation for later restoration... + { + pSavedFunction->Function = pFunction; + pSavedFunction->Size = size; + memcpy(pSavedFunction->Data, pFunction, pSavedFunction->Size); + + const uint8_t opCode = *reinterpret_cast(pFunction); + if (opCode == 0xe9) // If the function was a 32 bit relative jump to the real function (which + // is a common thing)... + { + int32_t jumpOffset; + memcpy(&jumpOffset, reinterpret_cast(pFunction) + 1, sizeof(int32_t)); + pSavedFunction->FunctionImplementation = + reinterpret_cast(pFunction) + 5 + jumpOffset; + } else + pSavedFunction->FunctionImplementation = nullptr; + } + + if (functionReturnValue == 0) // We write 3 bytes. + { + const uint8_t instructionBytes[] = {0x33, 0xc0, 0xc3}; // xor eax, eax; ret + memcpy(pFunction, instructionBytes, sizeof(instructionBytes)); + } else if (functionReturnValue == 1) // We write 5 bytes. + { + uint8_t instructionBytes[] = {0x33, 0xc0, 0xff, 0xc0, 0xc3}; // xor eax, eax; inc eax; ret + // -- note that this is smaller + // than (mov eax 0x00000001; + // ret), which takes 6 bytes. + memcpy(pFunction, instructionBytes, sizeof(instructionBytes)); + } else // We write 6 bytes. + { + uint8_t instructionBytes[] = {0xb8, 0x00, 0x00, 0x00, 0x00, 0xc3}; // mov eax, 0x00000000; ret + memcpy( + instructionBytes + 1, + &functionReturnValue, + sizeof(int32_t)); // mov eax, functionReturnValue; ret + memcpy(pFunction, instructionBytes, sizeof(instructionBytes)); + } + + VirtualProtect(pFunction, size, dwOldProtect, &dwOldProtect); + return true; + } +#else + OVR_UNUSED3(pFunction, functionReturnValue, pSavedFunction); +#endif + + return false; +} + +bool KillCdeclFunction(void* pFunction, SavedFunction* pSavedFunction) { +#if defined(OVR_OS_MS) + // The same implementation works for both 32 bit x86 and 64 bit x64. + DWORD dwOldProtect; + const uint8_t size = 1; + + if (VirtualProtect(pFunction, size, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { + if (pSavedFunction) // If the user wants to save the implementation for later restoration... + { + pSavedFunction->Function = pFunction; + pSavedFunction->Size = size; + memcpy(pSavedFunction->Data, pFunction, pSavedFunction->Size); + + const uint8_t opCode = *reinterpret_cast(pFunction); + if (opCode == 0xe9) // If the function was a 32 bit relative jump to the real function (which + // is a common thing)... + { + int32_t jumpOffset; + memcpy(&jumpOffset, reinterpret_cast(pFunction) + 1, sizeof(int32_t)); + pSavedFunction->FunctionImplementation = + reinterpret_cast(pFunction) + 5 + jumpOffset; + } else + pSavedFunction->FunctionImplementation = nullptr; + } + + const uint8_t instructionBytes[] = {0xc3}; // asm ret + memcpy(pFunction, instructionBytes, sizeof(instructionBytes)); + VirtualProtect(pFunction, size, dwOldProtect, &dwOldProtect); + return true; + } + +#else + OVR_UNUSED2(pFunction, pSavedFunction); +#endif + + return false; +} + +bool RedirectCdeclFunction( + void* pFunction, + const void* pDestFunction, + OVR::SavedFunction* pSavedFunction) { +#if defined(_WIN32) + // The same implementation works for both 32 bit x86 and 64 bit x64. + // We implement this as a 32 bit relative jump from pFunction to pDestFunction. + // This takes five bytes and is of the form: + // E9 <32bit offset> + // This can work only when the pDestFunction is within 32 bits of pFunction. That will always be + // the case when redirecting to a new location within the same module. But on 64 bit Windows, it + // may be that pFunction is in one module and pDestFunction is in another module (e.g. DLL) with + // an address that is farther than 32 bits away. In that case we need to instead do a 64 bit + // absolute jump or if there isn't enough space for those instruction bytes then we need to do a + // near jump to some nearby location where we can have a full 64 bit absolute jump. It turns out + // that in the case of calling DLL functions the absolute-jump-through-64bit-data 0xff instruction + // is used. We could change that 64 bit data. + +#if defined(_WIN64) + if (abs((intptr_t)pDestFunction - (intptr_t)pFunction) >= ((intptr_t)1 << 31)) { + // A 64 bit jump would be required in this case, which we currently don't support, but could + // with some effort. + return false; + } +#endif + + DWORD dwOldProtect; + const uint8_t size = 5; + + if (VirtualProtect(pFunction, size, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { + if (pSavedFunction) // If the user wants to save the implementation for later restoration... + { + pSavedFunction->Function = pFunction; + pSavedFunction->Size = size; + memcpy(pSavedFunction->Data, pFunction, pSavedFunction->Size); + + const uint8_t opCode = *reinterpret_cast(pFunction); + if (opCode == 0xe9) // If the function was a 32 bit relative jump to the real function (which + // is a common thing)... + { + int32_t jumpOffset; + memcpy(&jumpOffset, reinterpret_cast(pFunction) + 1, sizeof(int32_t)); + pSavedFunction->FunctionImplementation = + reinterpret_cast(pFunction) + 5 + jumpOffset; + } else + pSavedFunction->FunctionImplementation = nullptr; + } + + union Rel32Bytes { + int32_t rel32; + uint8_t bytes[4]; + } rel32Bytes = { + ((int32_t)pDestFunction - (int32_t)pFunction) - + size}; // -size because the offset is relative to after the 5 byte opcode sequence. + + uint8_t instructionBytes[] = {0xe9, + rel32Bytes.bytes[0], + rel32Bytes.bytes[1], + rel32Bytes.bytes[2], + rel32Bytes.bytes[3]}; // asm jmp + memcpy(pFunction, instructionBytes, sizeof(instructionBytes)); + VirtualProtect(pFunction, size, dwOldProtect, &dwOldProtect); + return true; + } + +#else + OVR_UNUSED3(pFunction, pDestFunction, pSavedFunction); +#endif + + return false; +} + +bool RestoreCdeclFunction(SavedFunction* pSavedFunction) { + if (pSavedFunction && pSavedFunction->Size) { +#if defined(OVR_OS_MS) + DWORD dwOldProtect; + + if (VirtualProtect( + pSavedFunction->Function, + pSavedFunction->Size, + PAGE_EXECUTE_READWRITE, + &dwOldProtect)) { + memcpy(pSavedFunction->Function, pSavedFunction->Data, pSavedFunction->Size); + VirtualProtect(pSavedFunction->Function, pSavedFunction->Size, dwOldProtect, &dwOldProtect); + return true; + } +#else + OVR_UNUSED(pSavedFunction); +#endif + } + + return false; +} + +CopiedFunction::CopiedFunction(const void* pFunction, size_t size) : Function(nullptr) { + if (pFunction) + Copy(pFunction, size); +} + +CopiedFunction::~CopiedFunction() { + // To consider: We may have use cases in which we want to intentionally not free the + // memory and instead let it live beyond our lifetime so that it can still be called. + Free(); +} + +const void* CopiedFunction::GetRealFunctionLocation(const void* pFunction) { + // It turns out that many functions are really jumps to the actual function code. + // These jumps are typically implemented with the E9 machine opcode, followed by + // an int32 relative jump distance. We need to handle that case. + + // If the code is executable but not readable, we'll need to make it readable. + bool readable = (pFunction && (GetMemoryAccess(pFunction) & OVR::kMARead) != 0); + + if (!readable) { + return nullptr; + + // To do: Implement this: + // readable = AugmentMemoryAccess(opCode, 1, OVR::kMARead); + } + + const uint8_t* opCode = static_cast(pFunction); + + if (*opCode == 0xE9) // If this is the E9 relative jmp instuction (which happens to be always used + // for local-module trampolining by VC++)... + { + int32_t jumpDistance; + memcpy(&jumpDistance, opCode + 1, sizeof(jumpDistance)); + + pFunction = (opCode + 5 + jumpDistance); // +5 because the jmp is relative to the end of the + // five byte 0xE9 instruction. + // Is it possible that pFunction points to another trampoline? I haven't seen such a thing, + // but it could be handled by a loop here or simply goto the opCode assignment line above. + } + + return pFunction; +} + +const void* CopiedFunction::Copy(const void* pFunction, size_t size) { + Free(); + +#if defined(_WIN32) + if (size == 0) // If we don't know the size... + { + // When debug symbols are present, we could look up the function size. + // On x64 we can possibly look up the size via the stack unwind data. + // On x86 and x64 we could possibly look for return statements while + // also checking if pFunction is simply a short trampoline. + size = 4096; // For our current uses this is good enough. But it's not general. + } + + void* pNewFunction = + VirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); + + if (pNewFunction) { + // It turns out that (especially in debug builds), pFunction may be a + // trampoline (unilateral jump) to the real function implementation elsewhere. + // We need to copy the real implementation and not the jump, at least if the + // jump is a relative jump (usually the case) and not an absolute jump. + const void* pRealFunction = GetRealFunctionLocation(pFunction); + + memcpy(pNewFunction, pRealFunction, size); + Function = pNewFunction; + } +#else + OVR_UNUSED2(pFunction, size); +#endif + + return Function; +} + +void CopiedFunction::Free() { + if (Function) { +#if defined(_WIN32) + VirtualFree(Function, 0, MEM_RELEASE); +#endif + + Function = nullptr; + } +} + +static bool DebuggerForcedNotPresent = false; + +// Force OVRIsDebuggerPresent to return false +void ForceDebuggerNotPresent() { + DebuggerForcedNotPresent = true; +} + +// Allow debugger check to proceded as normal +void ClearDebuggerNotPresent() { + DebuggerForcedNotPresent = false; +} + +bool OVRIsDebuggerPresent() { + if (DebuggerForcedNotPresent) { + return false; + } +#if defined(OVR_OS_MS) + return ::IsDebuggerPresent() != 0; + +#elif defined(OVR_OS_APPLE) + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; + struct kinfo_proc info; + size_t size = sizeof(info); + + info.kp_proc.p_flag = 0; + sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0); + + return ((info.kp_proc.p_flag & P_TRACED) != 0); + +#elif defined(PT_TRACE_ME) && !defined(OVR_OS_ANDROID) + return (ptrace(PT_TRACE_ME, 0, 1, 0) < 0); + +#elif (defined(OVR_OS_LINUX) || defined(OVR_OS_BSD)) && !defined(OVR_OS_ANDROID) + // This works better than the PT_TRACE_ME approach, but causes the debugger to get + // confused when executed under a debugger. + // It also presents this problem: + // http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html + // When the application calls fork() from a signal handler and any of the + // fork handlers registered by pthread_atfork() calls a function that is + // not asynch-signal-safe, the behavior is undefined. + // We may need to provide two pathways within this function, one of which + // doesn't fork and instead uses PT_TRACE_ME. + int pid = fork(); + int status; + bool present = false; + + if (pid == -1) // If fork failed... + { + // perror("fork"); + } else if (pid == 0) // If we are the child process... + { + int ppid = getppid(); + +#if defined(OVR_OS_LINUX) + if (ptrace(PTRACE_ATTACH, ppid, nullptr, nullptr) == 0) +#else + if (ptrace(PT_ATTACH, ppid, nullptr, nullptr) == 0) +#endif + { + waitpid(ppid, nullptr, 0); + +#if defined(OVR_OS_LINUX) + ptrace(PTRACE_CONT, getppid(), nullptr, nullptr); + ptrace(PTRACE_DETACH, getppid(), nullptr, nullptr); +#else + ptrace(PT_CONTINUE, getppid(), nullptr, nullptr); + ptrace(PT_DETACH, getppid(), nullptr, nullptr); +#endif + } else { + // ptrace failed so the debugger is present. + present = true; + } + + exit(present ? 1 : 0); // The WEXITSTATUS call below will read this exit value. + } else // Else we are the original process. + { + waitpid(pid, &status, 0); + present = + WEXITSTATUS(status) ? true : false; // Read the exit value from the child's call to exit. + } + + return present; + +#else + return false; +#endif +} + +// Exits the process with the given exit code. +void ExitProcess(intptr_t processReturnValue) { + exit((int)processReturnValue); +} + +// Note that we can't just return sizeof(void*) == 8, as we may have the case of a +// 32 bit app running on a 64 bit operating system. +static bool Is64BitOS() { +#if (OVR_PTR_SIZE >= 8) + return true; + +#elif defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) + BOOL is64BitOS = FALSE; + bool IsWow64ProcessPresent = + (GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process") != nullptr); + return (IsWow64ProcessPresent && IsWow64Process(GetCurrentProcess(), &is64BitOS) && is64BitOS); + +#elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) + utsname utsName; + memset(&utsName, 0, sizeof(utsName)); + return (uname(&utsName) == 0) && (strcmp(utsName.machine, "x86_64") == 0); + +#else + return false; +#endif +} + +// The output will always be 0-terminated. +// Returns the required strlen of the output. +// Returns (size_t)-1 on failure. +size_t SpawnShellCommand(const char* shellCommand, char* output, size_t outputCapacity) { +#if defined(OVR_OS_UNIX) || defined(OVR_OS_APPLE) + FILE* pFile = popen(shellCommand, "r"); + + if (pFile) { + size_t requiredLength = 0; + char buffer[256]; + + while (fgets(buffer, sizeof(buffer), pFile)) // fgets 0-terminates the buffer. + { + size_t length = OVR_strlen(buffer); + requiredLength += length; + + if (outputCapacity) { + OVR_strlcpy(output, buffer, outputCapacity); + length = MIN(outputCapacity, length); + } + + output += length; + outputCapacity -= length; + } + + pclose(pFile); + return requiredLength; + } +#else + // To do. Properly solving this on Windows requires a bit of code. + OVR_UNUSED(shellCommand); + OVR_UNUSED(output); + OVR_UNUSED(outputCapacity); +#endif + + return (size_t)-1; +} + +// Retrieves the name of the given thread. +// To do: Move this to OVR_Threads.h +bool GetThreadName(OVR::ThreadHandle threadHandle, char* threadName, size_t threadNameCapacity) { +#if (defined(OVR_OS_APPLE) || defined(OVR_OS_LINUX)) && !defined(OVR_OS_ANDROID) + int result = pthread_getname_np((pthread_t)threadHandle, threadName, threadNameCapacity); + if (result == 0) + return true; +#else + // This is not currently possible on Windows, as only the debugger stores the thread name. We + // could potentially use a vectored + // exception handler to catch all thread name exceptions (0x406d1388) and record them in a static + // list at runtime. To detect + // thread exit we could use WMI Win32_ThreadStopTrace. Maintain a list of thread names between + // these two events. + OVR_UNUSED(threadHandle); + OVR_UNUSED(threadNameCapacity); +#endif + + if (threadNameCapacity) + threadName[0] = 0; + + return false; +} + +OVR::ThreadSysId ConvertThreadHandleToThreadSysId(OVR::ThreadHandle threadHandle) { +#if defined(OVR_OS_WIN64) + return (OVR::ThreadSysId)::GetThreadId( + threadHandle); // Requires THREAD_QUERY_INFORMATION privileges. + +#elif defined(OVR_OS_WIN32) + typedef DWORD(WINAPI * GetThreadIdFunc)(HANDLE); + + static volatile bool sInitialized = false; + static GetThreadIdFunc spGetThreadIdFunc = nullptr; + static NtQueryInformationThreadFunc spNtQueryInformationThread = nullptr; + + if (!sInitialized) { + HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); + if (hKernel32) + spGetThreadIdFunc = (GetThreadIdFunc)(uintptr_t)GetProcAddress(hKernel32, "GetThreadId"); + + if (!spGetThreadIdFunc) { + HMODULE hNTDLL = GetModuleHandleA("ntdll.dll"); + + if (hNTDLL) + spNtQueryInformationThread = (NtQueryInformationThreadFunc)(uintptr_t)GetProcAddress( + hNTDLL, "NtQueryInformationThread"); + } + + sInitialized = true; + } + + if (spGetThreadIdFunc) + return (OVR::ThreadSysId)spGetThreadIdFunc(threadHandle); + + if (spNtQueryInformationThread) { + THREAD_BASIC_INFORMATION tbi; + + if (spNtQueryInformationThread(threadHandle, 0, &tbi, sizeof(tbi), nullptr) == 0) + return (OVR::ThreadSysId)tbi.UniqueThreadId; + } + + return OVR_THREADSYSID_INVALID; + +#elif defined(OVR_OS_APPLE) || defined(OVR_OS_LINUX) + + // I believe we can usually (though not portably) intepret the pthread_t as a pointer to a struct + // whose first member is a lwp id. + OVR_UNUSED(threadHandle); + return OVR_THREADSYSID_INVALID; + +#else + OVR_UNUSED(threadHandle); + return OVR_THREADSYSID_INVALID; +#endif +} + +OVR::ThreadHandle ConvertThreadSysIdToThreadHandle(OVR::ThreadSysId threadSysId) { + if (threadSysId == OVR_THREADSYSID_INVALID) + return OVR_THREADHANDLE_INVALID; + +#if defined(OVR_OS_MS) + // We currently request the given rights because that's what users of this function typically need + // it for. Ideally there would + // be a way to specify the requested rights in order to avoid the problem if we need only a subset + // of them but can't get it. + // The solution we use below to try opening with successively reduced rights will work for our + // uses here but isn't a good general solution to this. + OVR::ThreadHandle threadHandle = ::OpenThread( + THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, + TRUE, + (DWORD)threadSysId); + + if (threadHandle == OVR_THREADHANDLE_INVALID) { + threadHandle = + ::OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); + + if (threadHandle == OVR_THREADHANDLE_INVALID) + threadHandle = ::OpenThread(THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); + } + + return threadHandle; +#else + return (ThreadHandle)threadSysId; +#endif +} + +void FreeThreadHandle(OVR::ThreadHandle threadHandle) { +#if defined(OVR_OS_MS) + if (threadHandle != OVR_THREADHANDLE_INVALID) + ::CloseHandle(threadHandle); +#else + OVR_UNUSED(threadHandle); +#endif +} + +OVR::ThreadSysId GetCurrentThreadSysId() { +#if defined(OVR_OS_MS) + return ::GetCurrentThreadId(); +#else + return (ThreadSysId)pthread_self(); +#endif +} + +static void GetCurrentProcessFilePath(char* appPath, size_t appPathCapacity) { + appPath[0] = 0; + +#if defined(OVR_OS_MS) + wchar_t pathW[OVR_MAX_PATH]; + GetModuleFileNameW(0, pathW, (DWORD)OVR_ARRAY_COUNT(pathW)); + + auto requiredUTF8Length = OVR::UTF8Util::Strlcpy(appPath, appPathCapacity, pathW); + if (requiredUTF8Length >= appPathCapacity) { + appPath[0] = 0; + } +#elif defined(OVR_OS_APPLE) + struct BunderFolder { + // Returns true if pStr ends with pFind, case insensitively. + // To do: Move OVR_striend to OVRKernel/Std.h + static bool OVR_striend( + const char* pStr, + const char* pFind, + size_t strLength = (size_t)-1, + size_t findLength = (size_t)-1) { + if (strLength == (size_t)-1) + strLength = OVR_strlen(pStr); + if (findLength == (size_t)-1) + findLength = OVR_strlen(pFind); + if (strLength >= findLength) + return (OVR_stricmp(pStr + strLength - findLength, pFind) == 0); + return false; + } + + static bool IsBundleFolder(const char* filePath) { + // https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html#//apple_ref/doc/uid/10000123i-CH100-SW1 + static const char* extensionArray[] = {".app", ".bundle", ".framework", ".plugin", ".kext"}; + + for (size_t i = 0; i < OVR_ARRAY_COUNT(extensionArray); i++) { + if (OVR_striend(filePath, extensionArray[i])) + return true; + } + + return false; + } + }; + + char appPathTemp[PATH_MAX]; + uint32_t appPathTempCapacity32 = PATH_MAX; + size_t requiredStrlen = appPathCapacity; + + if (_NSGetExecutablePath(appPathTemp, &appPathTempCapacity32) == 0) { + char appPathTempReal[PATH_MAX]; + + if (realpath( + appPathTemp, + appPathTempReal)) // If the path is a symbolic link, this converts it to the real path. + { + // To consider: Enable reading the internal bundle executable path. An application on Mac may + // in + // fact be within a file bundle, which is an private file system within a file. With Objective + // C + // we could use: [[NSWorkspace sharedWorkspace] isFilePackageAtPath:fullPath]; + bool shouldReadTheBunderPath = false; + + if (shouldReadTheBunderPath) { + // We recursively call dirname() until we find .app/.bundle/.plugin as a directory name. + OVR_strlcpy(appPathTemp, appPathTempReal, OVR_ARRAY_COUNT(appPathTemp)); + bool found = BunderFolder::IsBundleFolder(appPathTemp); + + while (!found && OVR_strcmp(appPathTemp, ".") && OVR_strcmp(appPathTemp, "/")) { + OVR_strlcpy(appPathTemp, dirname(appPathTemp), OVR_ARRAY_COUNT(appPathTemp)); + found = BunderFolder::IsBundleFolder(appPathTemp); + } + + if (found) // If somewhere above we found a parent bundle container... + requiredStrlen = OVR_strlcpy(appPath, appPathTemp, appPathCapacity); + else + requiredStrlen = OVR_strlcpy(appPath, appPathTempReal, appPathCapacity); + } else { + requiredStrlen = OVR_strlcpy(appPath, appPathTempReal, appPathCapacity); + } + } + } + + if (requiredStrlen >= appPathCapacity) + appPath[0] = '\0'; + +#elif defined(OVR_OS_LINUX) + ssize_t length = readlink("/proc/self/exe", appPath, appPathCapacity); + + if ((length != -1) && ((size_t)length < (appPathCapacity - 1))) { + appPath[length] = '\0'; + } +#endif +} + +static const char* GetFileNameFromPath(const char* filePath) { + const char* lastPathSeparator = strrchr(filePath, '/'); + +#if defined(OVR_OS_MS) + // Microsoft APIs are inconsistent with respect to allowing / as a path separator. + const char* candidate = strrchr(filePath, '\\'); + + if (candidate > lastPathSeparator) { + lastPathSeparator = candidate; + } +#endif + + if (lastPathSeparator) + return lastPathSeparator + 1; + + return filePath; +} + +static void FormatDateTime( + char* buffer, + size_t bufferCapacity, + time_t timeValue, + bool getDate, + bool getTime, + bool localDateTime, + bool fileNameSafeCharacters = false) { + char temp[128]; + const tm* pTime = localDateTime ? localtime(&timeValue) : gmtime(&timeValue); + + if (bufferCapacity) + buffer[0] = 0; + + if (getDate) { + const char* format = fileNameSafeCharacters ? "%Y-%m-%d" : "%Y/%m/%d"; + strftime(temp, OVR_ARRAY_COUNT(temp), format, pTime); + OVR::OVR_strlcpy(buffer, temp, bufferCapacity); + } + + if (getTime) { + const char* format = fileNameSafeCharacters ? " %H.%M.%S" : " %H:%M:%S"; + strftime(temp, OVR_ARRAY_COUNT(temp), (getDate ? format : format + 1), pTime); + OVR::OVR_strlcat(buffer, temp, bufferCapacity); + } +} + +void GetOSVersionName(char* versionName, size_t versionNameCapacity) { +#if defined(OVR_OS_MS) + const char* name = "unknown"; + + RTL_OSVERSIONINFOEXW vi = {}; + vi.dwOSVersionInfoSize = sizeof(vi); + + // We use RtlGetVersion instead of GetVersionExW because the latter doesn't actually return the + // version of Windows, it returns + // the highest version of Windows that this application's manifest declared that it was compatible + // with. We want to know the + // real version of Windows and so need to fall back to RtlGetVersion. + LONG(WINAPI * pfnRtlGetVersion)(RTL_OSVERSIONINFOEXW*); + pfnRtlGetVersion = (decltype(pfnRtlGetVersion))(uintptr_t)GetProcAddress( + GetModuleHandleW((L"ntdll.dll")), "RtlGetVersion"); + + if (pfnRtlGetVersion) // This will virtually always succeed. + { + if (pfnRtlGetVersion(&vi) != 0) // pfnRtlGetVersion will virtually always succeed. + memset(&vi, 0, sizeof(vi)); + } + + if (vi.dwMajorVersion == 10) { + if (vi.dwMinorVersion == 0) { + if (vi.dwBuildNumber >= 10586) { + if (vi.wProductType == VER_NT_WORKSTATION) + name = "Windows 10 TH2+"; + else + name = "Windows Server 2016 Technical Preview TH2+"; + } else { + if (vi.wProductType == VER_NT_WORKSTATION) + name = "Windows 10"; + else + name = "Windows Server 2016 Technical Preview"; + } + } else { + // Unknown recent version. + if (vi.wProductType == VER_NT_WORKSTATION) + name = "Windows 10 Unknown"; + else + name = "Windows Server 2016 Unknown"; + } + } else if (vi.dwMajorVersion >= 7) { + // Unknown recent version. + } else if (vi.dwMajorVersion >= 6) { + if (vi.dwMinorVersion >= 4) + name = "Windows 10 Pre Released"; + else if (vi.dwMinorVersion >= 3) { + if (vi.wProductType == VER_NT_WORKSTATION) + name = "Windows 8.1"; + else + name = "Windows Server 2012 R2"; + } else if (vi.dwMinorVersion >= 2) { + if (vi.wProductType == VER_NT_WORKSTATION) + name = "Windows 8"; + else + name = "Windows Server 2012"; + } else if (vi.dwMinorVersion >= 1) { + if (vi.wProductType == VER_NT_WORKSTATION) + name = "Windows 7"; + else + name = "Windows Server 2008 R2"; + } else { + if (vi.wProductType == VER_NT_WORKSTATION) + name = "Windows Vista"; + else + name = "Windows Server 2008"; + } + } else if (vi.dwMajorVersion >= 5) { + if (vi.dwMinorVersion == 0) + name = "Windows 2000"; + else if (vi.dwMinorVersion == 1) + name = "Windows XP"; + else // vi.dwMinorVersion == 2 + { + if (GetSystemMetrics(SM_SERVERR2) != 0) + name = "Windows Server 2003 R2"; + else if (vi.wSuiteMask & VER_SUITE_WH_SERVER) + name = "Windows Home Server"; + if (GetSystemMetrics(SM_SERVERR2) == 0) + name = "Windows Server 2003"; + else + name = "Windows XP Professional x64 Edition"; + } + } else + name = "Windows 98 or earlier"; + + OVR_strlcpy(versionName, name, versionNameCapacity); + + if (vi.szCSDVersion[0]) // If the version is reporting a service pack string... + { + OVR_strlcat(versionName, ", ", versionNameCapacity); + + char servicePackname8[128]; + OVR::UTF8Util::Strlcpy(servicePackname8, sizeof(servicePackname8), vi.szCSDVersion); + OVR_strlcat(versionName, servicePackname8, versionNameCapacity); + } +#elif defined(OVR_OS_UNIX) || defined(OVR_OS_APPLE) + utsname utsName; + memset(&utsName, 0, sizeof(utsName)); + + if (uname(&utsName) == 0) + snprintf( + versionName, + versionNameCapacity, + "%s %s %s %s", + utsName.sysname, + utsName.release, + utsName.version, + utsName.machine); + else + snprintf(versionName, versionNameCapacity, "Unix"); +#endif +} + +void CreateException(CreateExceptionType exceptionType) { + char buffer[1024] = {}; + + switch (exceptionType) { + case kCETAccessViolation: { + int* pNullPtr = reinterpret_cast((rand() / 2) / RAND_MAX); + pNullPtr[0] = 0; // This line should generate an exception. + sprintf(buffer, "%p", pNullPtr); + break; + } + + case kCETDivideByZero: { + int smallValue = 1; + int largeValue = (1000 * exceptionType); + int divByZero = (smallValue / largeValue); // This line should generate a div/0 exception. + sprintf(buffer, "%d", divByZero); + break; + } + + case kCETIllegalInstruction: { +#if defined(OVR_CPU_X86) || \ + (defined(OVR_CPU_X86_64) && \ + !defined(OVR_CC_MSVC)) // (if x86) or (if x64 and any computer but VC++)... +#if defined(OVR_CC_MSVC) + __asm ud2 +#else // e.g. GCC + asm volatile("ud2"); +#endif + +#elif defined(OVR_CPU_X86_64) && (defined(OVR_OS_MS) && defined(PAGE_EXECUTE_READWRITE)) + // VC++ for x64 doesn't support inline asm. + void* pVoid = _AddressOfReturnAddress(); + void** ppVoid = reinterpret_cast(pVoid); + void* pReturnAddress = *ppVoid; + DWORD dwProtectPrev = 0; + + if (VirtualProtect( + pReturnAddress, + 2, + PAGE_EXECUTE_READWRITE, + &dwProtectPrev)) // If we can set the memory to be executable... + { + // Modify the code we return to. + uint8_t asm_ud2[] = {0x0f, 0x0b}; + memcpy(pReturnAddress, asm_ud2, sizeof(asm_ud2)); + VirtualProtect(pReturnAddress, 2, dwProtectPrev, &dwProtectPrev); + } else { + // To do: Fix this. + } + +#else +// To do: Fix this. +#endif + + break; + } + + case kCETStackCorruption: { + size_t size = (sizeof(buffer) * 16) - (rand() % 16); + char* pOutsizeStack = buffer - ((sizeof(buffer) * 16) + (rand() % 16)); + + memset(buffer, 0, size); + memset(pOutsizeStack, 0, size); // This line should generate an exception, or an exception + // will be generated upon return from this function. + break; + } + + case kCETStackOverflow: { + CreateException(exceptionType); // Call ourselves recursively. This line should generate a + // div/0 exception. + sprintf(buffer, "%d", exceptionType); + break; + } + + case kCETAlignment: { + // Not all platforms generate alignment exceptions. Some internally handle it. + void* pAligned = malloc(16); + char* pMisaligned = (char*)pAligned + 1; + uint64_t* pMisaligned64 = reinterpret_cast(pMisaligned); + + *pMisaligned64 = 0; // This line should generate an exception. + free(pAligned); + break; + } + + case kCETFPU: + // Platforms usually have FPU exceptions disabled. In order to test FPU exceptions we will + // need to at least + // temporarily disable them before executing code here to generate such exceptions. + // To do. + break; + + case kCETTrap: + // To do. This is hardware-specific. + break; + } +} + +//----------------------------------------------------------------------------- +// SymbolLookup + +#if defined(OVR_OS_MS) +#if defined(OVR_CC_MSVC) +// The Lock below is one that we want to keep around as long as possible, as there may be +// application code that +// needs to do symbol lookups during process teardown after main has returned. The init_seg(lib) +// statement +// below makes it so that this module's globals are initialized right after the C standard library +// has initialized, +// and are destroyed right before the C standard library is destroyed (after after all other app +// globals are destroyed). +#pragma warning(disable : 4073) // warning C4073: initializers put in library initialization area. +#pragma warning( \ + disable : 4075) // warning C4075: initializers put in unrecognized initialization area. +#pragma init_seg(lib) +#endif + +typedef BOOL(WINAPI* StackWalk64Type)( + DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); +typedef PVOID(WINAPI* SymFunctionTableAccess64Type)(HANDLE hProcess, DWORD64 dwAddr); +typedef DWORD64(WINAPI* SymGetModuleBase64Type)(HANDLE hProcess, DWORD64 dwAddr); +typedef DWORD(WINAPI* SymSetOptionsType)(DWORD SymOptions); +typedef BOOL( + WINAPI* SymInitializeWType)(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess); +typedef BOOL(WINAPI* SymCleanupType)(HANDLE hProcess); +typedef DWORD64(WINAPI* SymLoadModule64Type)( + HANDLE hProcess, + HANDLE hFile, + PCSTR ImageName, + PCSTR ModuleName, + DWORD64 BaseOfDll, + DWORD SizeOfDll); +typedef BOOL(WINAPI* SymFromAddrType)( + HANDLE hProcess, + DWORD64 Address, + PDWORD64 Displacement, + PSYMBOL_INFO Symbol); +typedef BOOL(WINAPI* SymGetLineFromAddr64Type)( + HANDLE hProcess, + DWORD64 qwAddr, + PDWORD pdwDisplacement, + PIMAGEHLP_LINE64 Line64); + +static StackWalk64Type pStackWalk64 = nullptr; +static SymFunctionTableAccess64Type pSymFunctionTableAccess64 = nullptr; +static SymGetModuleBase64Type pSymGetModuleBase64 = nullptr; +static SymSetOptionsType pSymSetOptions = nullptr; +static SymInitializeWType pSymInitializeW = nullptr; +static SymCleanupType pSymCleanup = nullptr; +static SymLoadModule64Type pSymLoadModule64 = nullptr; +static SymFromAddrType pSymFromAddr = nullptr; +static SymGetLineFromAddr64Type pSymGetLineFromAddr64 = nullptr; +static int32_t sSymUsageCount = 0; +static HMODULE sDbgHelp = nullptr; + +static OVR::Lock* GetSymbolLookupLockPtr() { + static OVR::Lock sDbgHelpLock; + return &sDbgHelpLock; +} + +bool SymbolLookup::Initialize() { + OVR::Lock::Locker autoLock(GetSymbolLookupLockPtr()); + + if (++sSymUsageCount > 1) { + OVR_ASSERT( + pSymInitializeW != + nullptr); // If it was already initialized then the pointers should be valid. + return true; + } + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms679294%28v=vs.85%29.aspx + sDbgHelp = LoadLibraryW( + L"DbgHelp.dll"); // It's best if the application supplies a recent version of this. + + if (sDbgHelp) { + pStackWalk64 = (StackWalk64Type)(uintptr_t)::GetProcAddress(sDbgHelp, "StackWalk64"); + pSymFunctionTableAccess64 = (SymFunctionTableAccess64Type)(uintptr_t)::GetProcAddress( + sDbgHelp, "SymFunctionTableAccess64"); + pSymGetModuleBase64 = + (SymGetModuleBase64Type)(uintptr_t)::GetProcAddress(sDbgHelp, "SymGetModuleBase64"); + pSymSetOptions = (SymSetOptionsType)(uintptr_t)::GetProcAddress(sDbgHelp, "SymSetOptions"); + pSymInitializeW = (SymInitializeWType)(uintptr_t)::GetProcAddress(sDbgHelp, "SymInitializeW"); + pSymCleanup = (SymCleanupType)(uintptr_t)::GetProcAddress(sDbgHelp, "SymCleanup"); + pSymLoadModule64 = + (SymLoadModule64Type)(uintptr_t)::GetProcAddress(sDbgHelp, "SymLoadModule64"); + pSymFromAddr = (SymFromAddrType)(uintptr_t)::GetProcAddress(sDbgHelp, "SymFromAddr"); + pSymGetLineFromAddr64 = + (SymGetLineFromAddr64Type)(uintptr_t)::GetProcAddress(sDbgHelp, "SymGetLineFromAddr64"); + + // To consider: Use a manually created search path: + // wchar_t searchPathW[4096]; // Semicolon-separated strings. + // The current working directory of the application. + // The directory of the application itself (GetModuleFileName). + // The _NT_SYMBOL_PATH environment variable. + // The _NT_ALTERNATE_SYMBOL_PATH environment variable. + + if (pSymInitializeW) { + if (pSymInitializeW(GetCurrentProcess(), nullptr /*searchPathW*/, FALSE)) { + if (pSymSetOptions) { + pSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES); + } + + return true; + } + } + } + + --sSymUsageCount; + return false; +} + +bool SymbolLookup::IsInitialized() { + // Note that it's possible that another thread could change the state of this right after the + // return. + OVR::Lock::Locker autoLock(GetSymbolLookupLockPtr()); + return (sSymUsageCount != 0); +} + +void SymbolLookup::Shutdown() { + OVR::Lock::Locker autoLock(GetSymbolLookupLockPtr()); + + if (sSymUsageCount > 0 && --sSymUsageCount <= 0) { + pSymCleanup(GetCurrentProcess()); + + pStackWalk64 = nullptr; + pSymFunctionTableAccess64 = nullptr; + pSymGetModuleBase64 = nullptr; + pSymSetOptions = nullptr; + pSymInitializeW = nullptr; + pSymCleanup = nullptr; + pSymLoadModule64 = nullptr; + pSymFromAddr = nullptr; + pSymGetLineFromAddr64 = nullptr; + + FreeLibrary(sDbgHelp); + sDbgHelp = nullptr; + } +} +#else +bool SymbolLookup::Initialize() { + return true; +} + +bool SymbolLookup::IsInitialized() { + return true; +} + +void SymbolLookup::Shutdown() {} +#endif + +SymbolLookup::SymbolLookup() + : AllowMemoryAllocation(true), + ModuleListUpdated(false), + ModuleInfoArray(), + ModuleInfoArraySize(0), + currentModuleInfo{} {} + +void SymbolLookup::AddSourceCodeDirectory(const char* pDirectory) { + OVR_UNUSED(pDirectory); +} + +void SymbolLookup::EnableMemoryAllocation(bool enabled) { + AllowMemoryAllocation = enabled; +} + +bool SymbolLookup::Refresh() { + ModuleListUpdated = false; + return RefreshModuleList(); +} + +OVR_DISABLE_MSVC_WARNING(4740) // flow in or out of inline asm code suppresses global optimization +OVR_DISABLE_MSVC_WARNING(4748) // /GS can not protect parameters and local variables from local +// buffer overrun because optimizations are disabled in function + +// Requires the thread to be suspended if not the current thread. +size_t SymbolLookup::GetBacktrace( + void* addressArray[], + size_t addressArrayCapacity, + size_t skipCount, + void* platformThreadContext, + OVR::ThreadSysId threadSysIdHelp) { +#if defined(OVR_OS_WIN64) + // The DbgHelp library must be loaded already. + OVR_ASSERT(sSymUsageCount > 0); + + if (platformThreadContext == nullptr) + return RtlCaptureStackBackTrace( + (DWORD)skipCount, (ULONG)addressArrayCapacity, addressArray, nullptr); + + // We need to get the call stack of another thread. + size_t frameIndex = 0; + CONTEXT context = {}; + PRUNTIME_FUNCTION pRuntimeFunction; + ULONG64 imageBase = 0; + ULONG64 imageBasePrev = 0; + HANDLE hThread = ConvertThreadSysIdToThreadHandle(threadSysIdHelp); + + if (hThread) { + // We need to get the full thread context if possible on x64 platforms. + // See for example https://bugzilla.mozilla.org/show_bug.cgi?id=1120126 + context.ContextFlags = CONTEXT_FULL; + + if (::GetThreadContext( + hThread, + &context)) // GetThreadContext will fail if the caller didn't suspend the thread. + { + if (context.Rip && (frameIndex < addressArrayCapacity)) + addressArray[frameIndex++] = (void*)(uintptr_t)context.Rip; + + while (context.Rip && (frameIndex < addressArrayCapacity)) { + imageBasePrev = imageBase; + pRuntimeFunction = + (PRUNTIME_FUNCTION)RtlLookupFunctionEntry(context.Rip, &imageBase, nullptr); + + if (pRuntimeFunction) { + // We have observed a problem in which the thread we are trying to read has exited by the + // time we get here, + // despite that we both suspended the thread and successfully read its context. This is + // contrary to the + // expectations set here: + // https://blogs.msdn.microsoft.com/oldnewthing/20150205-00/?p=44743. + // This code only executes in debugging situations and so should not be an issue for the + // large majority of + // end users. It's not safe in general in shipping applications to suspend threads. + __try { + VOID* handlerData = nullptr; + ULONG64 establisherFramePointers[2] = {0, 0}; + RtlVirtualUnwind( + UNW_FLAG_NHANDLER, + imageBase, + context.Rip, + pRuntimeFunction, + &context, + &handlerData, + establisherFramePointers, + nullptr); + } __except ( + GetExceptionCode() == 0x406D1388 /*set thread name*/ ? EXCEPTION_CONTINUE_EXECUTION + : EXCEPTION_EXECUTE_HANDLER) { + break; // If you encounter this under a debugger, just continue and let this code eat + // the exception. + } + } else { + // This would be viable only if we could rely on the presence of stack frames. + // context.Rip = (ULONG64)(*(PULONG64)context.Rsp); + // context.Rsp += 8; + + // Be safe and just bail. + context.Rip = 0; + } + + if (context.Rip && (frameIndex < addressArrayCapacity)) { + if (skipCount) + --skipCount; + else + addressArray[frameIndex++] = (void*)(uintptr_t)context.Rip; + } + } + } + + FreeThreadHandle(hThread); + } + + return frameIndex; + +#elif defined(OVR_OS_WIN32) + OVR_UNUSED(threadSysIdHelp); + + OVR::Lock::Locker autoLock(GetSymbolLookupLockPtr()); + size_t frameIndex = 0; + + if (pStackWalk64) { + CONTEXT context; + + if (platformThreadContext) { + memcpy(&context, platformThreadContext, sizeof(context)); + context.ContextFlags = CONTEXT_CONTROL; + } else { + memset(&context, 0, sizeof(context)); + context.ContextFlags = CONTEXT_CONTROL; + + __asm { + mov context.Ebp, EBP + mov context.Esp, ESP + call GetEIP + GetEIP: + pop context.Eip + } + } + + STACKFRAME64 sf; + memset(&sf, 0, sizeof(sf)); + sf.AddrPC.Offset = context.Eip; + sf.AddrPC.Mode = AddrModeFlat; + sf.AddrStack.Offset = context.Esp; + sf.AddrStack.Mode = AddrModeFlat; + sf.AddrFrame.Offset = context.Ebp; + sf.AddrFrame.Mode = AddrModeFlat; + + const HANDLE hCurrentProcess = ::GetCurrentProcess(); + const HANDLE hCurrentThread = ::GetCurrentThread(); + + if (!platformThreadContext) // If we are reading the current thread's call stack then we ignore + // this current function. + skipCount++; + + while (frameIndex < addressArrayCapacity) { + if (!pStackWalk64( + IMAGE_FILE_MACHINE_I386, + hCurrentProcess, + hCurrentThread, + &sf, + &context, + nullptr, + pSymFunctionTableAccess64, + pSymGetModuleBase64, + nullptr)) + break; + + if (sf.AddrFrame.Offset == 0) + break; + + if (skipCount) + --skipCount; + else + addressArray[frameIndex++] = ((void*)(uintptr_t)sf.AddrPC.Offset); + } + } + + return frameIndex; + +#elif (defined(OVR_OS_APPLE) || defined(OVR_OS_LINUX)) && \ + (defined(__LIBUNWIND__) || defined(LIBUNWIND_AVAIL)) + // Libunwind-based solution. Requires installation of libunwind package. + // Libunwind isn't always safe for threads that are in signal handlers. + // An approach to get the callstack of another thread is to use signal injection into the target + // thread. + + OVR_UNUSED(platformThreadContext); + OVR_UNUSED(threadSysIdHelp); + + size_t frameIndex = 0; + unw_cursor_t cursor; + unw_context_t uc; + unw_word_t ip, sp; + + unw_getcontext(&uc); // This gets the current thread's context. We could alternatively initialize + // another thread's context with it. + unw_init_local(&cursor, &uc); + + while ((unw_step(&cursor) > 0) && (frameIndex < addressArrayCapacity)) { + // We can get the function name here too on some platforms with unw_get_proc_info() and + // unw_get_proc_name(). + + if (skipCount) + --skipCount; + else { + unw_get_reg(&cursor, UNW_REG_IP, &ip); + addressArray[frameIndex++] = (void*)ip; + } + } + + return frameIndex; +#else + OVR_UNUSED(addressArray); + OVR_UNUSED(addressArrayCapacity); + OVR_UNUSED(skipCount); + OVR_UNUSED(platformThreadContext); + OVR_UNUSED(threadSysIdHelp); + + return 0; +#endif +} + +size_t SymbolLookup::GetBacktraceFromThreadHandle( + void* addressArray[], + size_t addressArrayCapacity, + size_t skipCount, + OVR::ThreadHandle threadHandle) { +#if defined(OVR_OS_MS) + size_t count = 0; + DWORD threadSysId = (DWORD)ConvertThreadHandleToThreadSysId(threadHandle); + + // Compare to 0, compare to the self 'pseudohandle' and compare to the self id. + if ((threadHandle == OVR_THREADHANDLE_INVALID) || (threadHandle == ::GetCurrentThread()) || + (threadSysId == ::GetCurrentThreadId())) // If threadSysId refers to the current thread... + return GetBacktrace( + addressArray, addressArrayCapacity, skipCount, nullptr, OVR_THREADSYSID_INVALID); + + // We are working with another thread. We need to suspend it and get its CONTEXT. + // Suspending other threads is risky, as they may be in some state that cannot be safely blocked. + DWORD suspendResult = + ::SuspendThread(threadHandle); // Requires that the handle have THREAD_SUSPEND_RESUME rights. + + if (suspendResult != (DWORD)-1) // Returns previous suspend count, or -1 if failed. + { + CONTEXT context = {}; + context.ContextFlags = CONTEXT_CONTROL | + CONTEXT_INTEGER; // Requires that the handle have THREAD_GET_CONTEXT rights. + + if (::GetThreadContext( + threadHandle, + &context)) // This is supposed to ensure that the thread really is stopped. + { + count = GetBacktrace(addressArray, addressArrayCapacity, skipCount, &context, threadSysId); + suspendResult = ::ResumeThread(threadHandle); + OVR_ASSERT_AND_UNUSED(suspendResult != (DWORD)-1, suspendResult); + } + } + + return count; + +#else + // To do. + OVR_UNUSED(addressArray); + OVR_UNUSED(addressArrayCapacity); + OVR_UNUSED(skipCount); + OVR_UNUSED(threadHandle); + return 0; +#endif +} + +size_t SymbolLookup::GetBacktraceFromThreadSysId( + void* addressArray[], + size_t addressArrayCapacity, + size_t skipCount, + OVR::ThreadSysId threadSysId) { +#if defined(OVR_OS_MS) + OVR::ThreadHandle threadHandle = ConvertThreadSysIdToThreadHandle(threadSysId); + if (threadHandle) { + size_t count = + GetBacktraceFromThreadHandle(addressArray, addressArrayCapacity, skipCount, threadHandle); + FreeThreadHandle(threadHandle); + return count; + } + return 0; + +#else + // To do. + OVR_UNUSED(addressArray); + OVR_UNUSED(addressArrayCapacity); + OVR_UNUSED(skipCount); + OVR_UNUSED(threadSysId); + return 0; +#endif +} + +// We need to return the required moduleInfoArrayCapacity. +size_t SymbolLookup::GetModuleInfoArray( + ModuleInfo* pModuleInfoArray, + size_t moduleInfoArrayCapacity, + ModuleSort moduleSort) { + // The count we would copy to pModuleInfoArray if moduleInfoArrayCapacity was enough. + size_t moduleCountRequired = 0; + + // The count we actually copy to pModuleInfoArray. Will be <= moduleInfoArrayCapacity. + size_t moduleCount = 0; + +#if defined(OVR_OS_MS) + HANDLE hProcess = GetCurrentProcess(); + HMODULE hModuleArray[200]; + DWORD cbNeeded = 0; + MODULEINFO mi; + + if (EnumProcessModules(hProcess, hModuleArray, sizeof(hModuleArray), &cbNeeded)) { + moduleCountRequired = ((cbNeeded / sizeof(HMODULE)) < OVR_ARRAY_COUNT(hModuleArray)) + ? (cbNeeded / sizeof(HMODULE)) + : OVR_ARRAY_COUNT(hModuleArray); + moduleCount = MIN(moduleCountRequired, OVR_ARRAY_COUNT(hModuleArray)); + moduleCount = MIN(moduleCount, moduleInfoArrayCapacity); + + for (size_t i = 0; i < moduleCount; i++) { + ModuleInfo& moduleInfo = pModuleInfoArray[i]; + + memset(&mi, 0, sizeof(mi)); + BOOL result = GetModuleInformation(hProcess, hModuleArray[i], &mi, sizeof(mi)); + + if (result) { + wchar_t pathW[OVR_MAX_PATH]; + + moduleInfo.handle = hModuleArray[i]; + moduleInfo.baseAddress = (uintptr_t)mi.lpBaseOfDll; + moduleInfo.size = mi.SizeOfImage; + + GetModuleFileNameW(hModuleArray[i], pathW, OVR_ARRAY_COUNT(pathW)); + auto requiredUTF8Length = OVR::UTF8Util::Strlcpy( + moduleInfo.filePath, OVR_ARRAY_COUNT(moduleInfo.filePath), pathW); + if (requiredUTF8Length < OVR_ARRAY_COUNT(moduleInfo.filePath)) { + OVR::OVR_strlcpy( + moduleInfo.name, + GetFileNameFromPath(moduleInfo.filePath), + OVR_ARRAY_COUNT(moduleInfo.name)); + } else { + moduleInfo.filePath[0] = '\0'; + moduleInfo.name[0] = '\0'; + } + } else { + moduleInfo.handle = 0; + moduleInfo.baseAddress = 0; + moduleInfo.size = 0; + moduleInfo.filePath[0] = '\0'; + moduleInfo.name[0] = '\0'; + } + } + } +#else + OVR_UNUSED(pModuleInfoArray); + OVR_UNUSED(moduleInfoArrayCapacity); + GetFileNameFromPath(nullptr); + moduleCountRequired = 0; + moduleCount = 0; +#endif + + if (moduleSort == ModuleSortByAddress) { + std::sort( + pModuleInfoArray, + pModuleInfoArray + moduleCount, + [](const ModuleInfo& mi1, const ModuleInfo& mi2) -> bool { + return mi1.baseAddress < mi2.baseAddress; + }); + } else if (moduleSort == ModuleSortByName) { + std::sort( + pModuleInfoArray, + pModuleInfoArray + moduleCount, + [](const ModuleInfo& mi1, const ModuleInfo& mi2) -> bool { + return (OVR_stricmp(mi1.name, mi2.name) < 0); + }); + } + + return moduleCountRequired; +} + +size_t SymbolLookup::GetThreadList( + ThreadHandle* threadHandleArray, + ThreadSysId* threadSysIdArray, + size_t threadArrayCapacity) { + size_t countRequired = 0; + size_t count = 0; + +#if defined(OVR_OS_MS) + // Print a list of threads. + DWORD currentProcessId = GetCurrentProcessId(); + HANDLE hThreadSnap = CreateToolhelp32Snapshot( + TH32CS_SNAPTHREAD, + currentProcessId); // ICreateToolhelp32Snapshot actually ignores currentProcessId. + + if (hThreadSnap != INVALID_HANDLE_VALUE) { + THREADENTRY32 te32; + te32.dwSize = sizeof(THREADENTRY32); + + if (Thread32First(hThreadSnap, &te32)) { + do { + if (te32.th32OwnerProcessID == currentProcessId) { + HANDLE hThread = ConvertThreadSysIdToThreadHandle(te32.th32ThreadID); + + if (hThread) { + ++countRequired; + + if ((threadHandleArray || threadSysIdArray) && (count < threadArrayCapacity)) { + if (threadHandleArray) + threadHandleArray[count] = hThread; // The caller must call CloseHandle on this + // thread, or call DoneThreadList on the + // returned array. + if (threadSysIdArray) + threadSysIdArray[count] = ConvertThreadHandleToThreadSysId(hThread); + ++count; + } + + if (!threadHandleArray) // If we aren't giving this back to the user... + FreeThreadHandle(hThread); + } + } + } while (Thread32Next(hThreadSnap, &te32)); + } + + CloseHandle(hThreadSnap); + } + +#else + // To do. + OVR_UNUSED(count); + OVR_UNUSED(threadHandleArray); + OVR_UNUSED(threadSysIdArray); + OVR_UNUSED(threadArrayCapacity); +#endif + + return countRequired; +} + +void SymbolLookup::DoneThreadList( + ThreadHandle* threadHandleArray, + ThreadSysId* threadSysIdArray, + size_t threadArrayCount) { +#if defined(OVR_OS_MS) + for (size_t i = 0; i != threadArrayCount; ++i) { + if (threadHandleArray[i]) { + CloseHandle(threadHandleArray[i]); + threadHandleArray[i] = OVR_THREADHANDLE_INVALID; + } + } + + OVR_UNUSED(threadSysIdArray); +#else + OVR_UNUSED(threadHandleArray); + OVR_UNUSED(threadSysIdArray); + OVR_UNUSED(threadArrayCount); +#endif +} + +// Writes a given thread's callstack wity symbols to the given output. +// It may not be safe to call this from an exception handler, as sOutput allocates memory. +bool SymbolLookup::ReportThreadCallstack( + OVR::String& sOutput, + size_t skipCount, + ThreadSysId threadSysId) { + sOutput.Clear(); + + if (!threadSysId) + threadSysId = GetCurrentThreadSysId(); + + void* addressArray[64]; + size_t addressCount = GetBacktraceFromThreadSysId( + addressArray, OVR_ARRAY_COUNT(addressArray), skipCount, threadSysId); + + // Print the header + char headerBuffer[256]; + char threadSysIdStr[48]; + char stackBaseStr[24]; + char stackLimitStr[24]; + void* pStackBase; + void* pStackLimit; + // void* pStackCurrent; // Current stack pointer. To do: support reporting this. + ThreadHandle threadHandle = ConvertThreadSysIdToThreadHandle(threadSysId); + OVR::GetThreadStackBounds(pStackBase, pStackLimit, threadHandle); + + SprintfThreadSysId(threadSysIdStr, OVR_ARRAY_COUNT(threadSysIdStr), threadSysId); + SprintfAddress(stackBaseStr, OVR_ARRAY_COUNT(stackBaseStr), pStackBase); + SprintfAddress(stackLimitStr, OVR_ARRAY_COUNT(stackLimitStr), pStackLimit); + + snprintf( + headerBuffer, + OVR_ARRAY_COUNT(headerBuffer), + "Thread id: %s, stack base: %s, stack limit: %s\n", + threadSysIdStr, + stackBaseStr, + stackLimitStr); + + sOutput += headerBuffer; + + // Print the backtrace info + char backtraceBuffer[1024]; // Sometimes function symbol names are very long. + SymbolInfo symbolInfo; + const char* pModuleName; + + if (addressCount == 0) { + sOutput += "\n"; + } else { + for (size_t i = 0; i < addressCount; ++i) { + LookupSymbol((uint64_t)addressArray[i], symbolInfo); + + if (symbolInfo.pModuleInfo && symbolInfo.pModuleInfo->name[0]) + pModuleName = symbolInfo.pModuleInfo->name; + else + pModuleName = "(unknown module)"; + + char addressStr[24]; + SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), addressArray[i]); + + if (symbolInfo.filePath[0]) + snprintf( + backtraceBuffer, + OVR_ARRAY_COUNT(backtraceBuffer), + "%-2u %-24s %s %s+%d %s:%d\n", + (unsigned)i, + pModuleName, + addressStr, + symbolInfo.function, + symbolInfo.functionOffset, + symbolInfo.filePath, + symbolInfo.fileLineNumber); + else + snprintf( + backtraceBuffer, + OVR_ARRAY_COUNT(backtraceBuffer), + "%-2u %-24s %s %s+%d\n", + (unsigned)i, + pModuleName, + addressStr, + symbolInfo.function, + symbolInfo.functionOffset); + + sOutput += backtraceBuffer; + } + } + + FreeThreadHandle(threadHandle); + + return (addressCount > 0); +} + +// Writes all thread's callstacks with symbols to the given output. +// It may not be safe to call this from an exception handler, as sOutput allocates memory. +bool SymbolLookup::ReportThreadCallstacks(OVR::String& sOutput, size_t skipCount) { + sOutput.Clear(); + + ThreadSysId threadSysIdArray[64]; + size_t threadSysIdCount = + GetThreadList(nullptr, threadSysIdArray, OVR_ARRAY_COUNT(threadSysIdArray)); + + if (threadSysIdCount > OVR_ARRAY_COUNT(threadSysIdArray)) + threadSysIdCount = OVR_ARRAY_COUNT(threadSysIdArray); + + for (size_t i = 0; i < threadSysIdCount; i++) { + String sTemp; + ReportThreadCallstack(sTemp, skipCount, threadSysIdArray[i]); + if (i > 0) + sOutput += "\n"; + sOutput += sTemp; + } + + return (threadSysIdCount > 0); +} + +bool SymbolLookup::ReportModuleInformation(OVR::String& sOutput) { + sOutput.Clear(); + + RefreshModuleList(); + + char backtraceBuffer[1024]; + + for (size_t i = 0; i < ModuleInfoArraySize; ++i) { + snprintf( + backtraceBuffer, + OVR_ARRAY_COUNT(backtraceBuffer), + "Base: 0x%llx Size: 0x%llx Name: '%s' Path: '%s'\n", + (unsigned long long)ModuleInfoArray[i].baseAddress, + (unsigned long long)ModuleInfoArray[i].size, + ModuleInfoArray[i].name, + ModuleInfoArray[i].filePath); + sOutput += backtraceBuffer; + } + + return true; +} + +bool SymbolLookup::RefreshModuleList() { + if (!ModuleListUpdated) { +#if defined(OVR_OS_MS) + OVR::Lock::Locker autoLock(GetSymbolLookupLockPtr()); + + // We can't rely on SymRefreshModuleList because it's present in DbgHelp 6.5, + // which doesn't distribute with Windows 7. + + // Currently we support only refreshing the list once ever. With a little effort + // we could revise this code to support re-refreshing the list at runtime to account + // for the possibility that modules have recently been added or removed. + if (pSymLoadModule64) { + const size_t requiredCount = + GetModuleInfoArray(ModuleInfoArray, OVR_ARRAY_COUNT(ModuleInfoArray)); + ModuleInfoArraySize = MIN(requiredCount, OVR_ARRAY_COUNT(ModuleInfoArray)); + + HANDLE hProcess = GetCurrentProcess(); + + for (size_t i = 0; i < ModuleInfoArraySize; i++) + pSymLoadModule64( + hProcess, + nullptr, + ModuleInfoArray[i].filePath, + nullptr, + ModuleInfoArray[i].baseAddress, + (DWORD)ModuleInfoArray[i].size); + + ModuleListUpdated = true; + } +#else + const size_t requiredCount = + GetModuleInfoArray(ModuleInfoArray, OVR_ARRAY_COUNT(ModuleInfoArray)); + ModuleInfoArraySize = MIN(requiredCount, OVR_ARRAY_COUNT(ModuleInfoArray)); + ModuleListUpdated = true; +#endif + } + + return true; +} + +bool SymbolLookup::LookupSymbol(uint64_t address, SymbolInfo& symbolInfo) { + return LookupSymbols(&address, &symbolInfo, 1); +} + +bool SymbolLookup::LookupSymbols( + uint64_t* addressArray, + SymbolInfo* pSymbolInfoArray, + size_t arraySize) { + bool success = false; + + if (!ModuleListUpdated) { + RefreshModuleList(); + } + +#if defined(OVR_OS_MS) + OVR::Lock::Locker autoLock(GetSymbolLookupLockPtr()); + + union SYMBOL_INFO_UNION { + SYMBOL_INFO msSymbolInfo; + char suffixPadding[sizeof(SYMBOL_INFO) + 1024]; + }; + + for (size_t i = 0; i < arraySize; i++) { + uint64_t& address = addressArray[i]; + SymbolInfo& symbolInfo = pSymbolInfoArray[i]; + + // Copy the address and ModuleInfo + symbolInfo.address = addressArray[i]; + symbolInfo.pModuleInfo = GetModuleInfoForAddress( + address); // We could also use siu.msSymbolInfo.ModBase to get the module slightly faster. + + // Get the function/offset. + SYMBOL_INFO_UNION siu; + memset(&siu, 0, sizeof(siu)); + siu.msSymbolInfo.SizeOfStruct = sizeof(siu.msSymbolInfo); + siu.msSymbolInfo.MaxNameLen = sizeof(siu.suffixPadding) - sizeof(SYMBOL_INFO) + + 1; // +1 because SYMBOL_INFO itself has Name[1]. + + HANDLE hProcess = GetCurrentProcess(); + DWORD64 displacement64 = 0; + bool bResult = (pSymFromAddr != nullptr) && + (pSymFromAddr(hProcess, address, &displacement64, &siu.msSymbolInfo) != FALSE); + + if (bResult) { + success = true; + symbolInfo.size = siu.msSymbolInfo.Size; + OVR_strlcpy(symbolInfo.function, siu.msSymbolInfo.Name, OVR_ARRAY_COUNT(symbolInfo.function)); + symbolInfo.functionOffset = (int32_t)displacement64; + } else { + symbolInfo.size = kMISizeInvalid; + symbolInfo.function[0] = 0; + symbolInfo.functionOffset = kMIFunctionOffsetInvalid; + } + + // Get the file/line + IMAGEHLP_LINE64 iLine64; + DWORD displacement = 0; + memset(&iLine64, 0, sizeof(iLine64)); + iLine64.SizeOfStruct = sizeof(iLine64); + + bResult = (pSymGetLineFromAddr64 != nullptr) && + (pSymGetLineFromAddr64(hProcess, address, &displacement, &iLine64) != FALSE); + + if (bResult) { + success = true; + OVR_strlcpy(symbolInfo.filePath, iLine64.FileName, OVR_ARRAY_COUNT(symbolInfo.filePath)); + symbolInfo.fileLineNumber = (int32_t)iLine64.LineNumber; + } else { + symbolInfo.filePath[0] = 0; + symbolInfo.fileLineNumber = kMILineNumberInvalid; + } + + // To do: get the source code when possible. We need to use the user-registered directory paths + // and the symbolInfo.filePath + // and find the given file in the tree(s), then open the file and find the + // symbolInfo.fileLineNumber line (and surrounding lines). + // symbolInfo.sourceCode[1024] + symbolInfo.sourceCode[0] = '\0'; + } + +#else + // We can use libunwind's unw_get_proc_name to try to get function name info. It can work + // regardless of relocation. + // Use backtrace_symbols and addr2line. Need to watch out for module load-time relocation. + // Ned to pass the -rdynamic flag to the linker. It will cause the linker to out in the link + // tables the name of all the none static functions in your code, not just the exported ones. + OVR_UNUSED(addressArray); + OVR_UNUSED(pSymbolInfoArray); + OVR_UNUSED(arraySize); +#endif + + return success; +} + +const ModuleInfo* SymbolLookup::GetModuleInfoForAddress(uint64_t address) { + // This is a linear seach. To consider: it would be significantly faster to search by + // address if we ordered it by base address and did a binary search. + for (size_t i = 0; i < ModuleInfoArraySize; ++i) { + const ModuleInfo& mi = ModuleInfoArray[i]; + + if ((mi.baseAddress <= address) && (address < (mi.baseAddress + mi.size))) + return &mi; + } + + return nullptr; +} + +const ModuleInfo& SymbolLookup::GetModuleInfoForCurrentModule() { + OVR_ASSERT(ModuleInfoArraySize > 0); // We expect that the modules have been iterated previously. + if (currentModuleInfo.baseAddress == 0) { // If the current module hasn't been identified yet... + const ModuleInfo* mi = GetModuleInfoForAddress((uintptr_t)GetInstructionAddress); + if (mi) + currentModuleInfo = *mi; // This will set currentModuleInfo.baseAddress to a non-zero value. + } + + return currentModuleInfo; +} + +ExceptionInfo::ExceptionInfo() + : time(), + timeVal(0), + backtrace(), + backtraceCount(0), + threadHandle(OVR_THREADHANDLE_INVALID), + threadSysId(OVR_THREADSYSID_INVALID), + threadName(), + pExceptionInstructionAddress(nullptr), + pExceptionMemoryAddress(nullptr), + cpuContext(), + exceptionDescription(), + symbolInfo() +#if defined(OVR_OS_MS) + , + exceptionRecord() +#endif +{ +} + +ExceptionHandler::ExceptionHandler() + : enabled(false), + reportPrivacyEnabled(true), + exceptionResponse(kERHandle), + exceptionListener(nullptr), + exceptionListenerUserValue(0), + appDescription(), + codeBasePathArray(), + reportFilePath(), + minidumpInfoLevel(kMILMedium), + miniDumpFilePath(), + LogFile(nullptr), + scratchBuffer(), + exceptionOccurred(false), + reportFilePathActual(), + minidumpFilePathActual(), + terminateReturnValue(0), + exceptionInfo() +#if defined(OVR_OS_MS) + , + vectoredHandle(nullptr), + previousFilter(nullptr), + pExceptionPointers(nullptr) +#endif +{ + SetExceptionPaths("default", "default"); +} + +void ExceptionHandler::GetCrashDumpDirectoryFromNames( + char* path, + const char* organizationName, + const char* ApplicationName) { + ExceptionHandler::GetCrashDumpDirectory(path, OVR_MAX_PATH); + OVR_strlcat(path, organizationName, OVR_MAX_PATH); + +// make the organization folder if necessary +#ifdef OVR_OS_MS + WCHAR wpath[OVR_MAX_PATH]; + auto requiredUTF8Length = OVR::UTF8Util::Strlcpy(wpath, OVR_ARRAY_COUNT(wpath), path); + // XXX error handling/logging? + if (requiredUTF8Length < OVR_ARRAY_COUNT(wpath)) + CreateDirectoryW(wpath, NULL); +#else + mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif + +#ifdef OVR_OS_MS + const char* separator = "\\"; +#else + const char* separator = "/"; +#endif + OVR_strlcat(path, separator, OVR_MAX_PATH); + OVR_strlcat(path, ApplicationName, OVR_MAX_PATH); +#ifdef OVR_OS_MS + requiredUTF8Length = OVR::UTF8Util::Strlcpy(wpath, OVR_ARRAY_COUNT(wpath), path); + // XXX error handling/logging? + if (requiredUTF8Length < OVR_ARRAY_COUNT(wpath)) + CreateDirectoryW(wpath, NULL); +#else + mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif + OVR_strlcat(path, separator, OVR_MAX_PATH); +} + +void ExceptionHandler::SetPathsFromNames( + const char* organizationName, + const char* ApplicationName, + const char* exceptionFormat, + const char* minidumpFormat) { + char exceptionPath[OVR_MAX_PATH]; + char miniDumpPath[OVR_MAX_PATH]; + ExceptionHandler::GetCrashDumpDirectoryFromNames( + exceptionPath, organizationName, ApplicationName); + ExceptionHandler::GetCrashDumpDirectoryFromNames(miniDumpPath, organizationName, ApplicationName); + + OVR::OVR_strlcat(exceptionPath, exceptionFormat, OVR_MAX_PATH); + OVR::OVR_strlcat(miniDumpPath, minidumpFormat, OVR_MAX_PATH); + + SetExceptionPaths(exceptionPath, miniDumpPath); +} + +ExceptionHandler::~ExceptionHandler() { + if (enabled) { + Enable(false); + } +} + +size_t ExceptionHandler::GetCrashDumpDirectory(char* directoryPath, size_t directoryPathCapacity) { +#if defined(OVR_OS_MS) + wchar_t pathW[OVR_MAX_PATH]; + HRESULT hr = SHGetFolderPathW( + nullptr, + CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, + nullptr, + SHGFP_TYPE_CURRENT, + pathW); // Expects pathW to be MAX_PATH. The returned path does not include a trailing + // backslash. + + if (SUCCEEDED(hr)) { + auto requiredUTF8Length = OVR::UTF8Util::Strlcpy(directoryPath, directoryPathCapacity, pathW); + if (requiredUTF8Length < directoryPathCapacity) // We need space for a trailing path separator. + { + if ((requiredUTF8Length == 0) || + (directoryPath[requiredUTF8Length - 1] != '\\')) // If there is no trailing \ char... + { + OVR::OVR_strlcat(directoryPath, "\\", directoryPathCapacity); + requiredUTF8Length++; + } + } + + return requiredUTF8Length; // Returns the required strlen. + } + +#elif defined(OVR_OS_MAC) + // This is the same location that Apple puts its OS-generated .crash files. + const char* home = getenv("HOME"); + size_t requiredStrlen = snprintf( + directoryPath, + directoryPathCapacity, + "%s/Library/Logs/DiagnosticReports/", + home ? home : "/Users/Shared/Logs/DiagnosticReports/"); + // To do: create the directory if it doesn't already exist. + return requiredStrlen; + +#elif defined(OVR_OS_UNIX) + const char* home = getenv("HOME"); + size_t requiredStrlen = + snprintf(directoryPath, directoryPathCapacity, "%s/Library/", home ? home : "/Users/Shared/"); + // To do: create the directory if it doesn't already exist. + return requiredStrlen; +#endif + + return 0; +} + +#if defined(OVR_OS_MS) + +static ExceptionHandler* sExceptionHandler = nullptr; + +unsigned WINAPI ExceptionHandler::ExceptionHandlerThreadExec(void* callingHandler) { + ExceptionHandler* caller = reinterpret_cast(callingHandler); + if (caller->miniDumpFilePath[0]) + caller->WriteMiniDump(); + + if (caller->reportFilePath[0]) + caller->WriteReport("Exception"); + + if (caller->exceptionListener) + caller->exceptionListener->HandleException( + caller->exceptionListenerUserValue, + caller, + &caller->exceptionInfo, + caller->reportFilePathActual); + return 1; +} + +LONG WINAPI Win32ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointersArg) { + if (sExceptionHandler) + return (LONG)sExceptionHandler->ExceptionFilter(pExceptionPointersArg); + return EXCEPTION_CONTINUE_SEARCH; +} + +LONG ExceptionHandler::ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointersArg) { + if (pauseCount) + return EXCEPTION_CONTINUE_SEARCH; + + // Exception codes < 0x80000000 are not true exceptions but rather are debugger notifications. + // They include DBG_TERMINATE_THREAD, + // DBG_TERMINATE_PROCESS, DBG_CONTROL_BREAK, DBG_COMMAND_EXCEPTION, DBG_CONTROL_C, + // DBG_PRINTEXCEPTION_C, DBG_RIPEXCEPTION, + // and 0x406d1388 (thread named, http://blogs.msdn.com/b/stevejs/archive/2005/12/19/505815.aspx). + + if (pExceptionPointersArg->ExceptionRecord->ExceptionCode < 0x80000000) + return EXCEPTION_CONTINUE_SEARCH; + + // VC++ C++ exceptions use code 0xe06d7363 ('Emsc') + // http://support.microsoft.com/kb/185294 + // http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx + if (pExceptionPointersArg->ExceptionRecord->ExceptionCode == 0xe06d7363) + return EXCEPTION_CONTINUE_SEARCH; + + // folly causes this when it closes some socket handles, not really a crash + if (static_cast(pExceptionPointersArg->ExceptionRecord->ExceptionCode) == + STATUS_HANDLE_NOT_CLOSABLE) + return EXCEPTION_CONTINUE_SEARCH; + + // winrt hwnd capture throws this on the first call but the + // exception is benign + if (pExceptionPointersArg->ExceptionRecord->ExceptionCode == 0x8001010D) + return EXCEPTION_CONTINUE_SEARCH; + + unsigned int tmp_zero = 0; + // If we can successfully change it from 0 to 1. + if (handlingBusy.compare_exchange_strong(tmp_zero, 1, std::memory_order_acquire)) { + exceptionOccurred = true; + + SymbolLookup::Initialize(); + + this->pExceptionPointers = pExceptionPointersArg; + + // Disable the handler while we do this processing. + ULONG result = RemoveVectoredExceptionHandler(vectoredHandle); + OVR_ASSERT_AND_UNUSED(result != 0, result); + + // Time + exceptionInfo.timeVal = time(nullptr); + exceptionInfo.time = *gmtime(&exceptionInfo.timeVal); + + // Thread id + // This is the thread id of the current thread and not the exception thread. + if (!DuplicateHandle( + GetCurrentProcess(), + GetCurrentThread(), + GetCurrentProcess(), + &exceptionInfo.threadHandle, + 0, + true, + DUPLICATE_SAME_ACCESS)) + exceptionInfo.threadHandle = 0; + exceptionInfo.threadSysId = ConvertThreadHandleToThreadSysId(exceptionInfo.threadHandle); + + OVR::GetThreadName( + exceptionInfo.threadHandle, + exceptionInfo.threadName, + OVR_ARRAY_COUNT(exceptionInfo.threadName)); + + // Backtraces + exceptionInfo.backtraceCount = symbolLookup.GetBacktrace( + exceptionInfo.backtrace, + OVR_ARRAY_COUNT(exceptionInfo.backtrace), + 0, + nullptr, + OVR_THREADSYSID_INVALID); // Get current thread backtrace. + + // Context + exceptionInfo.cpuContext = *pExceptionPointersArg->ContextRecord; + exceptionInfo.exceptionRecord = *pExceptionPointersArg->ExceptionRecord; + exceptionInfo.pExceptionInstructionAddress = exceptionInfo.exceptionRecord.ExceptionAddress; + if ((exceptionInfo.exceptionRecord.ExceptionCode == + static_cast(EXCEPTION_ACCESS_VIOLATION)) || + (exceptionInfo.exceptionRecord.ExceptionCode == + static_cast(EXCEPTION_IN_PAGE_ERROR))) { + exceptionInfo.pExceptionMemoryAddress = + (void*)exceptionInfo.exceptionRecord.ExceptionInformation[1]; // ExceptionInformation[0] + } + // indicates if it was a + // read (0), write (1), or + // data execution attempt + // (8). + else + exceptionInfo.pExceptionMemoryAddress = + pExceptionPointersArg->ExceptionRecord->ExceptionAddress; + + WriteExceptionDescription(); + + if (pExceptionPointersArg->ExceptionRecord->ExceptionCode == + static_cast(EXCEPTION_STACK_OVERFLOW)) { + unsigned int IdValue; + + void* ThreadHandle = (HANDLE)_beginthreadex( + 0, (unsigned)128 * 1024, ExceptionHandlerThreadExec, this, 0, (unsigned*)&IdValue); + WaitForSingleObject(ThreadHandle, INFINITE); + CloseHandle(ThreadHandle); + + } else { + if (reportFilePath[0]) + WriteReport("Exception"); + + if (miniDumpFilePath[0]) + WriteMiniDump(); + + if (exceptionListener) + exceptionListener->HandleException( + exceptionListenerUserValue, this, &exceptionInfo, reportFilePathActual); + } + if (exceptionInfo.threadHandle) { + CloseHandle(exceptionInfo.threadHandle); + exceptionInfo.threadHandle = 0; + } + + SymbolLookup::Shutdown(); + + // Restore the handler that we temporarily disabled above. + vectoredHandle = AddVectoredExceptionHandler(1, Win32ExceptionFilter); + + handlingBusy.store(0, std::memory_order_release); + } + + if (exceptionResponse == ExceptionHandler::kERContinue) + return EXCEPTION_CONTINUE_EXECUTION; + else if (exceptionResponse == ExceptionHandler::kERHandle) + return EXCEPTION_EXECUTE_HANDLER; + else if (exceptionResponse == ExceptionHandler::kERTerminate) { + TerminateProcess(GetCurrentProcess(), (UINT)terminateReturnValue); + return terminateReturnValue; + } else if (exceptionResponse == ExceptionHandler::kERThrow) + return EXCEPTION_CONTINUE_SEARCH; + + // kERDefault + return EXCEPTION_EXECUTE_HANDLER; +} + +#endif // defined(OVR_OS_MS) + +bool ExceptionHandler::Enable(bool enable) { +#if defined(OVR_OS_MS) + if (enable && !enabled) { + OVR_ASSERT(vectoredHandle == nullptr); + vectoredHandle = AddVectoredExceptionHandler(1, Win32ExceptionFilter); // Windows call. + enabled = (vectoredHandle != nullptr); + OVR_ASSERT(enabled); + sExceptionHandler = this; + return enabled; + } else if (!enable && enabled) { + if (sExceptionHandler == this) + sExceptionHandler = nullptr; + OVR_ASSERT(vectoredHandle != nullptr); + ULONG result = RemoveVectoredExceptionHandler(vectoredHandle); // Windows call. + OVR_ASSERT_AND_UNUSED(result != 0, result); + vectoredHandle = nullptr; + enabled = false; + return true; + } +#else + OVR_UNUSED(enable); +#endif + + return true; +} + +int ExceptionHandler::PauseHandling(bool pause) { + if (pause) + return ++pauseCount; + + OVR_ASSERT(pauseCount > 0); + return --pauseCount; +} + +void ExceptionHandler::EnableReportPrivacy(bool enable) { + reportPrivacyEnabled = enable; +} + +void ExceptionHandler::WriteExceptionDescription() { +#if defined(OVR_OS_MS) + // There is some extra information available for AV exception. + if (static_cast(exceptionInfo.exceptionRecord.ExceptionCode) == + EXCEPTION_ACCESS_VIOLATION) { + const char* error = (exceptionInfo.exceptionRecord.ExceptionInformation[0] == 0) + ? "reading" + : ((exceptionInfo.exceptionRecord.ExceptionInformation[0] == 1) ? "writing" : "executing"); + + char addressStr[24]; + SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionMemoryAddress); + snprintf( + exceptionInfo.exceptionDescription, + OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), + "ACCESS_VIOLATION %s address %s", + error, + addressStr); + } else { + exceptionInfo.exceptionDescription[0] = 0; + +// Process "standard" exceptions, other than 'access violation' +#define FORMAT_EXCEPTION(x) \ + case static_cast(EXCEPTION_##x): \ + OVR::OVR_strlcpy( \ + exceptionInfo.exceptionDescription, \ + #x, \ + OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription)); \ + break; + + switch (exceptionInfo.exceptionRecord.ExceptionCode) { + // FORMAT_EXCEPTION(ACCESS_VIOLATION) Already handled above. + FORMAT_EXCEPTION(DATATYPE_MISALIGNMENT) + FORMAT_EXCEPTION(BREAKPOINT) + FORMAT_EXCEPTION(SINGLE_STEP) + FORMAT_EXCEPTION(ARRAY_BOUNDS_EXCEEDED) + FORMAT_EXCEPTION(FLT_DENORMAL_OPERAND) + FORMAT_EXCEPTION(FLT_DIVIDE_BY_ZERO) + FORMAT_EXCEPTION(FLT_INEXACT_RESULT) + FORMAT_EXCEPTION(FLT_INVALID_OPERATION) + FORMAT_EXCEPTION(FLT_OVERFLOW) + FORMAT_EXCEPTION(FLT_STACK_CHECK) + FORMAT_EXCEPTION(FLT_UNDERFLOW) + FORMAT_EXCEPTION(INT_DIVIDE_BY_ZERO) + FORMAT_EXCEPTION(INT_OVERFLOW) + FORMAT_EXCEPTION(PRIV_INSTRUCTION) + FORMAT_EXCEPTION(IN_PAGE_ERROR) + FORMAT_EXCEPTION(ILLEGAL_INSTRUCTION) + FORMAT_EXCEPTION(NONCONTINUABLE_EXCEPTION) + FORMAT_EXCEPTION(STACK_OVERFLOW) + FORMAT_EXCEPTION(INVALID_DISPOSITION) + FORMAT_EXCEPTION(GUARD_PAGE) + FORMAT_EXCEPTION(INVALID_HANDLE) +#if defined(EXCEPTION_POSSIBLE_DEADLOCK) && \ + defined(STATUS_POSSIBLE_DEADLOCK) // This type seems to be non-existant in practice. + FORMAT_EXCEPTION(POSSIBLE_DEADLOCK) +#endif + } + + // If not one of the "known" exceptions, try to get the string from NTDLL.DLL's message table. + if (exceptionInfo.exceptionDescription[0] == 0) { + char addressStr[24]; + SprintfAddress( + addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionMemoryAddress); + + char buffer[384]; + DWORD capacity = OVR_ARRAY_COUNT(buffer); + + const size_t length = (size_t)FormatMessageA( + FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, + GetModuleHandleW(L"NTDLL.DLL"), + exceptionInfo.exceptionRecord.ExceptionCode, + 0, + buffer, + capacity, + nullptr); + if (length) + snprintf( + exceptionInfo.exceptionDescription, + OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), + "%s at instruction %s", + buffer, + addressStr); + + // If everything else failed just show the hex code. + if (exceptionInfo.exceptionDescription[0] == 0) + snprintf( + exceptionInfo.exceptionDescription, + OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), + "Unknown exception 0x%08x at instruction %s", + static_cast(exceptionInfo.exceptionRecord.ExceptionCode), + addressStr); + } + } +#else + // To do. + exceptionInfo.exceptionDescription[0] = 0; +#endif +} + +void ExceptionHandler::writeLogLine(const char* buffer, int length) { + OVR_ASSERT((int)strlen(buffer) == length); // Input must be null-terminated. + + if (LogFile != nullptr) + fwrite(buffer, length, 1, LogFile); + + fwrite(buffer, length, 1, stdout); + +#if defined(OVR_OS_WIN32) + ::OutputDebugStringA(buffer); +#endif +} + +void ExceptionHandler::WriteReportLine(const char* pLine) { + writeLogLine(pLine, (int)strlen(pLine)); +} + +void ExceptionHandler::WriteReportLineF(const char* format, ...) { + va_list args; + va_start(args, format); + int length = vsnprintf(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), format, args); + if (length >= (int)OVR_ARRAY_COUNT(scratchBuffer)) // If we didn't have enough space... + length = (OVR_ARRAY_COUNT(scratchBuffer) - 1); // ... use what we have. + va_end(args); + + writeLogLine(scratchBuffer, length); +} + +// Thread +// 0
: +// 1
: +// . . . +// +void ExceptionHandler::WriteThreadCallstack( + ThreadHandle threadHandle, + ThreadSysId threadSysId, + const char* additionalInfo) { + // We intentionally do not directly use the SymbolInfo::ReportThreadCallstack function because + // that function allocates memory, + // which we cannot do due to possibly being within an exception handler. + + // Print the header + char threadSysIdStr[32]; + char stackBaseStr[24]; + char stackLimitStr[24]; + char stackCurrentStr[24]; + void* pStackBase; + void* pStackLimit; + bool isExceptionThread = (threadSysId == exceptionInfo.threadSysId); + +#if defined(OVR_OS_MS) && (OVR_PTR_SIZE == 8) + void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) + ? (void*)exceptionInfo.cpuContext.Rsp + : nullptr; // We would need to suspend the thread, get its context, resume it, then read the +// rsp register. It turns out we are already doing that suspend/resume below in the +// backtrace call. +#else + void* pStackCurrent = nullptr; // To do. +#endif + + OVR::GetThreadStackBounds(pStackBase, pStackLimit, threadHandle); + + SprintfThreadSysId(threadSysIdStr, OVR_ARRAY_COUNT(threadSysIdStr), threadSysId); + SprintfAddress(stackBaseStr, OVR_ARRAY_COUNT(stackBaseStr), pStackBase); + SprintfAddress(stackLimitStr, OVR_ARRAY_COUNT(stackLimitStr), pStackLimit); + SprintfAddress(stackCurrentStr, OVR_ARRAY_COUNT(stackCurrentStr), pStackCurrent); + + WriteReportLineF( + "Thread id: %s, stack base: %s, stack limit: %s, stack current: %s, %s\n", + threadSysIdStr, + stackBaseStr, + stackLimitStr, + stackCurrentStr, + additionalInfo ? additionalInfo : ""); + + // Print the backtrace info + void* addressArray[64]; + size_t addressCount = symbolLookup.GetBacktraceFromThreadSysId( + addressArray, OVR_ARRAY_COUNT(addressArray), 0, threadSysId); + SymbolInfo symbolInfo; + const char* pModuleName; + size_t backtraceSkipCount = 0; + + if (isExceptionThread) { +// If this thread is the exception thread, skip some frames. +#if defined(OVR_OS_MS) + size_t i, iEnd = MIN(16, addressCount); + + for (i = 0; i < iEnd; i++) { + symbolLookup.LookupSymbol((uint64_t)addressArray[i], symbolInfo); + if (strstr(symbolInfo.function, "UserExceptionDispatcher") != nullptr) + break; + } + + if (i < iEnd) // If found... + backtraceSkipCount = i; + else if (addressCount >= 9) // Else default to 9, which is coincidentally what works. + backtraceSkipCount = 9; + else + backtraceSkipCount = 0; + + addressArray[backtraceSkipCount] = exceptionInfo.pExceptionInstructionAddress; +#endif + } + + if (addressCount == 0) { + WriteReportLine("\n\n"); + } else { + for (size_t i = backtraceSkipCount; i < addressCount; ++i) { + symbolLookup.LookupSymbol((uint64_t)addressArray[i], symbolInfo); + + if (symbolInfo.pModuleInfo && symbolInfo.pModuleInfo->name[0]) + pModuleName = symbolInfo.pModuleInfo->name; + else + pModuleName = "(unknown module)"; + + char addressStr[24]; + SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), addressArray[i]); + + if (symbolInfo.filePath[0]) + WriteReportLineF( + "%-2u %-24s %s %s+%d %s:%d\n%s", + (unsigned)i, + pModuleName, + addressStr, + symbolInfo.function, + symbolInfo.functionOffset, + symbolInfo.filePath, + symbolInfo.fileLineNumber, + (i + 1) == addressCount ? "\n" : ""); + else + WriteReportLineF( + "%-2u %-24s %s %s+%d\n%s", + (unsigned)i, + pModuleName, + addressStr, + symbolInfo.function, + symbolInfo.functionOffset, + (i + 1) == addressCount ? "\n" : ""); // If this is the last line, append another \n. + } + } +} + +void ExceptionHandler::WriteReport(const char* reportType) { + // It's important that we don't allocate any memory here if we can help it. + using namespace OVR; + + if (!reportType) + reportType = "Exception"; + + if (strstr( + reportFilePath, + "%s")) // If the user-specified file path includes a date/time component... + { + char dateTimeBuffer[64]; + FormatDateTime( + dateTimeBuffer, + OVR_ARRAY_COUNT(dateTimeBuffer), + exceptionInfo.timeVal, + true, + true, + false, + true); + snprintf( + reportFilePathActual, + OVR_ARRAY_COUNT(reportFilePathActual), + reportFilePath, + dateTimeBuffer); + } else { + OVR_strlcpy(reportFilePathActual, reportFilePath, OVR_ARRAY_COUNT(reportFilePathActual)); + } + + // Since LogFile is still null at this point, ... + OVR_ASSERT(LogFile == nullptr); + + // ...we are writing this to the console/syslog but not the log file. + if (strcmp(reportType, "Exception") == 0) + WriteReportLine("[ExceptionHandler] Exception caught! "); + + WriteReportLineF("Writing report to file: %s\n", reportFilePathActual); + +#if defined(OVR_OS_WIN32) +#ifndef OVR_SYSLOG_NAME +#define OVR_SYSLOG_NAME L"OculusVR" +#endif // OVR_SYSLOG_NAME + HANDLE hEventSource = ::RegisterEventSourceW(nullptr, OVR_SYSLOG_NAME); + + if (hEventSource) { + // This depends on the scratch buffer containing the file location. + const char* lines = scratchBuffer; + static_assert( + sizeof(scratchBuffer) < 31839, "RegisterEventSource has a size limit of 31839 per string"); + ::ReportEventA(hEventSource, EVENTLOG_ERROR_TYPE, 0, 0, nullptr, 1, 0, &lines, nullptr); + ::DeregisterEventSource(hEventSource); + } +#endif + + LogFile = fopen(reportFilePathActual, "w"); + OVR_ASSERT(LogFile != nullptr); + if (!LogFile) + return; + + SymbolLookup::Initialize(); + + { + // Exception information + WriteReportLineF("%s Info\n", reportType); + + WriteReportLineF("%s report file: %s\n", reportType, reportFilePathActual); + +#if defined(OVR_OS_MS) + if (miniDumpFilePath[0]) + WriteReportLineF("%s minidump file: %s\n", reportType, minidumpFilePathActual); +#endif + + char dateTimeBuffer[64]; + FormatDateTime( + dateTimeBuffer, + OVR_ARRAY_COUNT(dateTimeBuffer), + exceptionInfo.timeVal, + true, + true, + false, + false); + WriteReportLineF("Time (GMT): %s\n", dateTimeBuffer); + + FormatDateTime( + dateTimeBuffer, + OVR_ARRAY_COUNT(scratchBuffer), + exceptionInfo.timeVal, + true, + true, + true, + false); + WriteReportLineF("Time (local): %s\n", dateTimeBuffer); + WriteReportLineF( + "Thread name: %s\n", + exceptionInfo.threadName[0] ? exceptionInfo.threadName + : "(not available)"); // It's never possible on Windows to get + // thread names, as they are stored in the + // debugger at runtime. + + SprintfThreadHandle(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.threadHandle); + OVR_strlcat(scratchBuffer, "\n", OVR_ARRAY_COUNT(scratchBuffer)); + WriteReportLine("Thread handle: "); + WriteReportLine(scratchBuffer); + + SprintfThreadSysId(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.threadSysId); + OVR_strlcat(scratchBuffer, "\n", OVR_ARRAY_COUNT(scratchBuffer)); + WriteReportLine("Thread sys id: "); + WriteReportLine(scratchBuffer); + + char addressStr[24]; + SprintfAddress( + addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionInstructionAddress); + WriteReportLineF("Exception instruction address: %s (see callstack below)\n", addressStr); + WriteReportLineF("Exception description: %s\n", exceptionInfo.exceptionDescription); + + if (symbolLookup.LookupSymbol( + (uint64_t)exceptionInfo.pExceptionInstructionAddress, exceptionInfo.symbolInfo)) { + if (exceptionInfo.symbolInfo.filePath[0]) + WriteReportLineF( + "Exception location: %s (%d)\n", + exceptionInfo.symbolInfo.filePath, + exceptionInfo.symbolInfo.fileLineNumber); + else + WriteReportLineF( + "Exception location: %s (%d)\n", + exceptionInfo.symbolInfo.function, + exceptionInfo.symbolInfo.functionOffset); + } + + // To consider: print exceptionInfo.cpuContext registers + } + +#if defined(OVR_OS_WIN32) + { + WriteReportLine("\nApp Info\n"); + + // Print the app path. + char appPath[OVR_MAX_PATH]; + GetCurrentProcessFilePath(appPath, OVR_ARRAY_COUNT(appPath)); + WriteReportLineF("Process path: %s\n", appPath); + +#if (OVR_PTR_SIZE == 4) + WriteReportLine("App format: 32 bit\n"); +#else + WriteReportLine("App format: 64 bit\n"); +#endif + + // Print the app version + wchar_t pathW[OVR_MAX_PATH] = {}; + GetModuleFileNameW(0, pathW, (DWORD)OVR_ARRAY_COUNT(pathW)); + DWORD dwUnused; + DWORD dwSize = GetFileVersionInfoSizeW(pathW, &dwUnused); + scratchBuffer[0] = 0; + + if (dwSize > 0) { + void* const pVersionData = SafeMMapAlloc(dwSize); + + if (pVersionData) { + if (GetFileVersionInfoW(pathW, 0, dwSize, pVersionData)) { + VS_FIXEDFILEINFO* pFFI; + UINT size; + + static HMODULE library; + static std::once_flag once; + std::call_once(once, [&]() { library = LoadLibraryW(L"version.dll"); }); + + decltype(&::VerQueryValueW) const call = reinterpret_cast( + GetProcAddress(library, "VerQueryValueW")); + + if (call(pVersionData, L"\\", (void**)&pFFI, &size)) { + // This is the convention used by RelEng to encode the CL # for releases. + // This greatly simplifies figuring out which version of the Oculus Runtime + // this file came from, though it may not apply to some users of DebugHelp. + // Feel free to ignore it if you're not looking at the Oculus Runtime. + const unsigned CLNum = LOWORD(pFFI->dwFileVersionLS) + 65536; + + WriteReportLineF( + "App version: %u.%u.%u.%u (Runtime Installer CL# %u)\n", + HIWORD(pFFI->dwFileVersionMS), + LOWORD(pFFI->dwFileVersionMS), + HIWORD(pFFI->dwFileVersionLS), + LOWORD(pFFI->dwFileVersionLS), + CLNum); + } + } + + SafeMMapFree(pVersionData, dwSize); + } + } + + if (!scratchBuffer[0]) // If version info couldn't be found or read... + WriteReportLine("App version info not present\n"); + } + + { + WriteReportLine("\nSystem Info\n"); + + OSVERSIONINFOEXW vi; + memset(&vi, 0, sizeof(vi)); + vi.dwOSVersionInfoSize = sizeof(vi); + GetVersionExW((LPOSVERSIONINFOW)&vi); // Cast to the older type. + + char osVersionName[256]; + GetOSVersionName(osVersionName, OVR_ARRAY_COUNT(osVersionName)); + WriteReportLineF( + "OS name: %s, version: %u.%u build %u, %s, platform id: %u, service pack: %ls\n", + osVersionName, + vi.dwMajorVersion, + vi.dwMinorVersion, + vi.dwBuildNumber, + Is64BitOS() ? "64 bit" : "32 bit", + vi.dwPlatformId, + vi.szCSDVersion[0] ? vi.szCSDVersion : L""); + + WriteReportLineF("Debugger present: %s\n", OVRIsDebuggerPresent() ? "yes" : "no"); + + // System info + SYSTEM_INFO systemInfo; + GetNativeSystemInfo(&systemInfo); + + WriteReportLineF("Processor count: %u\n", systemInfo.dwNumberOfProcessors); + + // Windows Vista and later: + // BOOL WINAPI GetLogicalProcessorInformation(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer, + // PDWORD ReturnLength); + + if (systemInfo.wProcessorArchitecture == 0) + WriteReportLineF("Processor type: x86\n"); + else if (systemInfo.wProcessorArchitecture == 9) + WriteReportLineF("Processor type: x86-64\n"); + else if (systemInfo.wProcessorArchitecture == 10) + WriteReportLineF("Processor type: x86 on x86-64\n"); + + WriteReportLineF("Processor level: %u\n", systemInfo.wProcessorLevel); + WriteReportLineF("Processor revision: %u\n", systemInfo.wProcessorRevision); + + // Memory information + MEMORYSTATUSEX memoryStatusEx; + memset(&memoryStatusEx, 0, sizeof(memoryStatusEx)); + memoryStatusEx.dwLength = sizeof(memoryStatusEx); + GlobalMemoryStatusEx(&memoryStatusEx); + + WriteReportLineF("Memory load: %d%%\n", memoryStatusEx.dwMemoryLoad); + WriteReportLineF( + "Total physical memory: %I64d MiB\n", + memoryStatusEx.ullTotalPhys / (1024 * 1024)); // Or are Mebibytes equal to (1024 * 1000) + WriteReportLineF( + "Available physical memory: %I64d MiB\n", memoryStatusEx.ullAvailPhys / (1024 * 1024)); + WriteReportLineF( + "Total page file memory: %I64d MiB\n", memoryStatusEx.ullTotalPageFile / (1024 * 1024)); + WriteReportLineF( + "Available page file memory: %I64d MiB\n", memoryStatusEx.ullAvailPageFile / (1024 * 1024)); + WriteReportLineF( + "Total virtual memory: %I64d MiB\n", memoryStatusEx.ullTotalVirtual / (1024 * 1024)); + WriteReportLineF( + "Free virtual memory: %I64d MiB\n", memoryStatusEx.ullAvailVirtual / (1024 * 1024)); + + DISPLAY_DEVICEW dd; + memset(&dd, 0, sizeof(DISPLAY_DEVICE)); + dd.cb = sizeof(DISPLAY_DEVICE); + + for (int i = 0; EnumDisplayDevicesW(nullptr, (DWORD)i, &dd, EDD_GET_DEVICE_INTERFACE_NAME); + ++i) { + WriteReportLineF( + "Display Device %d name: %ls, context: %ls, primary: %s, mirroring: %s\n", + i, + dd.DeviceName, + dd.DeviceString, + (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) ? "yes" : "no", + (dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ? "yes" : "no"); + } + } + + // Print video card information + // http://msdn.microsoft.com/en-us/library/aa394512%28v=vs.85%29.aspx + { + IWbemLocator* pIWbemLocator = nullptr; + BSTR bstrServer = nullptr; + IWbemServices* pIWbemServices = nullptr; + BSTR bstrWQL = nullptr; + BSTR bstrPath = nullptr; + IEnumWbemClassObject* pEnum = nullptr; + IWbemClassObject* pObj = nullptr; + + CoInitializeEx(nullptr, COINIT_MULTITHREADED); + + HRESULT hr = CoCreateInstance( + __uuidof(WbemLocator), + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWbemLocator), + (LPVOID*)&pIWbemLocator); + if (FAILED(hr)) + goto End; + + bstrServer = SysAllocString(L"\\\\.\\root\\cimv2"); + hr = pIWbemLocator->ConnectServer( + bstrServer, nullptr, nullptr, 0L, 0L, nullptr, nullptr, &pIWbemServices); + if (FAILED(hr)) + goto End; + + hr = CoSetProxyBlanket( + pIWbemServices, + RPC_C_AUTHN_WINNT, + RPC_C_AUTHZ_NONE, + nullptr, + RPC_C_AUTHN_LEVEL_CALL, + RPC_C_IMP_LEVEL_IMPERSONATE, + nullptr, + EOAC_DEFAULT); + if (FAILED(hr)) + goto End; + + bstrWQL = SysAllocString(L"WQL"); + bstrPath = SysAllocString(L"select * from Win32_VideoController"); + hr = pIWbemServices->ExecQuery(bstrWQL, bstrPath, WBEM_FLAG_FORWARD_ONLY, nullptr, &pEnum); + if (FAILED(hr)) + goto End; + + ULONG uReturned; + hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &uReturned); + if (FAILED(hr)) + goto End; + + WriteReportLine("\nDisplay adapter list\n"); + + // helper function to properly init & clear variants + struct VariantHelper { + VariantHelper() { + ::VariantInit(&var); // must init before use + } + ~VariantHelper() { + ::VariantClear(&var); // must clear after use to avoid leaks + } + + BSTR getBSTR() const // return a value or default empty string + { + if ((var.vt == VT_BSTR) && var.bstrVal) + return var.bstrVal; + return CComBSTR(L""); + } + + uint32_t getLVal() const // return a value or default 0 + { + if (var.vt == VT_I4) + return var.lVal; + return 0; + } + + VARIANT* getVARIANT() // convenience function for passing to Get() + { + return &var; + } + + private: + VARIANT var; + }; + + for (unsigned i = 0; SUCCEEDED(hr) && uReturned; i++) { + char sString[256]; + + if (i > 0) + WriteReportLine("\n"); + + WriteReportLineF("Info for display adapter %u\n", i); + + { + VariantHelper v; + hr = pObj->Get(L"Name", 0, v.getVARIANT(), nullptr, nullptr); + if (SUCCEEDED(hr)) { + WideCharToMultiByte( + CP_ACP, 0, v.getBSTR(), -1, sString, sizeof(sString), nullptr, nullptr); + WriteReportLineF("Display Adapter Name: %s\n", sString); + } + } + { + VariantHelper v; + hr = pObj->Get(L"AdapterRAM", 0, v.getVARIANT(), nullptr, nullptr); + if (SUCCEEDED(hr)) { + uint32_t value(v.getLVal()); + + WriteReportLineF( + "Display Adapter RAM: %u %s\n", + (value > (1024 * 1024 * 1024) ? value / (1024 * 1024 * 1024) : value / (1024 * 1024)), + (value > (1024 * 1024 * 1024) ? "GiB" : "MiB")); + } + } + { + VariantHelper v; + hr = pObj->Get(L"DeviceID", 0, v.getVARIANT(), nullptr, nullptr); + if (SUCCEEDED(hr)) { + WideCharToMultiByte( + CP_ACP, 0, v.getBSTR(), -1, sString, sizeof(sString), nullptr, nullptr); + WriteReportLineF("Display Adapter DeviceID: %s\n", sString); + } + } + { + VariantHelper v; + hr = pObj->Get(L"DriverVersion", 0, v.getVARIANT(), nullptr, nullptr); + if (SUCCEEDED(hr)) { + WideCharToMultiByte( + CP_ACP, 0, v.getBSTR(), -1, sString, sizeof(sString), nullptr, nullptr); + WriteReportLineF("Display Adapter DriverVersion: %s\n", sString); + } + } + + { + VariantHelper v; + hr = pObj->Get(L"DriverDate", 0, v.getVARIANT(), nullptr, nullptr); + if (SUCCEEDED(hr)) { + std::wstring val(v.getBSTR()); // may return empty string + + while (val.size() < 8) // make at least 8 chars long to simplify below code + { + val += L" "; + } + + // http://technet.microsoft.com/en-us/library/ee156576.aspx + wchar_t year[5] = {val[0], val[1], val[2], val[3], 0}; + wchar_t month[3] = {val[4], val[5], 0}; + wchar_t monthDay[3] = {val[6], val[7], 0}; + + WriteReportLineF( + "Display Adapter DriverDate (US format): %ls/%ls/%ls\n", month, monthDay, year); + } + } + { + VariantHelper v; + // VideoProcessor + hr = pObj->Get(L"VideoProcessor", 0, v.getVARIANT(), nullptr, nullptr); + if (SUCCEEDED(hr)) { + WideCharToMultiByte( + CP_ACP, 0, v.getBSTR(), -1, sString, sizeof(sString), nullptr, nullptr); + WriteReportLineF("Display Adapter VideoProcessor %s\n", sString); + } + } + + { + VariantHelper v; + hr = pObj->Get(L"VideoModeDescription", 0, v.getVARIANT(), nullptr, nullptr); + if (SUCCEEDED(hr)) { + WideCharToMultiByte( + CP_ACP, 0, v.getBSTR(), -1, sString, sizeof(sString), nullptr, nullptr); + WriteReportLineF("Display Adapter VideoModeDescription: %s\n", sString); + } + } + + pObj->Release(); + + hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &uReturned); + } + + End: + if (pEnum) + pEnum->Release(); + if (bstrPath) + SysFreeString(bstrPath); + if (bstrWQL) + SysFreeString(bstrWQL); + if (pIWbemServices) + pIWbemServices->Release(); + if (bstrServer) + SysFreeString(bstrServer); + if (pIWbemLocator) + pIWbemLocator->Release(); + + CoUninitialize(); + } + + { + // Print a list of threads. + DWORD currentProcessId = GetCurrentProcessId(); + HANDLE hThreadSnap = CreateToolhelp32Snapshot( + TH32CS_SNAPTHREAD, + currentProcessId); // ICreateToolhelp32Snapshot actually ignores currentProcessId. + + if (hThreadSnap != INVALID_HANDLE_VALUE) { + THREADENTRY32 te32; + te32.dwSize = sizeof(THREADENTRY32); + + if (Thread32First(hThreadSnap, &te32)) { + WriteReportLine("\nThread list\n"); + + do { + if (te32.th32OwnerProcessID == currentProcessId) { + OVR::ThreadSysId threadSysId = te32.th32ThreadID; + OVR::ThreadSysId threadSysIdCurrent = ::GetCurrentThreadId(); + + HANDLE hThread = ConvertThreadSysIdToThreadHandle(threadSysId); + + if (hThread) { + if (threadSysId != + threadSysIdCurrent) // If threadSysId refers to a different thread... + { + // We are working with another thread. We need to suspend it and get its CONTEXT. + DWORD suspendResult = ::SuspendThread( + hThread); // Requires that the handle have THREAD_SUSPEND_RESUME rights. + + if (suspendResult == (DWORD)-1) // If failed... + { + WriteReportLineF("Skipping thread id: %u\n", (unsigned)threadSysId); + continue; + } + } + + char + buffer[96]; // Can't use scratchBuffer, because it's used by WriteThreadCallstack. + snprintf( + buffer, + OVR_ARRAY_COUNT(buffer), + "base priority: %ld, delta priority: %ld", + te32.tpBasePri, + te32.tpDeltaPri); + + bool threadIsExceptionThread = + (te32.th32ThreadID == (DWORD)exceptionInfo.threadSysId); + if (threadIsExceptionThread) + OVR_strlcat(buffer, ", exception thread", OVR_ARRAY_COUNT(buffer)); + + WriteThreadCallstack(hThread, (OVR::ThreadSysId)te32.th32ThreadID, buffer); + + if (threadSysId != threadSysIdCurrent) // If we called SuspendThread above... + ::ResumeThread(hThread); + + FreeThreadHandle(hThread); + } + } + } while (Thread32Next(hThreadSnap, &te32)); + } + + CloseHandle(hThreadSnap); + } + } + + { + // Print a list of the current modules within this process. + // DbgHelp.dll also provides a EnumerateLoadedModules64 function. + // To do: Convert the code below to use the GetModuleInfoArray function which we now have. + HMODULE hModule = LoadLibraryW(L"psapi.dll"); + + if (hModule) { + typedef BOOL(WINAPI * ENUMPROCESSMODULES)( + HANDLE hProcess, HMODULE * phModule, DWORD cb, LPDWORD lpcbNeeded); + typedef DWORD(WINAPI * GETMODULEBASENAME)( + HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); + typedef DWORD(WINAPI * GETMODULEFILENAMEEX)( + HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); + typedef BOOL(WINAPI * GETMODULEINFORMATION)( + HANDLE hProcess, HMODULE hModule, MODULEINFO * pmi, DWORD nSize); + + ENUMPROCESSMODULES pEnumProcessModules = + (ENUMPROCESSMODULES)(uintptr_t)GetProcAddress(hModule, "EnumProcessModules"); + GETMODULEBASENAME pGetModuleBaseName = + (GETMODULEBASENAME)(uintptr_t)GetProcAddress(hModule, "GetModuleBaseNameW"); + GETMODULEFILENAMEEX pGetModuleFileNameEx = + (GETMODULEFILENAMEEX)(uintptr_t)GetProcAddress(hModule, "GetModuleFileNameExW"); + GETMODULEINFORMATION pGetModuleInformation = + (GETMODULEINFORMATION)(uintptr_t)GetProcAddress(hModule, "GetModuleInformation"); + + HANDLE hProcess = GetCurrentProcess(); + HMODULE hModuleArray[200]; + DWORD cbNeeded; + + if (pEnumProcessModules(hProcess, hModuleArray, sizeof(hModuleArray), &cbNeeded)) { + size_t actualModuleCount = (cbNeeded / sizeof(HMODULE)); + + if (actualModuleCount > + OVR_ARRAY_COUNT(hModuleArray)) // If hModuleArray's capacity was not enough... + actualModuleCount = OVR_ARRAY_COUNT(hModuleArray); + + // Print a header + WriteReportLine("\nModule list\n"); + +#if (OVR_PTR_SIZE == 4) + WriteReportLine("Base Size Entrypoint Name Path\n"); +#else + WriteReportLine( + "Base Size Entrypoint Name Path\n"); +#endif + + // And go through the list one by one + for (size_t i = 0; i < actualModuleCount; i++) { + MODULEINFO mi; + size_t length; + + if (!pGetModuleInformation(hProcess, hModuleArray[i], &mi, sizeof(mi))) { + mi.EntryPoint = nullptr; + mi.lpBaseOfDll = nullptr; + mi.SizeOfImage = 0; + } + + // Write the base name. + wchar_t name[OVR_MAX_PATH + 3]; + name[0] = '"'; + if (pGetModuleBaseName(hProcess, hModuleArray[i], name + 1, OVR_MAX_PATH)) + length = wcslen(name); + else { + wcscpy(name + 1, L"(unknown)"); + length = 10; + } + + name[length] = '"'; + name[length + 1] = '\0'; + + // Write the path + wchar_t path[OVR_MAX_PATH + 3]; + path[0] = '"'; + if (pGetModuleFileNameEx(hProcess, hModuleArray[i], path + 1, OVR_MAX_PATH)) + length = wcslen(path); + else { + wcscpy(path + 1, L"(unknown)"); + length = 10; + } + path[length] = '"'; + path[length + 1] = '\0'; + +#if (OVR_PTR_SIZE == 4) + WriteReportLineF( + "0x%08x, 0x%08x 0x%08x %-24ls %ls\n", + (uint32_t)mi.lpBaseOfDll, + (uint32_t)mi.SizeOfImage, + (uint32_t)mi.EntryPoint, + name, + path); +#else + WriteReportLineF( + "0x%016I64x 0x%016I64x 0x%016I64x %-24ls %ls\n", + (uint64_t)mi.lpBaseOfDll, + (uint64_t)mi.SizeOfImage, + (uint64_t)mi.EntryPoint, + name, + path); +#endif + } + } + } + } + + { + // Print a list of processes. + // DbgHelp.dll provides a SymEnumProcesses function, but it's available with DbgHelp.dll v6.2 + // which doesn't ship with Windows until Windows 8. + WriteReportLine("\nProcess list\n"); + + if (reportPrivacyEnabled) + WriteReportLine("Disabled by report privacy settings\n"); + else { + HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + if (hProcessSnapshot != INVALID_HANDLE_VALUE) { + PROCESSENTRY32W pe32; + memset(&pe32, 0, sizeof(pe32)); + pe32.dwSize = sizeof(pe32); + + if (Process32FirstW(hProcessSnapshot, &pe32)) { + WriteReportLine("Process Id File\n"); + + do { + // Try to get the full path to the process, as pe32.szExeFile holds only the process + // file name. + // This will typically fail with a privilege error unless this process has debug + // privileges: http://support.microsoft.com/kb/131065/en-us + wchar_t filePathW[OVR_MAX_PATH]; + const wchar_t* pFilePathW = pe32.szExeFile; + HANDLE hProcess = ::OpenProcess( + PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, + FALSE, + pe32.th32ProcessID); // With Windows Vista+ we can use + // PROCESS_QUERY_LIMITED_INFORMATION. + if (hProcess) { + if (GetProcessImageFileNameW(hProcess, filePathW, (DWORD)OVR_ARRAY_COUNT(filePathW))) + pFilePathW = filePathW; + } + + WriteReportLineF("0x%08x %ls\n", pe32.th32ProcessID, pFilePathW); + } while (Process32NextW(hProcessSnapshot, &pe32)); + } + + CloseHandle(hProcessSnapshot); + } else { + WriteReportLine("Unable to read process list\n"); + } + } + } + +#elif defined(OVR_OS_APPLE) || defined(OVR_OS_UNIX) + Is64BitOS(); + GetCurrentProcessFilePath(nullptr, 0); + GetFileNameFromPath(nullptr); + GetOSVersionName(nullptr, 0); + +#endif // OVR_OS_MS + + SymbolLookup::Shutdown(); + + fclose(LogFile); + LogFile = nullptr; +} + +#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) + +static bool IsModuleDataSegmentNeeded(const wchar_t* modulePath) { + if (modulePath) { + const wchar_t* recognizedModuleNames[] = { + // To consider: make this dynamically specifiable by the application. + L"OVRServer_x64", + L"OculusAppFramework", + L"hid", + L"kernel32", + L"KernelBase", + L"msvcrt", + L"ws2_32", + L"mswsock", + L"ntdll", + L"user32", + L"wshtcpip"}; + + const wchar_t* recognizedModulePrefixes[] = {L"d3d", L"dxgi", L"nv", L"ati", L"amd"}; + + wchar_t fileName[MAX_PATH] = {}; + ::_wsplitpath_s(modulePath, NULL, 0, NULL, 0, fileName, MAX_PATH, NULL, 0); + std::transform(fileName, fileName + wcslen(fileName), fileName, ::towlower); + + for (size_t i = 0; i < OVR_ARRAY_COUNT(recognizedModuleNames); ++i) { + if (wcscmp(fileName, recognizedModuleNames[i]) == + 0) // If fileName equals recognizedModuleNames[i]... + return true; + } + + for (size_t i = 0; i < OVR_ARRAY_COUNT(recognizedModulePrefixes); ++i) { + if (wcsstr(fileName, recognizedModulePrefixes[i]) == + fileName) // If fileName begins with recognizedModulePrefixes[i]... + return true; + } + } + + return false; +} + +struct MinidumpCallbackContext { + ExceptionHandler::MinidumpInfoLevel infoLevel; + DWORD minidumpThreadId; +}; + +static BOOL CALLBACK MinidumpFilter( + PVOID pContext, + const PMINIDUMP_CALLBACK_INPUT callbackInput, + PMINIDUMP_CALLBACK_OUTPUT callbackOutput) { + if (!callbackInput || !callbackOutput || !pContext) { + // This should not normally occur. + return FALSE; + } + + // Most of the time, we're going to let the minidump writer do whatever + // it needs to do. However, when trying to limit information for things + // like smaller dumps, we want to filter out various things. So this callback + // is used as a way to filter out information that the user has said they + // don't want. + // + // If we were so inclined, we could use a delegate class to allow the user + // to customize the dump files even further. But for right now, this is + // close enough. + const MinidumpCallbackContext* pFilter = + reinterpret_cast(pContext); + + switch (callbackInput->CallbackType) { + case IncludeModuleCallback: + case ThreadCallback: + case ThreadExCallback: + return TRUE; + + case CancelCallback: + return FALSE; + + case IncludeThreadCallback: + // Return FALSE if the ThreadId is our minidump-writing thread, so it gets skipped. + return (callbackInput->IncludeThread.ThreadId != pFilter->minidumpThreadId); + + case MemoryCallback: + // Include memory only for large dumps. + return (pFilter->infoLevel == ExceptionHandler::kMILLarge); + + case ModuleCallback: { + if (pFilter->infoLevel == ExceptionHandler::kMILSmall) { + // Filter out modules that aren't being referenced by memory. + if (!(callbackOutput->ModuleWriteFlags & ModuleReferencedByMemory)) + callbackOutput->ModuleWriteFlags &= ~ModuleWriteModule; + } else if (pFilter->infoLevel == ExceptionHandler::kMILMedium) { + // Filter out modules that aren't of primary interest to us. + if (callbackOutput->ModuleWriteFlags & ModuleWriteDataSeg) { + if (!IsModuleDataSegmentNeeded(callbackInput->Module.FullPath)) + callbackOutput->ModuleWriteFlags &= ~ModuleWriteDataSeg; + } + } else if (pFilter->infoLevel == ExceptionHandler::kMILLarge) { + // We currently write all modules. + } + + return TRUE; + } + } + + return FALSE; +} + +#endif // defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) + +void ExceptionHandler::WriteMiniDump() { + if (minidumpInfoLevel == kMILNone) + return; + + if (strstr( + miniDumpFilePath, + "%s")) // If the user-specified file path includes a date/time component... + { + char dateTimeBuffer[64]; + FormatDateTime( + dateTimeBuffer, + OVR_ARRAY_COUNT(dateTimeBuffer), + exceptionInfo.timeVal, + true, + true, + false, + true); + snprintf( + minidumpFilePathActual, + OVR_ARRAY_COUNT(minidumpFilePathActual), + miniDumpFilePath, + dateTimeBuffer); + } else { + OVR_strlcpy(minidumpFilePathActual, miniDumpFilePath, OVR_ARRAY_COUNT(minidumpFilePathActual)); + } + +#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) + typedef BOOL(WINAPI * MINIDUMPWRITEDUMP)( + HANDLE hProcess, + DWORD ProcessId, + HANDLE hFile, + MINIDUMP_TYPE dumpType, + CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); + HMODULE hModuleDbgHelp = LoadLibraryW(L"DbgHelp.dll"); + + MINIDUMPWRITEDUMP pMiniDumpWriteDump = hModuleDbgHelp + ? (MINIDUMPWRITEDUMP)(void*)GetProcAddress(hModuleDbgHelp, "MiniDumpWriteDump") + : nullptr; + + if (pMiniDumpWriteDump) { + wchar_t miniDumpFilePathW[OVR_MAX_PATH]; + auto requiredUTF8Length = OVR::UTF8Util::Strlcpy( + miniDumpFilePathW, OVR_ARRAY_COUNT(miniDumpFilePathW), minidumpFilePathActual); + if (requiredUTF8Length < OVR_ARRAY_COUNT(miniDumpFilePathW)) { + HANDLE hFile = CreateFileW( + miniDumpFilePathW, + GENERIC_READ | GENERIC_WRITE, + 0, + 0, + CREATE_ALWAYS, + FILE_FLAG_WRITE_THROUGH, + 0); + + if (hFile != INVALID_HANDLE_VALUE) { + MINIDUMP_EXCEPTION_INFORMATION minidumpExceptionInfo = { + ::GetCurrentThreadId(), pExceptionPointers, TRUE}; + + int miniDumpFlags = MiniDumpNormal; + + switch ((int)minidumpInfoLevel) { + case kMILSmall: { + miniDumpFlags |= MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory; + break; + } + + case kMILMedium: { + miniDumpFlags |= MiniDumpWithDataSegs | MiniDumpWithPrivateReadWriteMemory | + MiniDumpWithHandleData | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo | + MiniDumpWithUnloadedModules; + break; + } + + case kMILLarge: { + miniDumpFlags |= MiniDumpWithDataSegs | MiniDumpWithPrivateReadWriteMemory | + MiniDumpWithHandleData | MiniDumpWithFullMemory | MiniDumpWithFullMemoryInfo | + MiniDumpWithThreadInfo | MiniDumpWithUnloadedModules | + MiniDumpWithProcessThreadData | MiniDumpIgnoreInaccessibleMemory | + MiniDumpWithTokenInformation; + break; + } + } + + MinidumpCallbackContext minidumpCallbackContext = {minidumpInfoLevel, + ::GetCurrentThreadId()}; + MINIDUMP_CALLBACK_INFORMATION minidumpCallbackInfo = {MinidumpFilter, + &minidumpCallbackContext}; + + // We are about to write out a minidump due to a crash. This minidump write can take a very + // long time. + // Look up the stack to see what went wrong. This is a bug in the code somewhere. + if (OVRIsDebuggerPresent()) { + OVR_ASSERT(false); + } + + BOOL result = pMiniDumpWriteDump( + GetCurrentProcess(), + GetCurrentProcessId(), + hFile, + (MINIDUMP_TYPE)miniDumpFlags, + pExceptionPointers ? &minidumpExceptionInfo : nullptr, + (CONST PMINIDUMP_USER_STREAM_INFORMATION) nullptr, + &minidumpCallbackInfo); + CloseHandle(hFile); + hFile = 0; + + OVR_ASSERT(result); + if (!result) { +// We print out some error information in debug builds. We can't write to +// a log because we are likely executing this within an exception. +#if defined(OVR_BUILD_DEBUG) + DWORD dwError = GetLastError(); + char errorBufferA[1024]; + DWORD errorBufferACapacity = OVR_ARRAY_COUNT(errorBufferA); + DWORD length = FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + dwError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + errorBufferA, + errorBufferACapacity, + nullptr); + + if (length) { + OutputDebugStringA("MiniDumpWriteDump failure: "); + OutputDebugStringA(errorBufferA); + } +#endif + + DeleteFileW(miniDumpFilePathW); + } + } else { + // XXX this will never assert + OVR_ASSERT(pMiniDumpWriteDump); // OVR_FAIL_F(("ExceptionHandler::WriteMiniDump: Failed to + // create minidump file at %s", minidumpFilePathActual)); + } + } else { + // failed to convert miniDumpFilePathW + OVR_ASSERT(false); + } + } + + FreeLibrary(hModuleDbgHelp); +#else +// Some platforms support various forms or exception reports and core dumps which are automatically +// generated upon us +// returning from our own exception handling. We might want to put something here if we are using a +// custom version of +// this, such as Google Breakpad. +#endif +} + +void ExceptionHandler::SetExceptionListener( + ExceptionListener* pExceptionListener, + uintptr_t userValue) { + exceptionListener = pExceptionListener; + exceptionListenerUserValue = userValue; +} + +void ExceptionHandler::SetAppDescription(const char* pAppDescription) { + appDescription = pAppDescription; +} + +void ExceptionHandler::SetExceptionPaths( + const char* exceptionReportPath, + const char* exceptionMiniDumpFilePath) { + char tempPath[OVR_MAX_PATH]; + + if (exceptionReportPath) { + if (OVR_stricmp(exceptionReportPath, "default") == 0) { + GetCrashDumpDirectory(tempPath, OVR_ARRAY_COUNT(tempPath)); + OVR::OVR_strlcat(tempPath, "Exception Report (%s).txt", OVR_ARRAY_COUNT(tempPath)); + exceptionReportPath = tempPath; + } + + OVR_strlcpy(reportFilePath, exceptionReportPath, OVR_ARRAY_COUNT(reportFilePath)); + } else { + reportFilePath[0] = '\0'; + } + + if (exceptionMiniDumpFilePath) { + if (OVR_stricmp(exceptionMiniDumpFilePath, "default") == 0) { + GetCrashDumpDirectory(tempPath, OVR_ARRAY_COUNT(tempPath)); + OVR::OVR_strlcat(tempPath, "Exception Minidump (%s).mdmp", OVR_ARRAY_COUNT(tempPath)); + exceptionMiniDumpFilePath = tempPath; + } + + OVR_strlcpy(miniDumpFilePath, exceptionMiniDumpFilePath, OVR_ARRAY_COUNT(miniDumpFilePath)); + } else { + miniDumpFilePath[0] = '\0'; + } +} + +void ExceptionHandler::SetCodeBaseDirectoryPaths( + const char* codeBaseDirectoryPathArray[], + size_t codeBaseDirectoryPathCount) { + for (size_t i = 0, + iCount = OVR::Alg::Min( + codeBaseDirectoryPathCount, OVR_ARRAY_COUNT(codeBasePathArray)); + i != iCount; + ++i) { + codeBasePathArray[i] = codeBaseDirectoryPathArray[i]; + } +} + +const char* ExceptionHandler::GetExceptionUIText(const char* exceptionReportPath) { + char* uiText = nullptr; + OVR::SysFile file(exceptionReportPath, SysFile::Open_Read, SysFile::Mode_ReadWrite); + + if (file.IsValid()) { + size_t length = (size_t)file.GetLength(); + uiText = (char*)OVR::SafeMMapAlloc(length + 1); + + if (uiText) { + file.Read((uint8_t*)uiText, (int)length); + uiText[length] = '\0'; + file.Close(); + +// Currently on Mac our message box implementation is unable to display arbitrarily large amounts of +// text. +// So we reduce its size to a more summary version before presenting. +#if defined(OVR_OS_MAC) + struct Find { + static char* PreviousChar(char* p, char c) { + while (*p != c) + p--; + return p; + } + }; // Assumes the given c is present prior to p. + + // Print that the full report is at + // Exception Info section + // Exception thread callstack. + char empty[] = ""; + char* pExceptionInfoBegin = + strstr(uiText, "Exception Info") ? strstr(uiText, "Exception Info") : empty; + char* pExceptionInfoEnd = + (pExceptionInfoBegin == empty) ? (empty + 1) : strstr(uiText, "\n\n"); + char* pExceptionThreadArea = strstr(uiText, ", exception thread"); + char* pExceptionThreadBegin = + pExceptionThreadArea ? Find::PreviousChar(pExceptionThreadArea, '\n') + 1 : empty; + char* pExceptionThreadEnd = + (pExceptionThreadBegin == empty) ? (empty + 1) : strstr(pExceptionThreadArea, "\n\n"); + + if (!pExceptionInfoEnd) + pExceptionInfoEnd = pExceptionInfoBegin; + *pExceptionInfoEnd = '\0'; + + if (!pExceptionThreadEnd) + pExceptionThreadEnd = pExceptionThreadBegin; + *pExceptionThreadEnd = '\0'; + + size_t uiTextBriefLength = snprintf( + nullptr, + 0, + "Full report:%s\n\nSummary report:\n%s\n\n%s", + exceptionReportPath, + pExceptionInfoBegin, + pExceptionThreadBegin); + char* uiTextBrief = (char*)OVR::SafeMMapAlloc(uiTextBriefLength + 1); + + if (uiTextBrief) { + snprintf( + uiTextBrief, + uiTextBriefLength + 1, + "Full report:%s\n\nSummary report:\n%s\n\n%s", + exceptionReportPath, + pExceptionInfoBegin, + pExceptionThreadBegin); + OVR::SafeMMapFree(uiText, length); + uiText = uiTextBrief; + } +#endif + } + } + + return uiText; +} + +void ExceptionHandler::FreeExceptionUIText(const char* messageBoxText) { + OVR::SafeMMapFree(messageBoxText, OVR_strlen(messageBoxText)); +} + +void ExceptionHandler::ReportDeadlock( + const char* threadName, + const char* organizationName, + const char* applicationName) { + if (!organizationName || !organizationName[0]) + organizationName = "Oculus"; + if (!applicationName || !applicationName[0]) + applicationName = "DefaultApp"; + + ExceptionHandler handler; + + handler.SetPathsFromNames( + organizationName, applicationName, "Deadlock Report (%s).txt", "Deadlock Minidump (%s).mdmp"); + + snprintf( + handler.exceptionInfo.exceptionDescription, + sizeof(handler.exceptionInfo.exceptionDescription), + "Deadlock in thread '%s'", + threadName ? threadName : "(null)"); + + handler.exceptionInfo.timeVal = time(nullptr); + handler.exceptionInfo.time = *gmtime(&handler.exceptionInfo.timeVal); + handler.WriteReport("Deadlock"); + handler.WriteMiniDump(); +} + +static ovrlog::Channel DefaultChannel("Kernel:Default"); +static OVRAssertionHandler sOVRAssertionHandler = OVR::DefaultAssertionHandler; +static intptr_t sOVRAssertionHandlerUserParameter = 0; + +OVRAssertionHandler GetAssertionHandler(intptr_t* userParameter) { + if (userParameter) + *userParameter = sOVRAssertionHandlerUserParameter; + return sOVRAssertionHandler; +} + +void SetAssertionHandler(OVRAssertionHandler assertionHandler, intptr_t userParameter) { + sOVRAssertionHandler = assertionHandler; + sOVRAssertionHandlerUserParameter = userParameter; +} + +intptr_t +DefaultAssertionHandler(intptr_t /*userParameter*/, const char* title, const char* message) { + if (OVRIsDebuggerPresent()) { + OVR_DEBUG_BREAK; + } else if (OVR::IsAutomationRunning()) { + DefaultChannel.LogWarning("[Assertion] ", title, ": ", std::string(message)); + } else { + OVR_UNUSED(title); + OVR_UNUSED(message); + +#if defined(OVR_BUILD_DEBUG) + if (Allocator::GetInstance()) // The code below currently depends on having a valid Allocator. + { + // Print a stack trace of all threads. + OVR::String s; + OVR::String threadListOutput; + static OVR::SymbolLookup symbolLookup; + + s = "Failure: "; + s += message; + + if (symbolLookup.Initialize() && + symbolLookup.ReportThreadCallstack(threadListOutput, 4)) // This '4' is there to skip our + // internal handling and retrieve + // starting at the assertion + // location (our caller) only. + { + // threadListOutput has newlines that are merely \n, whereas Windows MessageBox wants \r\n + // newlines. So we insert \r in front of all \n. + for (size_t i = 0, iEnd = threadListOutput.GetSize(); i < iEnd; i++) { + if (threadListOutput[i] == '\n') { + threadListOutput.Insert("\r", i, 1); + ++i; + ++iEnd; + } + } + + s += "\r\n\r\n"; + s += threadListOutput; + } + + OVR::Util::DisplayMessageBox(title, s.ToCStr()); + } else { + // See above. + OVR::Util::DisplayMessageBox(title, message); + } +#else + OVR::Util::DisplayMessageBox(title, message); +#endif + } + + return 0; +} + +bool IsAutomationRunning() { +#if defined(OVR_OS_WIN32) + // We use the OS GetEnvironmentVariable function as opposed to getenv, as that + // is process-wide as opposed to being tied to the current C runtime library. + return GetEnvironmentVariableW(L"OvrAutomationRunning", NULL, 0) > 0; +#else + return getenv("OvrAutomationRunning") != nullptr; +#endif +} + +//----------------------------------------------------------------------------- +// GUI Exception Listener + +GUIExceptionListener::GUIExceptionListener() : Handler() {} + +int GUIExceptionListener::HandleException( + uintptr_t userValue, + ExceptionHandler* pExceptionHandler, + ExceptionInfo* pExceptionInfo, + const char* reportFilePath) { + OVR_UNUSED3(userValue, pExceptionHandler, pExceptionInfo); + + // If an automated test is running or the debugger is present skip the dialog. + if (!(OVR::IsAutomationRunning() || OVRIsDebuggerPresent())) { + const char* uiText = ExceptionHandler::GetExceptionUIText(reportFilePath); + if (uiText) { + OVR::Util::DisplayMessageBox("Exception occurred", uiText); + ExceptionHandler::FreeExceptionUIText(uiText); + } + } + return 0; +} + +} // namespace OVR + +OVR_RESTORE_MSVC_WARNING() diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DebugHelp.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DebugHelp.h new file mode 100644 index 0000000..c11e032 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_DebugHelp.h @@ -0,0 +1,723 @@ +/************************************************************************************ + +Filename : OVR_DebugHelp.h +Content : Platform-independent exception handling interface +Created : October 6, 2014 + +Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_DebugHelp_h +#define OVR_DebugHelp_h + +#include "OVR_Atomic.h" +#include "OVR_Nullptr.h" +#include "OVR_String.h" +#include "OVR_System.h" +#include "OVR_Threads.h" +#include "OVR_Types.h" + +#include +#include + +#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) +#include "OVR_Win32_IncludeWindows.h" +#elif defined(OVR_OS_APPLE) || defined(OVR_OS_LINUX) +#include +#endif + +OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized + +namespace OVR { + +// Thread identifiers +// typedef void* ThreadHandle; // Already defined by OVR Threads. Same as Windows thread +// handle, Unix pthread_t. +// typedef void* ThreadId; // Already defined by OVR Threads. Used by Windows as DWORD +// thread id, by Unix as pthread_t. +typedef uintptr_t ThreadSysId; // System thread identifier. Used by Windows the same as ThreadId +// (DWORD), thread_act_t on Mac/BSD, lwp id on Linux. + +// Thread constants +// To do: Move to OVR Threads +#define OVR_THREADHANDLE_INVALID ((ThreadHandle*)nullptr) +#define OVR_THREADID_INVALID ((ThreadId*)nullptr) +#define OVR_THREADSYSID_INVALID ((uintptr_t)0) + +OVR::ThreadSysId ConvertThreadHandleToThreadSysId(OVR::ThreadHandle threadHandle); +OVR::ThreadHandle ConvertThreadSysIdToThreadHandle( + OVR::ThreadSysId threadSysId); // The returned handle must be freed with FreeThreadHandle. +void FreeThreadHandle(OVR::ThreadHandle threadHandle); // Frees the handle returned by +// ConvertThreadSysIdToThreadHandle. +OVR::ThreadSysId GetCurrentThreadSysId(); + +void GetOSVersionName(char* versionName, size_t versionNameCapacity); + +// CPUContext +#if defined(OVR_OS_MS) +typedef CONTEXT CPUContext; +#elif defined(OVR_OS_MAC) || defined(OVR_OS_LINUX) +typedef int CPUContext; // To do. +#endif + +// Force OVRIsDebuggerPresent to return false +void ForceDebuggerNotPresent(); +// Allow debugger check to proceded as normal +void ClearDebuggerNotPresent(); +// Tells if the current process appears to be running under a debugger. Does not attempt to +// detect the case of stealth debuggers (malware-related for example). +bool OVRIsDebuggerPresent(); + +// Exits the process with the given exit code. +#if !defined(OVR_NORETURN) +#if defined(OVR_CC_MSVC) +#define OVR_NORETURN __declspec(noreturn) +#else +#define OVR_NORETURN __attribute__((noreturn)) +#endif +#endif +OVR_NORETURN void ExitProcess(intptr_t processReturnValue); + +// Returns the instruction pointer of the caller for the position right after the call. +OVR_NO_INLINE void* GetInstructionAddress(); + +// Returns the instruction pointer of the call to the caller of this function. +// This is a macro defined as with the following C declaration: +// void* GetInstructionAddress(); +#ifndef OVRGetReturnAddress +#if defined(_MSC_VER) +#define OVRGetReturnAddress() _ReturnAddress() +#else // GCC, clang +#define OVRGetReturnAddress() __builtin_return_address(0) +#endif +#endif + +// Returns the stack base and limit addresses for the given thread, or for the current thread if the +// threadHandle is default. +// The stack limit is a value less than the stack base on most platforms, as stacks usually grow +// downward. +// Some platforms (e.g. Microsoft) have dynamically resizing stacks, in which case the stack limit +// reflects the current limit. +void GetThreadStackBounds( + void*& pStackBase, + void*& pStackLimit, + ThreadHandle threadHandle = OVR_THREADHANDLE_INVALID); + +enum MemoryAccess { kMANone = 0x00, kMARead = 0x01, kMAWrite = 0x02, kMAExecute = 0x04 }; + +// Returns MemoryAccess flags. Returns kMAUnknown for unknown access. +int GetMemoryAccess(const void* p); + +/// Used by KillCdeclFunction and RestoreCdeclFunction +/// +struct SavedFunction { + void* Function; + uint8_t Size; + uint8_t Data[15]; + void* FunctionImplementation; // Points to the original function, if possible to use it. + + SavedFunction() : Function(nullptr), Size(0), FunctionImplementation(nullptr) {} + + SavedFunction(int) {} // Intentionally uninitialized +}; + +/// Overwrites the implementation of a statically linked function with an implementation +/// that unilaterally returns the given int32_t value. Works regardless of the arguments +/// passed to that function by the caller. This version is specific to cdecl functions +/// as opposed to Microsoft stdcall functions. Requires the ability to use VirtualProtect +/// to change the code memory to be writable. Returns true if the operation was successful. +/// +/// Since this function overwrites the memory of the existing function implementation, +/// it reequires the function to have at least enough bytes for this. If functionReturnValue +/// is zero then pFunction must be at least three bytes in size. If functionReturnValue is +/// non-zero then pFunction must be at least six bytes in size. +/// +/// Example usage: +/// int __cdecl _CrtIsValidHeapPointer(const void* heapPtr); +/// +/// void main(int, char*[]){ +/// KillCdeclFunction(_CrtIsValidHeapPointer, TRUE); // Make _CrtIsValidHeapPointer always +/// return true. +/// } +/// +bool KillCdeclFunction( + void* pFunction, + int32_t functionReturnValue, + SavedFunction* pSavedFunction = nullptr); + +/// This version is for functions that return void. It causes them to immediately return. +/// +/// Example usage: +/// void __cdecl _CrtCheckMemory(); +/// +/// void main(int, char*[]){ +/// KillCdeclFunction(_CrtCheckMemory); +/// } +/// +bool KillCdeclFunction(void* pFunction, SavedFunction* pSavedFunction = nullptr); + +/// RedirectCdeclFunction +/// +/// Upon success, pSavedFunction is modified to contain a saved copy of the modified bytes. +/// Upon failure, pSavedFunction is not modified. +/// RestoreCdeclFunction can be used to restore the bytes saved by pSavedFunction. +/// +/// Example usage: +/// void* MyMalloc(size_t n) +/// { ... } +/// RedirectCdeclFunction(malloc, MyMalloc); +/// +bool RedirectCdeclFunction( + void* pFunction, + const void* pDestFunction, + OVR::SavedFunction* pSavedFunction = nullptr); + +/// Restores a function which was previously killed by KillCdeclFunction. +/// +/// Example usage: +/// void main(int, char*[]){ +/// SavedFunction savedFunction +/// KillCdeclFunction(_CrtCheckMemory, &savedFunction); +/// [...] +/// RestoreCdeclFunction(&savedFunction); +/// } +/// +bool RestoreCdeclFunction(SavedFunction* pSavedFunction); + +/// Smart class which temporarily kills a function and restores it upon scope completion. +/// +/// Example usage: +/// void main(int, char*[]){ +/// TempCdeclFunctionKill tempKill(_CrtIsValidHeapPointer, TRUE); +/// [...] +/// } +/// +struct TempCdeclFunctionKill { + TempCdeclFunctionKill(void* pFunction, int32_t functionReturnValue) + : Success(false), FunctionPtr(nullptr), SavedFunctionData() { + Success = KillCdeclFunction(pFunction, functionReturnValue, &SavedFunctionData); + } + + TempCdeclFunctionKill(void* pFunction) + : Success(false), FunctionPtr(nullptr), SavedFunctionData() { + Success = KillCdeclFunction(pFunction, &SavedFunctionData); + } + + ~TempCdeclFunctionKill() { + if (Success) + RestoreCdeclFunction(&SavedFunctionData); + } + + bool Success; + void* FunctionPtr; + SavedFunction SavedFunctionData; +}; + +/// Class which implements copying the executable bytes of a function to a newly allocated page. +/// This is useful for when doing some kinds of function interception and overriding at runtime. +/// +/// Example usage: +/// void main(int, char*[]){ +/// CopiedFunction strlenCopy(strlen); +/// size_t n = strlen("test"); // Will execute through the newly allocated version of strlen. +/// } +/// +class CopiedFunction { + public: + CopiedFunction(const void* pFunction = nullptr, size_t size = 0); + ~CopiedFunction(); + + const void* Copy(const void* pFunction, size_t size); + + void Free(); + + const void* GetFunction() const { + return Function; + } + + protected: + const void* GetRealFunctionLocation(const void* pFunction); + + void* Function; +}; + +// OVR_MAX_PATH +// Max file path length (for most uses). +// To do: move this to OVR_File. +#if !defined(OVR_MAX_PATH) +#if defined( \ + OVR_OS_MS) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx +#define OVR_MAX_PATH \ + 260 // Windows can use paths longer than this in some cases (network paths, UNC paths). +#else +#define OVR_MAX_PATH 1024 // This isn't a strict limit on all Unix-based platforms. +#endif +#endif + +// ModuleHandle +#if defined(OVR_OS_MS) +typedef void* ModuleHandle; // from LoadLibrary() +#elif defined(OVR_OS_APPLE) || defined(OVR_OS_UNIX) +typedef void* ModuleHandle; // from dlopen() +#endif + +#define OVR_MODULEHANDLE_INVALID ((ModuleHandle*)nullptr) + +// Module info constants +static const ModuleHandle kMIHandleInvalid = OVR_MODULEHANDLE_INVALID; +static const uint64_t kMIAddressInvalid = 0xffffffffffffffffull; +static const uint64_t kMISizeInvalid = 0xffffffffffffffffull; +static const int32_t kMILineNumberInvalid = -1; +static const int32_t kMIFunctionOffsetInvalid = -1; +static const uint64_t kMIBaseAddressInvalid = 0xffffffffffffffffull; +static const uint64_t kMIBaseAddressUnspecified = 0xffffffffffffffffull; + +struct ModuleInfo { + ModuleHandle handle; + uint64_t baseAddress; // The actual runtime base address of the module. May be different from + // the base address specified in the debug symbol file, because the module may be placed at a + // different address on startup. + uint64_t size; + char filePath[OVR_MAX_PATH]; // UTF8 encoded + char name[32]; // UTF8 encoded + char type[8]; // Unix-specific. e.g. __TEXT + char permissions[8]; // Unix specific. e.g. "drwxr-xr-x" + + ModuleInfo() + : handle(kMIHandleInvalid), baseAddress(kMIBaseAddressInvalid), size(0), filePath(), name() {} +}; + +// Refers to symbol info for an instruction address. +// Info includes function name, source code file/line, and source code itself. +struct SymbolInfo { + uint64_t address; + uint64_t size; + const ModuleInfo* pModuleInfo; + char filePath[OVR_MAX_PATH]; + int32_t fileLineNumber; + char function[384]; // This is a fixed size because we need to use it during application + // exceptions. + int32_t functionOffset; + char sourceCode[1024]; // This is a string representing the code itself and not a file path to the + // code. + + SymbolInfo() + : address(kMIAddressInvalid), + size(kMISizeInvalid), + pModuleInfo(nullptr), + filePath(), + fileLineNumber(kMILineNumberInvalid), + function(), + functionOffset(kMIFunctionOffsetInvalid), + sourceCode() {} +}; + +// Implements support for reading thread lists, module lists, backtraces, and backtrace symbols. +class SymbolLookup { + public: + SymbolLookup(); + ~SymbolLookup() = default; + + // Every successful call to Initialize must be eventually matched by a call to Shutdown. + // Shutdown should be called if and only if Initialize returns true. + static bool Initialize(); + + static bool IsInitialized(); + + static void Shutdown(); + + void AddSourceCodeDirectory(const char* pDirectory); + + // Should be disabled when within an exception handler. + void EnableMemoryAllocation(bool enabled); + + // Refresh our view of the symbols and modules present within the current process. + bool Refresh(); + + // Retrieves the backtrace (call stack) of the given thread. There may be some per-platform + // restrictions on this. + // Returns the number written, which will be <= addressArrayCapacity. + // This may not work on some platforms unless stack frames are enabled. + // For Microsoft platforms the platformThreadContext is CONTEXT*. + // For Apple platforms the platformThreadContext is x86_thread_state_t* or arm_thread_state_t*. + // If threadSysIdHelp is non-zero, it may be used by the implementation to help produce a better + // backtrace. + static size_t GetBacktrace( + void* addressArray[], + size_t addressArrayCapacity, + size_t skipCount = 0, + void* platformThreadContext = nullptr, + OVR::ThreadSysId threadSysIdHelp = OVR_THREADSYSID_INVALID); + + // Retrieves the backtrace for the given ThreadHandle. + // Returns the number written, which will be <= addressArrayCapacity. + static size_t GetBacktraceFromThreadHandle( + void* addressArray[], + size_t addressArrayCapacity, + size_t skipCount = 0, + OVR::ThreadHandle threadHandle = OVR_THREADHANDLE_INVALID); + + // Retrieves the backtrace for the given ThreadSysId. + // Returns the number written, which will be <= addressArrayCapacity. + static size_t GetBacktraceFromThreadSysId( + void* addressArray[], + size_t addressArrayCapacity, + size_t skipCount = 0, + OVR::ThreadSysId threadSysId = OVR_THREADSYSID_INVALID); + + enum ModuleSort { ModuleSortNone = 0, ModuleSortByAddress, ModuleSortByName }; + + // Gets a list of the modules (e.g. DLLs) present in the current process. + // Writes as many ModuleInfos as possible to pModuleInfoArray. + // Returns the required count of ModuleInfos, which will be > moduleInfoArrayCapacity if the + // capacity needs to be larger. + static size_t GetModuleInfoArray( + ModuleInfo* pModuleInfoArray, + size_t moduleInfoArrayCapacity, + ModuleSort moduleSort = ModuleSortNone); + + // Retrieves a list of the current threads. Unless the process is paused the list is volatile. + // Returns the required capacity, which may be larger than threadArrayCapacity. + // Either array can be NULL to specify that it's not written to. + // For Windows the caller needs to CloseHandle the returned ThreadHandles. This can be done by + // calling DoneThreadList. + static size_t GetThreadList( + ThreadHandle* threadHandleArray, + ThreadSysId* threadSysIdArray, + size_t threadArrayCapacity); + + // Frees any references to thread handles or ids returned by GetThreadList; + static void DoneThreadList( + ThreadHandle* threadHandleArray, + ThreadSysId* threadSysIdArray, + size_t threadArrayCount); + + // Writes a given thread's callstack with symbols to the given output. + // It may not be safe to call this from an exception handler, as sOutput allocates memory. + bool ReportThreadCallstack( + OVR::String& sOutput, + size_t skipCount = 0, + ThreadSysId threadSysId = OVR_THREADSYSID_INVALID); + + // Writes all thread's callstacks with symbols to the given output. + // It may not be safe to call this from an exception handler, as sOutput allocates memory. + bool ReportThreadCallstacks(OVR::String& sOutput, size_t skipCount = 0); + + // Writes all loaded modules to the given output string. + // It may not be safe to call this from an exception handler, as sOutput allocates memory. + bool ReportModuleInformation(OVR::String& sOutput); + + // Retrieves symbol info for the given address. + bool LookupSymbol(uint64_t address, SymbolInfo& symbolInfo); + bool LookupSymbols(uint64_t* addressArray, SymbolInfo* pSymbolInfoArray, size_t arraySize); + + // The returned ModuleInfo points to an internal structure. This function assumes that the + // internal cached ModuleInfo array is valid. If modules are dynamically added or removed + // during runtime then the array may be partially out of date. + // May return NULL if there was no found module for the address. + const ModuleInfo* GetModuleInfoForAddress(uint64_t address); + + const ModuleInfo& GetModuleInfoForCurrentModule(); + + protected: + bool RefreshModuleList(); + + protected: + // True by default. If true then we allow allocating memory (and as a + // result provide less information). This is useful for when in an + // exception handler. + bool AllowMemoryAllocation; + bool ModuleListUpdated; + + // Cached list of modules we use. This is a fixed size because + // we need to use it during application exceptions. + ModuleInfo ModuleInfoArray[256]; + size_t ModuleInfoArraySize; + + // The ModuleInfo for the current module, which is often needed and so we make a member for it. + ModuleInfo currentModuleInfo; +}; + +// ExceptionInfo +// We need to be careful to avoid data types that can allocate memory while we are +// handling an exception, as the memory system may be corrupted at that point in time. +struct ExceptionInfo { + tm time; // GM time. + time_t timeVal; // GM time_t (seconds since 1970). + void* backtrace[64]; + size_t backtraceCount; + ThreadHandle threadHandle; // + ThreadSysId threadSysId; // + char threadName[32]; // Cannot be an allocating String object. + void* pExceptionInstructionAddress; + void* pExceptionMemoryAddress; + CPUContext cpuContext; + char exceptionDescription[1024]; // Cannot be an allocating String object. + SymbolInfo symbolInfo; // SymbolInfo for the exception location. + +#if defined(OVR_OS_MS) + EXCEPTION_RECORD exceptionRecord; // This is a Windows SDK struct. +#endif + + ExceptionInfo(); +}; + +// Implments support for asynchronous exception handling and basic exception report generation. +// If you are implementing exception handling for a commercial application and want auto-uploading +// functionality you may want to consider using something like Google Breakpad. This exception +// handler +// is for in-application debug/diagnostic services, though it can write a report that has similar +// information to Breakpad or OS-provided reports such as Apple .crash files. +// +// Example usage: +// ExceptionHandler exceptionHandler; +// +// int main(int, char**) +// { +// exceptionHandler.Enable(true); +// exceptionHandler.SetExceptionListener(pSomeListener, 0); // Optional listener hook. +// } +// +class ExceptionHandler { + public: + ExceptionHandler(); + ~ExceptionHandler(); + + // Enables or disables handling by installing or uninstalling an exception handler. + // If you merely want to temporarily pause handling then it may be better to cause PauseHandling, + // as that's a lighter weight solution. + bool Enable(bool enable); + + // Pauses handling. Exceptions will be caught but immediately passed on to the next handler + // without taking any action. Pauses are additive and calls to Pause(true) must be eventually + // matched to Pause(false). This function can be called from multiple threads simultaneously. + // Returns the new pause count. + int PauseHandling(bool pause); + + // Some report info can be considered private information of the user, such as the current process + // list, + // computer name, IP address or other identifying info, etc. We should not report this information + // for + // external users unless they agree to this. + void EnableReportPrivacy(bool enable); + + struct ExceptionListener { + virtual ~ExceptionListener() {} + virtual int HandleException( + uintptr_t userValue, + ExceptionHandler* pExceptionHandler, + ExceptionInfo* pExceptionInfo, + const char* reportFilePath) = 0; + }; + + void SetExceptionListener(ExceptionListener* pExceptionListener, uintptr_t userValue); + + // What we do after handling the exception. + enum ExceptionResponse { + kERContinue, // Continue execution. Will result in the exception being re-generated unless the + // application has fixed the cause. Similar to Windows + // EXCEPTION_CONTINUE_EXECUTION. + kERHandle, // Causes the OS to handle the exception as it normally would. Similar to Windows + // EXCEPTION_EXECUTE_HANDLER. + kERTerminate, // Exit the application. + kERThrow, // Re-throw the exception. Other handlers may catch it. Similar to Windows + // EXCEPTION_CONTINUE_SEARCH. + kERDefault // Usually set to kERTerminate. + }; + + void SetExceptionResponse(ExceptionResponse er) { + exceptionResponse = er; + } + + // Allws you to add an arbitrary description of the current application, which will be added to + // exception reports. + void SetAppDescription(const char* appDescription); + + // Specifies how much info the minidump has, but also how large it gets. + enum MinidumpInfoLevel { + kMILNone, // Don't generate a .mdmp file. + kMILSmall, // Will result in a .mdmp file that's about 10-30 KiB + kMILMedium, // Will result in a .mdmp file that's about 5-15 MiB + kMILLarge // Will result in a .mdmp file that's about 50-150 MiB. + }; + + void SetMinidumpInfoLevel(MinidumpInfoLevel level) { + minidumpInfoLevel = level; + } + + MinidumpInfoLevel GetMinidumpInfoLevel() const { + return minidumpInfoLevel; + } + + // If the report path has a "%s" in its name, then assume the path is a sprintf format and write + // it + // with the %s specified as a date/time string. + // The report path can be "default" to signify that you want to use the default user location. + // Passing NULL for exceptionReportPath or exceptionMinidumpPath causes those files to not be + // written. + // By default both the exceptionReportPath and exceptionMinidumpPath are NULL. + // Example usage: + // handler.SetExceptionPaths("/Users/Current/Exceptions/Exception %s.txt"); + void SetExceptionPaths( + const char* exceptionReportPath, + const char* exceptionMinidumpPath = nullptr); + + // Calls SetExceptionPaths in the appropriate convention for each operating system + // Windows: %AppData%\Organization\Application + // Mac: ~/Library/Logs/DiagnosticReports/Organization/Application" + // Linux: ~/Library/Organization/Application + // exceptionFormat and minidumpFormat define the file names in the format above + // with the %s specified as a date/time string. + void SetPathsFromNames( + const char* organizationName, + const char* ApplicationName, + const char* exceptionFormat = "Exception Report (%s).txt", + const char* minidumpFormat = "Exception Minidump (%s).mdmp"); + + // Allows you to specify base directories for code paths, which can be used to associate exception + // addresses to lines + // of code as opposed to just file names and line numbers, or function names plus binary offsets. + void SetCodeBaseDirectoryPaths( + const char* codeBaseDirectoryPathArray[], + size_t codeBaseDirectoryPathCount); + + // Writes lines into the current report. + void WriteReportLine(const char* pLine); + void WriteReportLineF(const char* format, ...); + + // Retrieves a directory path which ends with a path separator. + // Returns the required strlen of the path. + // Guarantees the presence of the directory upon returning true. + static size_t GetCrashDumpDirectory(char* directoryPath, size_t directoryPathCapacity); + + // Retrieves a directory path for a specific organization and application. + // Returns the required strlen of the path. + // Guarantees the presence of the directory upon returning true. + static void GetCrashDumpDirectoryFromNames( + char* path, + const char* organizationName, + const char* ApplicationName); + + // Given an exception report at a given file path, returns a string suitable for displaying in a + // message + // box or similar user interface during the handling of an exception. The returned string must be + // passed + // to FreeMessageBoxText when complete. + static const char* GetExceptionUIText(const char* exceptionReportPath); + static void FreeExceptionUIText(const char* messageBoxText); + + // Writes a deadlock report similar to an exception report. Since there is no allocation risk, an + // exception handler is created for this log. + static void ReportDeadlock( + const char* threadName, + const char* organizationName = nullptr, + const char* applicationName = nullptr); + + protected: + // Write one log line to log file, console, syslog, and debug output. + // If LogFile is null, it will not write to the log file. + // The buffer must be null-terminated. + void writeLogLine(const char* buffer, int length); + + void WriteExceptionDescription(); + void WriteReport(const char* reportType); + void WriteThreadCallstack( + ThreadHandle threadHandle, + ThreadSysId threadSysId, + const char* additionalInfo); + void WriteMiniDump(); + + protected: + // Runtime constants + bool enabled; + std::atomic pauseCount = {0}; // 0 means unpaused. 1+ means paused. + bool reportPrivacyEnabled; // Defaults to true. + ExceptionResponse exceptionResponse; // Defaults to kERHandle + ExceptionListener* exceptionListener; + uintptr_t exceptionListenerUserValue; + String appDescription; + String codeBasePathArray[6]; // 6 is arbitrary. + char reportFilePath[OVR_MAX_PATH]; // May be an encoded path, in that it has "%s" in it or is + // named "default". See reporFiletPathActual for the runtime + // actual report path. + MinidumpInfoLevel minidumpInfoLevel; + char miniDumpFilePath[OVR_MAX_PATH]; + FILE* LogFile; // Can/should we use OVR Files for this? + char scratchBuffer[4096]; + + // Runtime variables + bool exceptionOccurred; + std::atomic handlingBusy = {0}; + char reportFilePathActual[OVR_MAX_PATH]; + char minidumpFilePathActual[OVR_MAX_PATH]; + int terminateReturnValue; + ExceptionInfo exceptionInfo; + SymbolLookup symbolLookup; + +#if defined(OVR_OS_MS) + void* vectoredHandle; + LPTOP_LEVEL_EXCEPTION_FILTER previousFilter; + LPEXCEPTION_POINTERS pExceptionPointers; + + friend LONG WINAPI Win32ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers); + LONG ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers); + + // handles exception in a new thread, used for stack overflow + static unsigned WINAPI ExceptionHandlerThreadExec(void* callingHandler); +#endif +}; + +// Identifies basic exception types for the CreateException function. +enum CreateExceptionType { + kCETAccessViolation, // Read or write to inaccessable memory. + kCETAlignment, // Misaligned read or write. + kCETDivideByZero, // Integer divide by zero. + kCETFPU, // Floating point / VPU exception. + kCETIllegalInstruction, // Illegal opcode. + kCETStackCorruption, // Stack frame was corrupted. + kCETStackOverflow, // Stack ran out of space, often due to infinite recursion. + kCETTrap // System/OS trap (system call). +}; + +// Creates an exception of the given type, primarily for testing. +void CreateException(CreateExceptionType exceptionType); + +//----------------------------------------------------------------------------- +// GUI Exception Listener +// +// When this exception handler is called, it will verify that the application +// is not being debugged at that instant. If not, then it will present a GUI +// to the user containing error information. +// Initially the exception listener is not silenced. +class GUIExceptionListener : public ExceptionHandler::ExceptionListener { + public: + GUIExceptionListener(); + + virtual int HandleException( + uintptr_t userValue, + ExceptionHandler* pExceptionHandler, + ExceptionInfo* pExceptionInfo, + const char* reportFilePath) OVR_OVERRIDE; + + protected: + ExceptionHandler Handler; +}; + +} // namespace OVR + +OVR_RESTORE_MSVC_WARNING() + +#endif // OVR_DebugHelp_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Delegates.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Delegates.h new file mode 100644 index 0000000..7001c0f --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Delegates.h @@ -0,0 +1,468 @@ +/************************************************************************************ + +Filename : OVR_Delegates.h +Content : C++ Delegates +Created : June 15, 2014 +Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +/* + Based on The Impossibly Fast C++ Delegates by Sergey Ryazanov from + http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx (2005) +*/ + +/* + Usage: + + Declare a delegate with a void (int) signature, also known as a + function that returns void and has one parameter that is an int: + typedef Delegate1 MyDelegate; + MyDelegate d; + + Point the delegate to a member function: + d.SetMember(&a); + d = MyDelegate::FromMember(&a); + + Point the delegate to a const member function: + d.SetConstMember(&c); + d = MyDelegate::FromConstMember(&c); + + Point the delegate to a free function: + d.SetFree<&FreeFunctionX>(); + d = MyDelegate::FromFree<&FreeFunctionX>(); + + Invoke the function via the delegate (works for all 3 cases): + d(1000); + + By default the delegates are uninitialized. + To clear an array of delegates quickly just zero the memory. + + This implementation is nicer than FastDelegates in my opinion + because it is simple and easy to read. It is a little slower + for virtual functions, but the size of the delegate is small, + and it will only get better as compilers improve. +*/ + +#ifndef OVR_Delegates_h +#define OVR_Delegates_h + +#include "OVR_Types.h" + +namespace OVR { + +template +class Delegate0 { + typedef ret_type (*StubPointer)(void*); + typedef Delegate0 this_type; + + void* _object; + StubPointer _stub; + + inline Delegate0(void* object, StubPointer stub) { + _object = object; + _stub = stub; + } + + // Stubs + + template + static inline ret_type FreeStub(void* /*object*/) { + return (F)(); + } + + template + static inline ret_type MemberStub(void* object) { + T* p = static_cast(object); + return (p->*F)(); + } + + template + static inline ret_type ConstMemberStub(void* object) { + T* p = static_cast(object); + return (p->*F)(); + } + + public: + inline Delegate0() : _object(0), _stub(0) {} + + // Function invocation + + inline ret_type operator()() const { + return (*_stub)(_object); + } + + // Use stub pointer as a validity flag and equality checker + + inline bool operator==(const this_type& rhs) const { + return _object == rhs._object && _stub == rhs._stub; + } + + inline bool operator!=(const this_type& rhs) const { + return _object != rhs._object || _stub != rhs._stub; + } + + inline bool IsValid() const { + return _stub != 0; + } + + inline bool operator!() const { + return _stub == 0; + } + + inline void Invalidate() { + _stub = 0; + } + + // Delegate creation from a function + + template + static inline this_type FromFree() { + return this_type(0, &FreeStub); + } + + template + static inline this_type FromMember(T* object) { + return this_type(object, &MemberStub); + } + + template + static inline this_type FromConstMember(T const* object) { + return this_type(const_cast(object), &ConstMemberStub); + } + + // In-place assignment to a different function + + template + inline void SetFree() { + *this = FromFree(); + } + + template + inline void SetMember(T* object) { + *this = FromMember(object); + } + + template + inline void SetConstMember(T const* object) { + *this = FromConstMember(object); + } +}; + +template +class Delegate1 { + typedef ret_type (*StubPointer)(void*, arg1_type); + typedef Delegate1 this_type; + + void* _object; + StubPointer _stub; + + inline Delegate1(void* object, StubPointer stub) { + _object = object; + _stub = stub; + } + + // Stubs + + template + static inline ret_type FreeStub(void* /*object*/, arg1_type a1) { + return (F)(a1); + } + + template + static inline ret_type MemberStub(void* object, arg1_type a1) { + T* p = static_cast(object); + return (p->*F)(a1); + } + + template + static inline ret_type ConstMemberStub(void* object, arg1_type a1) { + T* p = static_cast(object); + return (p->*F)(a1); + } + + public: + inline Delegate1() : _object(0), _stub(0) {} + + // Function invocation + + inline ret_type operator()(arg1_type a1) const { + return (*_stub)(_object, a1); + } + + // Use stub pointer as a validity flag and equality checker + + inline bool operator==(const this_type& rhs) const { + return _object == rhs._object && _stub == rhs._stub; + } + + inline bool operator!=(const this_type& rhs) const { + return _object != rhs._object || _stub != rhs._stub; + } + + inline bool IsValid() const { + return _stub != 0; + } + + inline bool operator!() const { + return _stub == 0; + } + + inline void Invalidate() { + _stub = 0; + } + + // Delegate creation from a function + + template + static inline this_type FromFree() { + return this_type(0, &FreeStub); + } + + template + static inline this_type FromMember(T* object) { + return this_type(object, &MemberStub); + } + + template + static inline this_type FromConstMember(T const* object) { + return this_type(const_cast(object), &ConstMemberStub); + } + + // In-place assignment to a different function + + template + inline void SetFree() { + *this = FromFree(); + } + + template + inline void SetMember(T* object) { + *this = FromMember(object); + } + + template + inline void SetConstMember(T const* object) { + *this = FromConstMember(object); + } +}; + +template +class Delegate2 { + typedef ret_type (*StubPointer)(void*, arg1_type, arg2_type); + typedef Delegate2 this_type; + + void* _object; + StubPointer _stub; + + inline Delegate2(void* object, StubPointer stub) { + _object = object; + _stub = stub; + } + + // Stubs + + template + static inline ret_type FreeStub(void* /*object*/, arg1_type a1, arg2_type a2) { + return (F)(a1, a2); + } + + template + static inline ret_type MemberStub(void* object, arg1_type a1, arg2_type a2) { + T* p = static_cast(object); + return (p->*F)(a1, a2); + } + + template + static inline ret_type ConstMemberStub(void* object, arg1_type a1, arg2_type a2) { + T* p = static_cast(object); + return (p->*F)(a1, a2); + } + + public: + inline Delegate2() : _object(0), _stub(0) {} + + // Function invocation + + inline ret_type operator()(arg1_type a1, arg2_type a2) const { + return (*_stub)(_object, a1, a2); + } + + // Use stub pointer as a validity flag and equality checker + + inline bool operator==(const this_type& rhs) const { + return _object == rhs._object && _stub == rhs._stub; + } + + inline bool operator!=(const this_type& rhs) const { + return _object != rhs._object || _stub != rhs._stub; + } + + inline bool IsValid() const { + return _stub != 0; + } + + inline bool operator!() const { + return _stub == 0; + } + + inline void Invalidate() { + _stub = 0; + } + + // Delegate creation from a function + + template + static inline this_type FromFree() { + return this_type(0, &FreeStub); + } + + template + static inline this_type FromMember(T* object) { + return this_type(object, &MemberStub); + } + + template + static inline this_type FromConstMember(T const* object) { + return this_type(const_cast(object), &ConstMemberStub); + } + + // In-place assignment to a different function + + template + inline void SetFree() { + *this = FromFree(); + } + + template + inline void SetMember(T* object) { + *this = FromMember(object); + } + + template + inline void SetConstMember(T const* object) { + *this = FromConstMember(object); + } +}; + +template +class Delegate3 { + typedef ret_type (*StubPointer)(void*, arg1_type, arg2_type, arg3_type); + typedef Delegate3 this_type; + + void* _object; + StubPointer _stub; + + inline Delegate3(void* object, StubPointer stub) { + _object = object; + _stub = stub; + } + + // Stubs + + template + static inline ret_type FreeStub(void* /*object*/, arg1_type a1, arg2_type a2, arg3_type a3) { + return (F)(a1, a2, a3); + } + + template + static inline ret_type MemberStub(void* object, arg1_type a1, arg2_type a2, arg3_type a3) { + T* p = static_cast(object); + return (p->*F)(a1, a2, a3); + } + + template + static inline ret_type ConstMemberStub(void* object, arg1_type a1, arg2_type a2, arg3_type a3) { + T* p = static_cast(object); + return (p->*F)(a1, a2, a3); + } + + public: + inline Delegate3() : _object(0), _stub(0) {} + + // Function invocation + + inline ret_type operator()(arg1_type a1, arg2_type a2, arg3_type a3) const { + return (*_stub)(_object, a1, a2, a3); + } + + // Use stub pointer as a validity flag and equality checker + + inline bool operator==(const this_type& rhs) const { + return _object == rhs._object && _stub == rhs._stub; + } + + inline bool operator!=(const this_type& rhs) const { + return _object != rhs._object || _stub != rhs._stub; + } + + inline bool IsValid() const { + return _stub != 0; + } + + inline bool operator!() const { + return _stub == 0; + } + + inline void Invalidate() { + _stub = 0; + } + + // Delegate creation from a function + + template + static inline this_type FromFree() { + return this_type(0, &FreeStub); + } + + template + static inline this_type FromMember(T* object) { + return this_type(object, &MemberStub); + } + + template + static inline this_type FromConstMember(T const* object) { + return this_type(const_cast(object), &ConstMemberStub); + } + + // In-place assignment to a different function + + template + inline void SetFree() { + *this = FromFree(); + } + + template + inline void SetMember(T* object) { + *this = FromMember(object); + } + + template + inline void SetConstMember(T const* object) { + *this = FromConstMember(object); + } +}; + +// Add more here if needed, but keep in mind that a short, simple interface +// is rewarded by making the delegates faster... + +} // namespace OVR + +#endif // OVR_Delegates_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Deque.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Deque.h new file mode 100644 index 0000000..b83f7ed --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Deque.h @@ -0,0 +1,287 @@ +/************************************************************************************ + +Filename : OVR_Deque.h +Content : Deque container +Created : Nov. 15, 2013 +Authors : Dov Katz + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#pragma once + +#include "OVR_ContainerAllocator.h" + +namespace OVR { + +template > +class Deque { + public: + enum { DefaultCapacity = 500 }; + + Deque(int capacity = DefaultCapacity); + virtual ~Deque(void); + + virtual void PushBack(const Elem& Item); // Adds Item to the end + virtual void PushFront(const Elem& Item); // Adds Item to the beginning + virtual Elem PopBack(void); // Removes Item from the end + virtual Elem PopFront(void); // Removes Item from the beginning + virtual const Elem& PeekBack(int count = 0) const; // Returns count-th Item from the end + virtual const Elem& PeekFront(int count = 0) const; // Returns count-th Item from the beginning + + virtual inline size_t GetSize(void) const; // Returns Number of Elements + OVR_FORCE_INLINE int GetSizeI(void) const { + return (int)GetSize(); + } + virtual inline size_t GetCapacity(void) const; // Returns the maximum possible number of elements + virtual void Clear(void); // Remove all elements + virtual inline bool IsEmpty() const; + virtual inline bool IsFull() const; + + protected: + Elem* Data; // The actual Data array + const int Capacity; // Deque capacity + int Beginning; // Index of the first element + int End; // Index of the next after last element + + // Instead of calculating the number of elements, using this variable + // is much more convenient. + int ElemCount; + + private: + OVR_NON_COPYABLE(Deque); +}; + +template > +class InPlaceMutableDeque : public Deque { + typedef Deque BaseType; + + public: + InPlaceMutableDeque(int capacity = BaseType::DefaultCapacity) : BaseType(capacity) {} + virtual ~InPlaceMutableDeque(){}; + + using BaseType::PeekBack; + using BaseType::PeekFront; + virtual Elem& PeekBack(int count = 0); // Returns count-th Item from the end + virtual Elem& PeekFront(int count = 0); // Returns count-th Item from the beginning +}; + +// Same as Deque, but allows to write more elements than maximum capacity +// Old elements are lost as they are overwritten with the new ones +template > +class CircularBuffer : public InPlaceMutableDeque { + typedef InPlaceMutableDeque BaseType; + + public: + CircularBuffer(int MaxSize = BaseType::DefaultCapacity) : BaseType(MaxSize){}; + virtual ~CircularBuffer() {} + + // The following methods are inline as a workaround for a VS bug causing erroneous C4505 warnings + // See: http://stackoverflow.com/questions/3051992/compiler-warning-at-c-template-base-class + inline virtual void PushBack(const Elem& Item); // Adds Item to the end, overwriting the oldest + // element at the beginning if necessary + inline virtual void PushFront(const Elem& Item); // Adds Item to the beginning, overwriting the + // oldest element at the end if necessary +}; + +//---------------------------------------------------------------------------------- + +// Deque Constructor function +template +Deque::Deque(int capacity) + : Capacity(capacity), Beginning(0), End(0), ElemCount(0) { + Data = (Elem*)Allocator::Alloc(Capacity * sizeof(Elem)); +} + +// Deque Destructor function +template +Deque::~Deque(void) { + Clear(); + Allocator::Free(Data); +} + +template +void Deque::Clear() { + if (!IsEmpty()) { + if (Beginning < End) { + // no wrap-around + Allocator::DestructArray(Data + Beginning, End - Beginning); + } else { + // wrap-around + Allocator::DestructArray(Data + Beginning, Capacity - Beginning); + Allocator::DestructArray(Data, End); + } + } + + Beginning = 0; + End = 0; + ElemCount = 0; +} + +// Push functions +template +void Deque::PushBack(const Elem& Item) { + // Error Check: Make sure we aren't + // exceeding our maximum storage space + OVR_ASSERT(ElemCount < Capacity); + + Allocator::Construct(Data + End, Item); + ++End; + ++ElemCount; + + // Check for wrap-around + if (End >= Capacity) + End -= Capacity; +} + +template +void Deque::PushFront(const Elem& Item) { + // Error Check: Make sure we aren't + // exceeding our maximum storage space + OVR_ASSERT(ElemCount < Capacity); + + --Beginning; + // Check for wrap-around + if (Beginning < 0) + Beginning += Capacity; + + Allocator::Construct(Data + Beginning, Item); + ++ElemCount; +} + +// Pop functions +template +Elem Deque::PopFront(void) { + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT(ElemCount > 0); + + Elem ReturnValue = Data[Beginning]; + Allocator::Destruct(Data + Beginning); + + ++Beginning; + --ElemCount; + + // Check for wrap-around + if (Beginning >= Capacity) + Beginning -= Capacity; + + return ReturnValue; +} + +template +Elem Deque::PopBack(void) { + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT(ElemCount > 0); + + --End; + --ElemCount; + + // Check for wrap-around + if (End < 0) + End += Capacity; + + Elem ReturnValue = Data[End]; + Allocator::Destruct(Data + End); + + return ReturnValue; +} + +// Peek functions +template +const Elem& Deque::PeekFront(int count) const { + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT(ElemCount > count); + + int idx = Beginning + count; + if (idx >= Capacity) + idx -= Capacity; + return Data[idx]; +} + +template +const Elem& Deque::PeekBack(int count) const { + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT(ElemCount > count); + + int idx = End - count - 1; + if (idx < 0) + idx += Capacity; + return Data[idx]; +} + +// Mutable Peek functions +template +Elem& InPlaceMutableDeque::PeekFront(int count) { + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT(BaseType::ElemCount > count); + + int idx = BaseType::Beginning + count; + if (idx >= BaseType::Capacity) + idx -= BaseType::Capacity; + return BaseType::Data[idx]; +} + +template +Elem& InPlaceMutableDeque::PeekBack(int count) { + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT(BaseType::ElemCount > count); + + int idx = BaseType::End - count - 1; + if (idx < 0) + idx += BaseType::Capacity; + return BaseType::Data[idx]; +} + +template +inline size_t Deque::GetCapacity(void) const { + return Capacity; +} + +template +inline size_t Deque::GetSize(void) const { + return ElemCount; +} + +template +inline bool Deque::IsEmpty(void) const { + return ElemCount == 0; +} + +template +inline bool Deque::IsFull(void) const { + return ElemCount == Capacity; +} + +// ******* CircularBuffer ******* +// Push functions +template +void CircularBuffer::PushBack(const Elem& Item) { + if (this->IsFull()) + this->PopFront(); + BaseType::PushBack(Item); +} + +template +void CircularBuffer::PushFront(const Elem& Item) { + if (this->IsFull()) + this->PopBack(); + BaseType::PushFront(Item); +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Error.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Error.cpp new file mode 100644 index 0000000..6030077 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Error.cpp @@ -0,0 +1,886 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_Error.cpp +Content : Structs and functions for handling OVRErrorInfos +Created : February 15, 2015 +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Error.h" +#include "Logging/Logging_Library.h" +#include "OVR_Atomic.h" +#include "OVR_DebugHelp.h" +#include "OVR_Std.h" +#include "OVR_String.h" +#include "OVR_Threads.h" +#include "OVR_Timer.h" +#include "OVR_Types.h" +#include "OVR_UTF8Util.h" +#include "OVR_Win32_IncludeWindows.h" + +OVR_DISABLE_ALL_MSVC_WARNINGS() +OVR_DISABLE_MSVC_WARNING(4265) +#if defined(OVR_OS_WIN32) +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +OVR_RESTORE_MSVC_WARNING() +OVR_RESTORE_ALL_MSVC_WARNINGS() + +OVR_DEFINE_SINGLETON(OVR::LastErrorTLS); + +OVR_DISABLE_MSVC_WARNING(4996) // 'localtime': This function or variable may be unsafe. + +static ovrlog::Channel Logger("Kernel:Error"); + +// ----------------------------------------------------------------------------- +// ***** OVR_ERROR_ENABLE_BACKTRACES +// +// If defined then we record backtraces in Errors. +// +#if !defined(OVR_ERROR_ENABLE_BACKTRACES) +#if defined(OVR_BUILD_DEBUG) +#define OVR_ERROR_ENABLE_BACKTRACES 1 +#endif +#endif + +namespace OVR { + +//----------------------------------------------------------------------------- +// LastErrorTLS + +static SymbolLookup Symbols; + +LastErrorTLS::LastErrorTLS() { + Symbols.Initialize(); + + // Must be at end of function + PushDestroyCallbacks(); +} + +LastErrorTLS::~LastErrorTLS() { + Symbols.Shutdown(); +} + +void LastErrorTLS::OnSystemDestroy() { + delete this; +} + +// This is an accessor which auto-allocates and initializes the return value if needed. +OVRError& LastErrorTLS::LastError() { + Lock::Locker autoLock(&TheLock); + + ThreadId threadId = GetCurrentThreadId(); + auto i = TLSDictionary.Find(threadId); + + if (i == TLSDictionary.End()) { + TLSDictionary.Add(threadId, OVRError::Success()); + i = TLSDictionary.Find(threadId); + } + + return (*i).Second; +} + +// ****** OVRFormatDateTime +// +// Prints a date/time like so: +// Y-M-d H:M:S [ms:us:ns] +// Example output: +// 2016-12-25 8:15:01 [392:445:23] +// +// SysClockTime is of type std::chrono::time_point. +// +// To consider: Move SysClockTime and OVRFormatDateTime to OVRKernel. +// +static void OVRFormatDateTime(SysClockTime sysClockTime, OVR::String& dateTimeString) { + // Get the basic Date and HMS time. + char buffer[128]; + struct tm tmResult; + const time_t cTime = std::chrono::system_clock::to_time_t(sysClockTime); + +#if defined(_MSC_VER) + localtime_s(&tmResult, &cTime); +#else + localtime_r(&cTime, &tmResult); +#endif + + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tmResult); + + // Append milli:micro:nano time. + std::chrono::system_clock::duration timeSinceEpoch = sysClockTime.time_since_epoch(); + + std::chrono::seconds s = std::chrono::duration_cast(timeSinceEpoch); + timeSinceEpoch -= s; + + std::chrono::milliseconds ms = + std::chrono::duration_cast(timeSinceEpoch); + timeSinceEpoch -= ms; + + std::chrono::microseconds us = + std::chrono::duration_cast(timeSinceEpoch); + timeSinceEpoch -= us; + + std::chrono::nanoseconds ns = + std::chrono::duration_cast(timeSinceEpoch); + + char buffer2[384]; + sprintf(buffer2, "%s [%d:%d:%d]", buffer, (int)ms.count(), (int)us.count(), (int)ns.count()); + + dateTimeString = buffer2; +} + +static void OVRRemoveTrailingNewlines(String& s) { + while (!s.IsEmpty() && ((s.Back() == '\n') || (s.Back() == '\r'))) + s.PopBack(); +} + +OVR_SELECTANY const int64_t OVRError::kLogLineUnset; + +OVRError::OVRError() { + Reset(); +} + +OVRError::OVRError(ovrResult code) : OVRError() { + Code = code; +} + +OVRError::OVRError(ovrResult code, const char* pFormat, ...) : OVRError(code) { + va_list argList; + va_start(argList, pFormat); + StringBuffer strbuff; + strbuff.AppendFormatV(pFormat, argList); + SetDescription(strbuff.ToCStr()); + va_end(argList); +} + +OVRError::OVRError(const OVRError& ovrError) { + operator=(ovrError); +} + +OVRError::OVRError(OVRError&& ovrError) { + operator=(std::move(ovrError)); +} + +OVRError::~OVRError() { + // Empty +} + +OVRError& OVRError::operator=(const OVRError& ovrError) { + ErrorString = ovrError.ErrorString; + Code = ovrError.Code; + SysCodeType = ovrError.SysCodeType; + SysCode = ovrError.SysCode; + strcpy(SysCodeStr, ovrError.SysCodeStr); + Description = ovrError.Description; + Context = ovrError.Context; + OVRTime = ovrError.OVRTime; + ClockTime = ovrError.ClockTime; + LogLine = ovrError.LogLine; + SourceFilePath = ovrError.SourceFilePath; + SourceFileLine = ovrError.SourceFileLine; + Backtrace = ovrError.Backtrace; + AlreadyLogged = ovrError.AlreadyLogged; + + return *this; +} + +OVRError& OVRError::operator=(OVRError&& ovrError) { + ErrorString = ovrError.ErrorString; + Code = ovrError.Code; + SysCodeType = ovrError.SysCodeType; + SysCode = ovrError.SysCode; + strcpy(SysCodeStr, ovrError.SysCodeStr); + Description = std::move(ovrError.Description); + Context = std::move(ovrError.Context); + OVRTime = ovrError.OVRTime; + ClockTime = ovrError.ClockTime; + LogLine = ovrError.LogLine; + SourceFilePath = std::move(ovrError.SourceFilePath); + SourceFileLine = ovrError.SourceFileLine; + Backtrace = std::move(ovrError.Backtrace); + AlreadyLogged = ovrError.AlreadyLogged; + + return *this; +} + +void OVRError::SetCurrentValues() { + OVRTime = Timer::GetSeconds(); // It would be better if we called ovr_GetTimeInSeconds, but that + // doesn't have a constant header to use. + + ClockTime = std::chrono::system_clock::now(); + +#if defined(OVR_ERROR_ENABLE_BACKTRACES) + if (Symbols.IsInitialized()) { + void* addressArray[32]; + size_t n = Symbols.GetBacktrace( + addressArray, OVR_ARRAY_COUNT(addressArray), 2, nullptr, OVR_THREADSYSID_INVALID); + Backtrace.Clear(); + Backtrace.Append(addressArray, n); + } +#endif +} + +void OVRError::Reset() { + ErrorString.Clear(); + Code = ovrSuccess; + SysCodeType = ovrSysErrorCodeType::None; + SysCode = ovrSysErrorCodeSuccess; + SysCodeStr[0] = '\0'; + Description.Clear(); + Context.Clear(); + OVRTime = 0; + ClockTime = SysClockTime(); + LogLine = kLogLineUnset; + SourceFilePath.Clear(); + SourceFileLine = 0; + Backtrace.ClearAndRelease(); + AlreadyLogged = false; +} + +String OVRError::GetErrorString() const { + if (ErrorString.GetSize() == 0) { // If not already cached... + ErrorString.AppendString("OVR Error:\n"); + + // Code + OVR::String errorCodeString; + GetErrorCodeString(Code, false, errorCodeString); + ErrorString.AppendFormat(" Code: %d -- %s\n", Code, errorCodeString.ToCStr()); + + // SysCode + if (SysCode != ovrSysErrorCodeSuccess) { + if (SysCodeStr[0]) { // If the sys error was previously set to a custom value... + ErrorString.AppendFormat( + " System error: %d (%x) -- %s\n", (int)SysCode, (int)SysCode, SysCodeStr); + } else { // Else just build it with the system error code. + OVR::String sysErrorString; + GetSysErrorCodeString(SysCodeType, SysCode, false, sysErrorString); + OVRRemoveTrailingNewlines(sysErrorString); + ErrorString.AppendFormat( + " System error: %d (%x) -- %s\n", (int)SysCode, (int)SysCode, sysErrorString.ToCStr()); + } + } + + // Description + if (Description.GetLength()) { + ErrorString.AppendFormat(" Description: %s\n", Description.ToCStr()); + } + + // OVRTime + ErrorString.AppendFormat(" OVRTime: %f\n", OVRTime); + + // SysClockTime + OVR::String sysClockTimeString; + OVRFormatDateTime(ClockTime, sysClockTimeString); + ErrorString.AppendFormat(" Time: %s\n", sysClockTimeString.ToCStr()); + + // Context + if (Context.GetLength()) + ErrorString.AppendFormat(" Context: %s\n", Context.ToCStr()); + + // If LogLine is set, + if (LogLine != kLogLineUnset) + ErrorString.AppendFormat(" LogLine: %lld\n", LogLine); + + // FILE/LINE + if (SourceFilePath.GetLength()) + ErrorString.AppendFormat(" File/Line: %s:%d\n", SourceFilePath.ToCStr(), SourceFileLine); + + // Backtrace + if (Backtrace.GetSize()) { + // We can trace symbols in a debug build here or we can trace just addresses. See other code + // for examples of how to trace symbols. + ErrorString.AppendFormat(" Backtrace: "); + for (size_t i = 0, iEnd = Backtrace.GetSize(); i != iEnd; ++i) + ErrorString.AppendFormat(" %p", Backtrace[i]); + ErrorString.AppendChar('\n'); + } + } + + return OVR::String(ErrorString.ToCStr(), ErrorString.GetSize()); +} + +void OVRError::SetCode(ovrResult code) { + Code = code; +} + +ovrResult OVRError::GetCode() const { + return Code; +} + +void OVRError::SetSysCode( + ovrSysErrorCodeType sysCodeType, + ovrSysErrorCode sysCode, + const char* sysCodeString) { + SysCodeType = sysCodeType; + SysCode = sysCode; + if (sysCodeString) + OVR_strlcpy(SysCodeStr, sysCodeString, sizeof(SysCodeStr)); +} + +ovrSysErrorCodeType OVRError::GetSysCodeType() const { + return SysCodeType; +} + +ovrSysErrorCode OVRError::GetSysCode() const { + return SysCode; +} + +void OVRError::SetDescription(const char* pDescription) { + if (pDescription) { + Description = pDescription; + OVRRemoveTrailingNewlines(Description); // Users sometimes send text with trailing newlines, + // which have no purpose in the error report. + } else + Description.Clear(); +} + +String OVRError::GetDescription() const { + return Description; +} + +void OVRError::SetContext(const char* pContext) { + if (pContext) { + Context = pContext; + OVRRemoveTrailingNewlines(Context); + } else + Context.Clear(); +} + +String OVRError::GetContext() const { + return Context; +} + +void OVRError::SetOVRTime(double ovrTime) { + OVRTime = ovrTime; +} + +double OVRError::GetOVRTime() const { + return OVRTime; +} + +void OVRError::SetSysClockTime(const SysClockTime& clockTime) { + ClockTime = clockTime; +} + +SysClockTime OVRError::GetSysClockTime() const { + return ClockTime; +} + +void OVRError::SetLogLine(int64_t logLine) { + LogLine = logLine; +} + +int64_t OVRError::GetLogLine() const { + return LogLine; +} + +void OVRError::SetSource(const char* pSourceFilePath, int sourceFileLine) { + if (pSourceFilePath) + SourceFilePath = pSourceFilePath; + else + SourceFilePath.Clear(); + SourceFileLine = sourceFileLine; +} + +std::pair OVRError::GetSource() const { + return std::make_pair(SourceFilePath, SourceFileLine); +} + +OVRError::AddressArray OVRError::GetBacktrace() const { + return Backtrace; +} + +void LogError(OVRError& ovrError) { + // If not already logged, + if (!ovrError.IsAlreadyLogged()) { + Logger.LogError(ovrError.GetErrorString()); + + ovrError.SetAlreadyLogged(); + } +} + +void SetError(OVRError& ovrError) { + // Record that the current thread's last error is this error. If we wanted to support + // chaining of errors such that multiple OVRErrors could be concurrent in a thread + // (e.g. one that occurred deep in the call chain and a higher level version of it higher + // in the call chain), we could handle that here. + LastErrorTLS::GetInstance()->LastError() = ovrError; +} + +static OVRErrorCallback ErrorCallback; + +void SetErrorCallback(OVRErrorCallback callback) { + ErrorCallback = callback; +} + +OVRError MakeError( + ovrResult errorCode, + ovrSysErrorCodeType sysCodeType, + ovrSysErrorCode sysCode, + const char* sysCodeString, // Optional pre-generated sys error code string. + const char* pSourceFile, + int sourceLine, + bool logError, + bool assertError, + const char* pContext, + const char* pDescriptionFormat, + ...) { + OVRError ovrError(errorCode); + + ovrError.SetCurrentValues(); // Sets the current time, etc. + + ovrError.SetSysCode(sysCodeType, sysCode, sysCodeString); + + va_list argList; + va_start(argList, pDescriptionFormat); + StringBuffer strbuff; + strbuff.AppendFormatV(pDescriptionFormat, argList); + va_end(argList); + ovrError.SetDescription(strbuff.ToCStr()); + + ovrError.SetContext(pContext); + + ovrError.SetSource(pSourceFile, sourceLine); + + // Set the TLS last error. + LastErrorTLS::GetInstance()->LastError() = ovrError; + + int silencerOptions = ovrlog::ErrorSilencer::GetSilenceOptions(); + + if (silencerOptions & ovrlog::ErrorSilencer::CompletelySilenceLogs) + logError = false; + + if (silencerOptions & ovrlog::ErrorSilencer::PreventErrorAsserts) + assertError = false; + + if (logError) + Logger.LogError(ovrError.GetErrorString().ToCStr()); + + if (assertError) { + // Assert in debug mode to alert unit tester/developer of the error as it occurs. + OVR_FAIL_M(ovrError.GetErrorString().ToCStr()); + } + + // ErrorCallback should be called after LastErrorTLS is set. + // ErrorCallback could choose to save LastErrorTLS if desired. + if (ErrorCallback) { + const bool quiet = !logError && !assertError; + ErrorCallback(ovrError, quiet); + } + + return ovrError; +} + +typedef std::unordered_map ResultNameMap; + +static ResultNameMap& GetResultNameMap() { + static ResultNameMap resultNameMap; + return resultNameMap; +} + +const char* GetErrorCodeName(ovrResult errorCode) { + if (errorCode == ovrSuccess) { + return "ovrSuccess"; // Speed up a common case + } + + const ResultNameMap& resultNameMap = GetResultNameMap(); + ResultNameMap::const_iterator it = resultNameMap.find(errorCode); + + if (it == resultNameMap.end()) { + OVR_FAIL_M("Unknown result code. It should have been registered"); + return "UnknownResultCode"; + } + + return it->second; +} + +void OVRError::RegisterResultCodeName(ovrResult number, const char* name) { + ResultNameMap& resultNameMap = GetResultNameMap(); + if (resultNameMap.find(number) != resultNameMap.end()) { + OVR_FAIL_M("Duplicate result code registered"); + return; + } + resultNameMap[number] = name; +} + +bool GetErrorCodeString(ovrResult resultIn, bool prefixErrorCode, OVR::String& sResult) { + char codeBuffer[256]; + + const char* errorCodeName = GetErrorCodeName(resultIn); + + if (prefixErrorCode) { + snprintf( + codeBuffer, + OVR_ARRAY_COUNT(codeBuffer), + "0x%llx (%lld) %s", + (unsigned long long)resultIn, + (long long)resultIn, + errorCodeName); + } else { + snprintf(codeBuffer, OVR_ARRAY_COUNT(codeBuffer), "%s", errorCodeName); + } + + sResult = codeBuffer; + + return true; +} + +#if defined(OVR_OS_WIN32) +static const wchar_t* OVR_DXGetErrorStringW(HRESULT dwDXGIErrorCode) { + switch (dwDXGIErrorCode) { + case DXGI_ERROR_DEVICE_HUNG: + return L"DXGI_ERROR_DEVICE_HUNG"; // The application's device failed due to badly formed + // commands sent by the application. This is an design-time + // issue that should be investigated and fixed. + case DXGI_ERROR_DEVICE_REMOVED: + return L"DXGI_ERROR_DEVICE_REMOVED"; // The video card has been physically removed from the + // system, or a driver upgrade for the video card has + // occurred. The application should destroy and recreate + // the device. For help debugging the problem, call + // ID3D10Device::GetDeviceRemovedReason. + case DXGI_ERROR_DEVICE_RESET: + return L"DXGI_ERROR_DEVICE_RESET"; // The device failed due to a badly formed command. This is + // a run-time issue; The application should destroy and + // recreate the device. + case DXGI_ERROR_DRIVER_INTERNAL_ERROR: + return L"DXGI_ERROR_DRIVER_INTERNAL_ERROR"; // The driver encountered a problem and was put + // into the device removed state. + case DXGI_ERROR_FRAME_STATISTICS_DISJOINT: + return L"DXGI_ERROR_FRAME_STATISTICS_DISJOINT"; // An event (for example, a power cycle) + // interrupted the gathering of presentation + // statistics. + case DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE: + return L"DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE"; // The application attempted to acquire + // exclusive ownership of an output, but + // failed because some other application + // (or device within the application) + // already acquired ownership. + case DXGI_ERROR_INVALID_CALL: + return L"DXGI_ERROR_INVALID_CALL"; // The application provided invalid parameter data; this + // must be debugged and fixed before the application is + // released. + case DXGI_ERROR_MORE_DATA: + return L"DXGI_ERROR_MORE_DATA"; // The buffer supplied by the application is not big enough to + // hold the requested data. + case DXGI_ERROR_NONEXCLUSIVE: + return L"DXGI_ERROR_NONEXCLUSIVE"; // A global counter resource is in use, and the Direct3D + // device can't currently use the counter resource. + case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: + return L"DXGI_ERROR_NOT_CURRENTLY_AVAILABLE"; // The resource or request is not currently + // available, but it might become available + // later. + case DXGI_ERROR_NOT_FOUND: + return L"DXGI_ERROR_NOT_FOUND"; // When calling IDXGIObject::GetPrivateData, the GUID passed + // in is not recognized as one previously passed to + // IDXGIObject::SetPrivateData or + // IDXGIObject::SetPrivateDataInterface. When calling + // IDXGIFactory::EnumAdapters or IDXGIAdapter::EnumOutputs, + // the enumerated ordinal is out of range. + case DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED: + return L"DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED"; // Reserved + case DXGI_ERROR_REMOTE_OUTOFMEMORY: + return L"DXGI_ERROR_REMOTE_OUTOFMEMORY"; // Reserved + case DXGI_ERROR_WAS_STILL_DRAWING: + return L"DXGI_ERROR_WAS_STILL_DRAWING"; // The GPU was busy at the moment when a call was made + // to perform an operation, and did not execute or + // schedule the operation. + case DXGI_ERROR_UNSUPPORTED: + return L"DXGI_ERROR_UNSUPPORTED"; // The requested functionality is not supported by the + // device or the driver. + case DXGI_ERROR_ACCESS_LOST: + return L"DXGI_ERROR_ACCESS_LOST"; // The desktop duplication interface is invalid. The desktop + // duplication interface typically becomes invalid when a + // different type of image is displayed on the desktop. + case DXGI_ERROR_WAIT_TIMEOUT: + return L"DXGI_ERROR_WAIT_TIMEOUT"; // The time-out interval elapsed before the next desktop + // frame was available. + case DXGI_ERROR_SESSION_DISCONNECTED: + return L"DXGI_ERROR_SESSION_DISCONNECTED"; // The Remote Desktop Services session is currently + // disconnected. + case DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE: + return L"DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE"; // The DXGI output (monitor) to which the swap + // chain content was restricted is now + // disconnected or changed. + case DXGI_ERROR_CANNOT_PROTECT_CONTENT: + return L"DXGI_ERROR_CANNOT_PROTECT_CONTENT"; // DXGI can't provide content protection on the + // swap chain. This error is typically caused by + // an older driver, or when you use a swap chain + // that is incompatible with content protection. + case DXGI_ERROR_ACCESS_DENIED: + return L"DXGI_ERROR_ACCESS_DENIED"; // You tried to use a resource to which you did not have + // the required access privileges. This error is most + // typically caused when you write to a shared resource + // with read-only access. + case DXGI_ERROR_NAME_ALREADY_EXISTS: + return L"DXGI_ERROR_NAME_ALREADY_EXISTS"; // The supplied name of a resource in a call to + // IDXGIResource1::CreateSharedHandle is already + // associated with some other resource. + case DXGI_ERROR_SDK_COMPONENT_MISSING: + return L"DXGI_ERROR_SDK_COMPONENT_MISSING"; // The operation depends on an SDK component that + // is missing or mismatched. + } + + return nullptr; +} +#endif + +bool GetSysErrorCodeString( + ovrSysErrorCodeType sysErrorCodeType, + ovrSysErrorCode sysErrorCode, + bool prefixErrorCode, + OVR::String& sResult) { + char errorBuffer[1024]; + errorBuffer[0] = '\0'; + + if (prefixErrorCode) { + char prefixBuffer[64]; + snprintf( + prefixBuffer, + OVR_ARRAY_COUNT(prefixBuffer), + "0x%llx (%lld): ", + (unsigned long long)sysErrorCode, + (long long)sysErrorCode); + sResult = prefixBuffer; + } else { + sResult.Clear(); + } + + if (sysErrorCodeType == ovrSysErrorCodeType::Vulkan) { + // We have a problem here in that we can't #include because this source is + // distributed as part of a public SDK, and we don't want to create that dependency. + // However, vulkan.h errors are stable, so we can repeat them here. + char buffer[32]; + OVR_itoa(sysErrorCode, buffer, sizeof(buffer), 10); + const char* vkResultStr = buffer; // Default to the numerical value. + + switch (static_cast(sysErrorCode)) { + case 0: + vkResultStr = "VK_SUCESS"; + break; + case 1: + vkResultStr = "VK_NOT_READY"; + break; + case 2: + vkResultStr = "VK_TIMEOUT"; + break; + case 3: + vkResultStr = "VK_EVENT_SET"; + break; + case 4: + vkResultStr = "VK_EVENT_RESET"; + break; + case 5: + vkResultStr = "VK_INCOMPLETE"; + break; + case -1: + vkResultStr = "VK_ERROR_OUT_OF_HOST_MEMORY"; + break; + case -2: + vkResultStr = "VK_ERROR_OUT_OF_DEVICE_MEMORY"; + break; + case -3: + vkResultStr = "VK_ERROR_INITIALIZATION_FAILED"; + break; + case -4: + vkResultStr = "VK_ERROR_DEVICE_LOST"; + break; + case -5: + vkResultStr = "VK_ERROR_MEMORY_MAP_FAILED"; + break; + case -6: + vkResultStr = "VK_ERROR_LAYER_NOT_PRESENT"; + break; + case -7: + vkResultStr = "VK_ERROR_EXTENSION_NOT_PRESENT"; + break; + case -8: + vkResultStr = "VK_ERROR_FEATURE_NOT_PRESENT"; + break; + case -9: + vkResultStr = "VK_ERROR_INCOMPATIBLE_DRIVER"; + break; + case -10: + vkResultStr = "VK_ERROR_TOO_MANY_OBJECTS"; + break; + case -11: + vkResultStr = "VK_ERROR_FORMAT_NOT_SUPPORTED"; + break; + case -12: + vkResultStr = "VK_ERROR_FRAGMENTED_POOL"; + break; + case -1000000000: + vkResultStr = "VK_ERROR_SURFACE_LOST_KHR"; + break; + case -1000000001: + vkResultStr = "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; + break; + case 1000001003: + vkResultStr = "VK_SUBOPTIMAL_KHR"; + break; + case -1000001004: + vkResultStr = "VK_ERROR_OUT_OF_DATE_KHR"; + break; + case -1000003001: + vkResultStr = "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; + break; + case -1000011001: + vkResultStr = "VK_ERROR_VALIDATION_FAILED_EXT"; + break; + case -1000012000: + vkResultStr = "VK_ERROR_INVALID_SHADER_NV"; + break; + case -1000069000: + vkResultStr = "VK_ERROR_OUT_OF_POOL_MEMORY_KHR"; + break; + case -1000072003: + vkResultStr = "VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR"; + break; + case -1000174001: + vkResultStr = "VK_ERROR_NOT_PERMITTED_EXT"; + break; + default: + // Use the numerical default above. + break; + } + + OVR::OVR_strlcat(errorBuffer, vkResultStr, sizeof(errorBuffer)); + } else if (sysErrorCodeType == ovrSysErrorCodeType::OpenGL) { + char buffer[32]; + OVR_itoa(sysErrorCode, buffer, sizeof(buffer), 10); + const char* glResultStr = buffer; // Default to the numerical value. + + switch (sysErrorCode) { + case 0: + glResultStr = "GL_NO_ERROR"; + break; + case 0x0500: + glResultStr = "GL_INVALID_ENUM"; + break; + case 0x0501: + glResultStr = "GL_INVALID_VALUE"; + break; + case 0x0502: + glResultStr = "GL_INVALID_OPERATION"; + break; + case 0x0503: + glResultStr = "GL_STACK_OVERFLOW"; + break; + case 0x0504: + glResultStr = "GL_STACK_UNDERFLOW"; + break; + case 0x0505: + glResultStr = "GL_OUT_OF_MEMORY"; + break; + default: + // Use the numerical default above. + break; + } + + OVR::OVR_strlcat(errorBuffer, glResultStr, sizeof(errorBuffer)); + } else if (sysErrorCodeType == ovrSysErrorCodeType::OS) { +#if defined(OVR_OS_WIN32) + // Note: It may be useful to use FORMAT_MESSAGE_FROM_HMODULE here to get a module-specific error + // string if our source of errors ends up including more than just system-native errors. For + // example, a third party module with custom errors defined in it. + + WCHAR errorBufferW[1024]; + DWORD errorBufferWCapacity = OVR_ARRAY_COUNT(errorBufferW); + DWORD length = FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + (DWORD)sysErrorCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + errorBufferW, + errorBufferWCapacity, + nullptr); + + if (!length) // If failed... + { + if (HRESULT_FACILITY(sysErrorCode) == _FACDXGI) // If it is a DXGI error... + { + // This situation occurs on Windows 7. You can't use FORMAT_MESSAGE_FROM_HMODULE to solve it + // either. We can only use DXGetErrorString or manually handle it. + const wchar_t* pStr = OVR_DXGetErrorStringW(sysErrorCode); + + if (pStr) { + wcscpy_s(errorBufferW, OVR_ARRAY_COUNT(errorBufferW), pStr); + length = (DWORD)wcslen(errorBufferW); + } + } + } + + if (length) // If errorBufferW contains what we are looking for... + { + // Need to convert WCHAR errorBuffer to UTF8 char sResult; + const auto requiredUTF8Length = + OVR::UTF8Util::Strlcpy(errorBuffer, OVR_ARRAY_COUNT(errorBuffer), errorBufferW); + if (requiredUTF8Length >= + OVR_ARRAY_COUNT(errorBuffer)) // Zero out if too big (XXX truncate instead?) + errorBuffer[0] = '\0'; + // Else fall through + } // Else fall through +#else +#if ( \ + ((defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) || \ + (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && \ + !_GNU_SOURCE) || \ + defined(__APPLE__) || defined(__BSD__) + const int result = strerror_r((int)sysErrorCode, errorBuffer, OVR_ARRAY_COUNT(errorBuffer)); + + if (result != 0) // If failed... [result is 0 upon success; result will be EINVAL if the code is + // not recognized; ERANGE if buffer didn't have enough capacity.] + errorBuffer[0] = '\0'; // re-null-terminate, in case strerror_r left it in an invalid state. +#else + const char* result = strerror_r((int)sysErrorCode, errorBuffer, OVR_ARRAY_COUNT(errorBuffer)); + + if (result == + nullptr) // Implementations in practice seem to always return a pointer, though the + // behavior isn't formally standardized. + errorBuffer[0] = '\0'; // re-null-terminate, in case strerror_r left it in an invalid state. +#endif +#endif + } + + // Fall through functionality of simply printing the value as an integer. + if (errorBuffer[0]) // If errorBuffer was successfully written above... + { + sResult += errorBuffer; + return true; + } + + sResult += "(unknown)"; // This is not localized. Question: Is there a way to get the error + // formatting functions above to print this themselves in a localized way? + return false; +} + +} // namespace OVR + +template <> +void ovrlog::LogStringize(LogStringBuffer& buffer, const OVR::OVRError& error) { + buffer.Stream << error.GetErrorString().ToCStr(); +} diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Error.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Error.h new file mode 100644 index 0000000..a9d91f1 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Error.h @@ -0,0 +1,795 @@ +/************************************************************************************ + +Filename : OVR_Error.h +Content : Structs and functions for handling OVRErrors +Created : February 15, 2015 +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_Hash.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Threads.h" + +OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized + +#ifndef OVR_RESULT_DEFINED +#define OVR_RESULT_DEFINED ///< Allows ovrResult to be independently defined. +/// API call results are represented at the highest level by a single ovrResult. +typedef int32_t ovrResult; +#endif + +/// \brief Indicates if an ovrResult indicates success. +/// +/// Some functions return additional successful values other than ovrSucces and +/// require usage of this macro to indicate successs. +/// +#if !defined(OVR_SUCCESS) +#define OVR_SUCCESS(result) (result >= 0) +#endif + +/// \brief Indicates if an ovrResult indicates an unqualified success. +/// +/// This is useful for indicating that the code intentionally wants to +/// check for result == ovrSuccess as opposed to OVR_SUCCESS(), which +/// checks for result >= ovrSuccess. +/// +#if !defined(OVR_UNQUALIFIED_SUCCESS) +#define OVR_UNQUALIFIED_SUCCESS(result) (result == ovrSuccess) +#endif + +/// \brief Indicates if an ovrResult indicates failure. +/// +#if !defined(OVR_FAILURE) +#define OVR_FAILURE(result) (!OVR_SUCCESS(result)) +#endif + +// Success is a value greater or equal to 0, while all error types are negative values. +#ifndef OVR_SUCCESS_DEFINED +#define OVR_SUCCESS_DEFINED ///< Allows ovrResult to be independently defined. +typedef enum ovrSuccessType_ { + /// This is a general success result. Use OVR_SUCCESS to test for success. + ovrSuccess = 0, +} ovrSuccessType; +#endif + +/// ----------------------------------------------------------------------------- +/// ***** OVR_FILE / OVR_LINE +/// +#if !defined(OVR_FILE) +#if defined(OVR_BUILD_DEBUG) +#define OVR_FILE __FILE__ +#define OVR_LINE __LINE__ +#else +#define OVR_FILE nullptr +#define OVR_LINE 0 +#endif +#endif + +// LOG_VAARG_ATTRIBUTE macro, enforces printf-style formatting 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 + +namespace OVR { + +/// ----------------------------------------------------------------------------- +/// ***** OVR_MAKE_ERROR, OVR_MAKE_ERROR_F, OVR_MAKE_SYS_ERROR, OVR_MAKE_SYS_ERROR_F +/// +/// Declaration: +/// OVRError OVR_MAKE_ERROR(ovrResult r, const char* description); +/// OVRError OVR_MAKE_ERROR_F(ovrResult r, const char* format, ...); +/// +/// OVRError OVR_MAKE_SYS_ERROR(ovrResult r, ovrSysErrorCode sysCode, const char* description); +/// OVRError OVR_MAKE_SYS_ERROR_F(ovrResult r, ovrSysErrorCode sysCode, const char* format, ...); +/// +/// Example usage: +/// OVRError InitGraphics() +/// { +/// if(!GraphicsCardPresent()) +/// { +/// return OVR_MAKE_ERROR(ovrError_GraphicsInit, "Failed to init graphics; graphics +/// support absent."); +/// } +/// +/// HRESULT hr = pDevice->CreateTexture2D(&dsDesc, nullptr, &Texture); +/// if(FAILED(hr)) +/// { +/// return OVR_MAKE_SYS_ERROR_F(ovrError_GraphicsInit, hr, "Failed to create texture of +/// size %u x %u", dsDesc.Width, dsDesc.Height); +/// } +/// or: +/// OVR_HR_CHECK_RET_ERROR(ovrError_GraphicsInit, hr, "Failed to create texture of size +/// %u x %u", dsDesc.Width, dsDesc.Height); +/// +/// return ovrSuccess; // Converts to an OVRError instance that has no error. +/// } +/// +#define OVR_MAKE_ERROR(errorCode, pDescription) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::None, \ + OVR::ovrSysErrorCodeSuccess, \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + true, \ + nullptr, \ + "%s", \ + (pDescription)) + +// Note: The format string is the first part of the .../__VA_ARGS__ as per the C99-C++11 Standards. +#define OVR_MAKE_ERROR_F(errorCode, ...) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::None, \ + OVR::ovrSysErrorCodeSuccess, \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + true, \ + nullptr, \ + __VA_ARGS__) + +#define OVR_MAKE_SYS_ERROR(errorCode, sysErrorCode, pDescription) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::OS, \ + (sysErrorCode), \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + true, \ + nullptr, \ + "%s", \ + (pDescription)) + +// Note: The format string is the first part of the .../__VA_ARGS__ as per the C99-C++11 Standards. +#define OVR_MAKE_SYS_ERROR_F(errorCode, sysErrorCode, ...) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::OS, \ + (sysErrorCode), \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + true, \ + nullptr, \ + __VA_ARGS__) + +#define OVR_MAKE_VULKAN_ERROR(errorCode, sysErrorCode, pDescription) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::Vulkan, \ + (sysErrorCode), \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + true, \ + nullptr, \ + "%s", \ + (pDescription)) + +// Note: The format string is the first part of the .../__VA_ARGS__ as per the C99-C++11 Standards. +#define OVR_MAKE_VULKAN_ERROR_F(errorCode, sysErrorCode, ...) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::Vulkan, \ + (sysErrorCode), \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + true, \ + nullptr, \ + __VA_ARGS__) + +#define OVR_MAKE_OPENGL_ERROR(errorCode, sysErrorCode, pDescription) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::OpenGL, \ + (sysErrorCode), \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + true, \ + nullptr, \ + "%s", \ + (pDescription)) + +// Note: The format string is the first part of the .../__VA_ARGS__ as per the C99-C++11 Standards. +#define OVR_MAKE_OPENGL_ERROR_F(errorCode, sysErrorCode, ...) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::OpenGL, \ + (sysErrorCode), \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + true, \ + nullptr, \ + __VA_ARGS__) + +// Consider using OVR_MAKE_QUIET_ERROR() instead of OVR_MAKE_ERROR() where the error +// should not automatically log/assert. If the error is normal (HMD unplugged) or +// repetitive then please use OVR_MAKE_QUIET_ERROR(). + +#define OVR_MAKE_QUIET_ERROR(errorCode, pDescription) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::None, \ + OVR::ovrSysErrorCodeSuccess, \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + false, \ + false, \ + nullptr, \ + "%s", \ + (pDescription)) + +// Note: The format string is the first part of the .../__VA_ARGS__ as per the C99-C++11 Standards. +#define OVR_MAKE_QUIET_ERROR_F(errorCode, ...) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::None, \ + OVR::ovrSysErrorCodeSuccess, \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + false, \ + false, \ + nullptr, \ + __VA_ARGS__) + +#define OVR_MAKE_QUIET_SYS_ERROR(errorCode, sysErrorCode, pDescription) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::OS, \ + (sysErrorCode), \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + false, \ + false, \ + nullptr, \ + "%s", \ + (pDescription)) + +// Note: The format string is the first part of the .../__VA_ARGS__ as per the C99-C++11 Standards. +#define OVR_MAKE_QUIET_SYS_ERROR_F(errorCode, sysErrorCode, ...) \ + OVR::MakeError( \ + (errorCode), \ + ovrSysErrorCodeType::OS, \ + (sysErrorCode), \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + false, \ + false, \ + nullptr, \ + __VA_ARGS__) + +// Consider using OVR_MAKE_NOASSERT_ERROR() instead of OVR_MAKE_ERROR() where the error +// should not automatically log/assert. If the error is normal (HMD unplugged) or +// repetitive then please use OVR_MAKE_NOASSERT_ERROR(). + +#define OVR_MAKE_NOASSERT_ERROR(errorCode, pDescription) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::None, \ + OVR::ovrSysErrorCodeSuccess, \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + false, \ + nullptr, \ + "%s", \ + (pDescription)) + +// Note: The format string is the first part of the .../__VA_ARGS__ as per the C99-C++11 Standards. +#define OVR_MAKE_NOASSERT_ERROR_F(errorCode, ...) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::None, \ + OVR::ovrSysErrorCodeSuccess, \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + false, \ + nullptr, \ + __VA_ARGS__) + +#define OVR_MAKE_NOASSERT_SYS_ERROR(errorCode, sysErrorCode, pDescription) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::OS, \ + (sysErrorCode), \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + false, \ + nullptr, \ + "%s", \ + (pDescription)) + +// Note: The format string is the first part of the .../__VA_ARGS__ as per the C99-C++11 Standards. +#define OVR_MAKE_NOASSERT_SYS_ERROR_F(errorCode, sysErrorCode, ...) \ + OVR::MakeError( \ + (errorCode), \ + OVR::ovrSysErrorCodeType::OS, \ + (sysErrorCode), \ + nullptr, \ + OVR_FILE, \ + OVR_LINE, \ + true, \ + false, \ + nullptr, \ + __VA_ARGS__) + +// Set the TLS last error: +#define OVR_SET_ERROR(ovrError) OVR::SetError(ovrError) + +// Log the error if it has not already been logged: +#define OVR_LOG_ERROR(ovrError) OVR::LogError(ovrError) + +// Check an HRESULT error code and assert/log on failure: +#define OVR_HR_CHECK_RET_ERROR(errorCode, sysErrorCode, pDescription) \ + if (FAILED(sysErrorCode)) { \ + return OVR_MAKE_SYS_ERROR_F((errorCode), (sysErrorCode), "%s", (pDescription)); \ + } + +// Note: The format string is the first part of the .../__VA_ARGS__ as per the C99-C++11 Standards. +#define OVR_HR_CHECK_RET_ERROR_F(errorCode, sysErrorCode, ...) \ + if (FAILED(sysErrorCode)) { \ + return OVR_MAKE_SYS_ERROR_F((errorCode), (sysErrorCode), __VA_ARGS__); \ + } + +/// ----------------------------------------------------------------------------- +/// ***** ovrSysErrorCodeType +/// +enum class ovrSysErrorCodeType { + None, + OS, /// Windows: HRESULT or DWORD system error code from GetLastError. + ALVR, /// AMD LiquidVR error + NVAPI, /// NVidia API error + NVENC, /// NVidia video encode API error + Vulkan, /// Vulkan graphics API + OpenGL /// OpenGL graphics API +}; + +/// ----------------------------------------------------------------------------- +/// ***** ovrSysErrorCode +/// +/// Identifies a platform- or API-specific error identifier. +/// The error space is identified by ovrSysErrorCodeType. +/// +typedef uint32_t ovrSysErrorCode; + +/// ----------------------------------------------------------------------------- +/// ***** ovrSysErrorCodeSuccess +/// +/// Identifies a ovrSysErrorCode that's success. +/// +const ovrSysErrorCode ovrSysErrorCodeSuccess = 0; + +/// ----------------------------------------------------------------------------- +/// ***** ovrSysErrorCodeNone +/// +/// Identifies a ovrSysErrorCode that's un-set. +/// +const ovrSysErrorCode ovrSysErrorCodeNone = 0; + +// SysClockTime is a C++11 equivalent to C time_t. +typedef std::chrono::time_point SysClockTime; + +/// ----------------------------------------------------------------------------- +/// ***** OVRError +/// +/// Represents an error and relevant information about it. +/// While you can create error instances directly via this class, it's better if +/// you create them via the OVR_MAKE_ERROR family of macros, or at least via the +/// MakeError function. +/// +/// Relevant design analogues: +/// https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSError_Class/ +/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms723041%28v=vs.85%29.aspx +/// +class OVRError { + private: + // Cannot convert boolean to OVRError - It must be done explicitly. + explicit OVRError(bool) = delete; + + public: + OVRError(); + OVRError(ovrResult code); // Intentionally not explicit. + OVRError(ovrResult code, const char* pFormat, ...); + + OVRError(const OVRError& OVRError); + OVRError(OVRError&& OVRError); + + virtual ~OVRError(); + + // Construct a success code. Use Succeeded() to check for success. + static OVRError Success() { + return OVRError(); + } + + OVRError& operator=(const OVRError& OVRError); + OVRError& operator=(OVRError&& OVRError); + + // Use this to check if result is a success code + bool Succeeded() const { + return Code >= ovrSuccess; + } + bool Failed() const { + return !Succeeded(); + } + + // Sets the OVRTime, ClockTime, Backtrace to current values. + void SetCurrentValues(); // To do: Come up with a more appropiate name. + + // Clears all members to a newly default-constructed state. + void Reset(); + + // Get the full error string for this error. May include newlines. + String GetErrorString() const; + + // Property accessors + void SetCode(ovrResult code); + ovrResult GetCode() const; + + // Example usage: + // ovrResult SomeFunction() { + // OVRError err = SomeOtherFunction(); + // return err; + // } + operator ovrResult() const { + return Code; + } + + void SetSysCode( + ovrSysErrorCodeType sysCodeType, + ovrSysErrorCode sysCode, + const char* sysCodeString = nullptr); + ovrSysErrorCodeType GetSysCodeType() const; + ovrSysErrorCode GetSysCode() const; + + void SetDescription(const char* pDescription); + String GetDescription() const; + + void SetContext(const char* pContext); + String GetContext() const; + + void SetOVRTime(double ovrTime); + double GetOVRTime() const; + + void SetSysClockTime(const SysClockTime& clockTime); + SysClockTime GetSysClockTime() const; + + static const int64_t kLogLineUnset = -1; + void SetLogLine(int64_t logLine); + int64_t GetLogLine() const; + + bool IsAlreadyLogged() const { + return AlreadyLogged; + } + void SetAlreadyLogged() { + AlreadyLogged = true; + } + void ResetAlreadyLogged() { + AlreadyLogged = false; + } + + void SetSource(const char* pSourceFilePath, int sourceFileLine); + std::pair GetSource() const; + + typedef OVR::Array AddressArray; + AddressArray GetBacktrace() const; + + static void RegisterResultCodeName(ovrResult number, const char* name); + + protected: + mutable StringBuffer ErrorString; /// Complete error string describing the variables below. + ovrResult Code; /// The main ovrResult, which is a high level error id. + ovrSysErrorCodeType SysCodeType; + ovrSysErrorCode SysCode; /// ovrSysErrorCodeSuccess means no system error code. + char SysCodeStr[64]; /// String describing just the sys code error. + String Description; /// Unlocalized error description string. + String Context; /// Context string. For example, for a file open failure this is the file path. + double OVRTime; /// Time when the error was generated. Same format as OVR time. + SysClockTime ClockTime; /// Wall clock time. + int64_t LogLine; /// Log line of the error. -1 if not set (not logged). + String SourceFilePath; /// The __FILE__ where the error was first encountered. + int SourceFileLine; /// The __LINE__ where the error was first encountered. + AddressArray Backtrace; /// Backtrace at point of error. May be empty in publicly released builds. + bool AlreadyLogged; /// Error has already been logged to avoid double-printing it. +}; + +/// ----------------------------------------------------------------------------- +/// ***** SetError +/// +/// This function sets the error as the last error via the TLS last error class. +/// +void SetError(OVRError& ovrError); + +/// ----------------------------------------------------------------------------- +/// ***** LogError +/// +/// Utility function for logging an error based on the Log subsystem. +/// +void LogError(OVRError& ovrError); + +/// ----------------------------------------------------------------------------- +/// ***** MakeError +/// +/// Utility function for making an error, logging it, and setting it as the last error for the +/// current thread. It's preferred to instead use the OVR_MAKE_ERROR macro functions, as they handle +/// file/line functionality cleanly between debug and release. The "quiet" parameter will prevent it +/// from automatically logging/asserting. +/// +OVRError MakeError( + ovrResult errorCode, + ovrSysErrorCodeType sysCodeType, + ovrSysErrorCode sysCode, + const char* sysCodeString, // Optional pre-generated sys error code string. + const char* pSourceFile, + int sourceLine, + bool logError, + bool assertError, + const char* pContext, + const char* pDescriptionFormat, + ...) OVR_LOG_VAARG_ATTRIBUTE(10, 11); + +// ----------------------------------------------------------------------------- +// ***** LastErrorTLS +// +// We don't use C++11 thread-local storage nor C-style __thread/__declsped(thread) +// to manager thread-local storage, as neither of these provide a means for us +// to control the lifetime of the data. Rather it can be controlled only +// passively by the thread's lifetime. Similarly we don't use pthread_getspecific +// pthread_setspecific (and Windows equivalents) because they too don't let us +// control the lifetime of the data. Our solution is to have a map of threads +// to thread-specific data, and we can clear the entire map on ovrShutdown as-needed. +// this scheme is not as fast as the aforementioned schemes but it doesn't need to +// be fast for our use. +// +// We use pointers below instead of concrete objects because we want to have their +// lifetimes entirely controlled by ovr_Initialize/ovr_Shutdown. + +class LastErrorTLS : public NewOverrideBase, public SystemSingletonBase { + OVR_DECLARE_SINGLETON(LastErrorTLS); + + public: + OVRError& LastError(); + + protected: + // Protect hash from multiple thread access. + Lock TheLock; + + // Map thread-id to OVRError objects. + typedef Hash TLSHash; + TLSHash TLSDictionary; +}; + +/// ----------------------------------------------------------------------------- +/// ***** GetErrorCodeName +/// +/// Utility function which converts an ovrResult error code to a string which matches +/// errorCode's ovrResult enumeration identifier. +/// +const char* GetErrorCodeName(ovrResult errorCode); + +/// ----------------------------------------------------------------------------- +/// ***** GetErrorCodeString +/// +/// Utility function which converts an ovrResult error code to a readable string version. +/// +bool GetErrorCodeString(ovrResult errorCode, bool prefixErrorCode, OVR::String& sResult); + +/// ----------------------------------------------------------------------------- +/// ***** GetSysErrorCodeString +/// +/// Utility function which converts a system error to a string. Similar to the Windows FormatMessage +/// function and the Unix strerror_r function. +/// If prefixErrorCode is true then the string is prefixed with ": " +/// Returns true if the sysErrorCode was a known valid code and a string was produced from it. +/// Else the returned string will be empty. The returned string may have tabs or newlines. +/// Users of OVR_MAKE_SYS_ERROR and MakeError don't need to call this function, as it's done +/// automatically internally. +/// +bool GetSysErrorCodeString( + ovrSysErrorCodeType sysErrorCodeType, + ovrSysErrorCode sysErrorCode, + bool prefixErrorCode, + OVR::String& sResult); + +//------------------------------------------------------------------------------------- +// C++ Exception state + +// CPPExceptionInfo contains information about a possible exception state for the current library. +// We cannot safely use the OVRError system for this, as it could fail when we are in an exceptional +// state. It would be a non-trivial effort to make the OVRError system work in a way that doesn't +// allocate memory, for various reasons. + +struct CPPExceptionInfo { + CPPExceptionInfo() OVR_NOEXCEPT : ExceptionOccurred(false), Description() {} + + void Reset() OVR_NOEXCEPT { + ExceptionOccurred = false; + Description[0] = '\0'; + } + + void FromStdException(const std::exception& e) OVR_NOEXCEPT { + ExceptionOccurred = true; + OVR_strlcpy(Description, e.what(), sizeof(Description)); + } + + void FromString(const char* str) OVR_NOEXCEPT { + ExceptionOccurred = true; + OVR_strlcpy(Description, str, sizeof(Description)); + } + + // If this get set to true then it should never be set back to false + // except by an unloading of the module (i.e. DLL) itself. + bool ExceptionOccurred; + + // Describes the exception in a way that makes no external calls + // nor allocates any memory. + char Description[256]; +}; + +extern OVR::CPPExceptionInfo gCPPExceptionInfo; + +// Helper macros to make repetitive exception handling tasks non-redundant. +// +// Example usage: +// OVR_PUBLIC_FUNCTION(void) ovr_DoSomething(ovrSession session) +// { +// OVR_CAPI_TRY_VOID +// { +// HMDState* hmds = GetHMDStateFromOvrHmd(session); +// if (hmds) +// hmds->DoSomething(); +// } +// OVR_CAPI_CATCH +// } +// +// OVR_PUBLIC_FUNCTION(int) ovr_DoSomething(ovrSession session) +// { +// int result = 0; +// +// OVR_CAPI_TRY_VALUE(result) +// { +// HMDState* hmds = GetHMDStateFromOvrHmd(session); +// if (hmds) +// result = hmds->DoSomething; +// } +// OVR_CAPI_CATCH +// +// return result; +// } +// +// OVR_PUBLIC_FUNCTION(ovrResult) ovr_DoSomething(ovrSession session) +// { +// OVR_CAPI_TRY_OVRRESULT +// { +// HMDState* pState = GetHMDStateFromOvrHmd(session); +// if (!pState) +// { +// OVR_MAKE_ERROR(ovrError_InvalidSession, L"Invalid session."); +// return ovrError_InvalidSession; +// } +// return hmds->DoSomething(); +// } +// OVR_CAPI_CATCH +// +// return ovrError_CPPException; +// } + +#if defined(OVR_BUILD_DEBUG) + +#define OVR_CAPI_TRY_VOID \ + do { \ + } while (false); + +#define OVR_CAPI_TRY_VALUE(exceptionStateReturnValue) \ + do { \ + } while (false); + +#define OVR_CAPI_TRY_OVRRESULT \ + do { \ + } while (false); + +#define OVR_CAPI_CATCH \ + do { \ + } while (false); + +#else // OVR_BUILD_DEBUG + +#define OVR_CAPI_TRY_VOID \ + if (OVR::gCPPExceptionInfo.ExceptionOccurred) \ + return; \ + try + +#define OVR_CAPI_TRY_VALUE(exceptionStateReturnValue) \ + if (OVR::gCPPExceptionInfo.ExceptionOccurred) \ + return exceptionStateReturnValue; \ + try + +#define OVR_CAPI_TRY_OVRRESULT \ + if (OVR::gCPPExceptionInfo.ExceptionOccurred) \ + return ovrError_RuntimeException; \ + try + +#define OVR_CAPI_CATCH \ + catch (const std::exception& e) { \ + OVR::gCPPExceptionInfo.FromStdException(e); \ + } \ + catch (...) { \ + OVR::gCPPExceptionInfo.FromString("Non-standard C++ exception occurred."); \ + } + +#endif // OVR_BUILD_DEBUG + +/// ----------------------------------------------------------------------------- +/// ***** OVRErrorCallback +/// +/// Identifies a callback error handler. +/// Callbacks were added instead of integrating logic directly in OVRError +/// to make application specific logic easier +/// +typedef std::function OVRErrorCallback; + +/// ----------------------------------------------------------------------------- +/// ***** SetErrorCallback +/// +/// Sets callback to be issued whenever an error is encountered. +/// +void SetErrorCallback(OVRErrorCallback callback); + +} // namespace OVR + +#ifndef MICRO_OVR +namespace ovrlog { + +template <> +void LogStringize(LogStringBuffer& buffer, const OVR::OVRError& error); + +} // namespace ovrlog +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_File.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_File.cpp new file mode 100644 index 0000000..5f370c0 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_File.cpp @@ -0,0 +1,521 @@ +/************************************************************************** + +Filename : OVR_File.cpp +Content : File wrapper class implementation (Win32) + +Created : April 5, 1999 +Authors : Michael Antonov + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +**************************************************************************/ + +#define GFILE_CXX + +// Standard C library (Captain Obvious guarantees!) +#include + +#include "OVR_File.h" + +namespace OVR { + +// Buffered file adds buffering to an existing file +// FILEBUFFER_SIZE defines the size of internal buffer, while +// FILEBUFFER_TOLERANCE controls the amount of data we'll effectively try to buffer +#define FILEBUFFER_SIZE (8192 - 8) +#define FILEBUFFER_TOLERANCE 4096 + +// ** Constructor/Destructor + +// Hidden constructor +// Not supposed to be used +BufferedFile::BufferedFile() : DelegatedFile(0) { + pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE); + BufferMode = NoBuffer; + FilePos = 0; + Pos = 0; + DataSize = 0; +} + +// Takes another file as source +BufferedFile::BufferedFile(File* pfile) : DelegatedFile(pfile) { + pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE); + BufferMode = NoBuffer; + FilePos = pfile->LTell(); + Pos = 0; + DataSize = 0; +} + +// Destructor +BufferedFile::~BufferedFile() { + // Flush in case there's data + if (pFile) + FlushBuffer(); + // Get rid of buffer + if (pBuffer) + OVR_FREE(pBuffer); +} + +/* +bool BufferedFile::VCopy(const Object &source) +{ + if (!DelegatedFile::VCopy(source)) + return 0; + + // Data members + BufferedFile *psource = (BufferedFile*)&source; + + // Buffer & the mode it's in + pBuffer = psource->pBuffer; + BufferMode = psource->BufferMode; + Pos = psource->Pos; + DataSize = psource->DataSize; + return 1; +} +*/ + +// Initializes buffering to a certain mode +bool BufferedFile::SetBufferMode(BufferModeType mode) { + if (!pBuffer) + return false; + if (mode == BufferMode) + return true; + + FlushBuffer(); + + // Can't set write mode if we can't write + if ((mode == WriteBuffer) && (!pFile || !pFile->IsWritable())) + return 0; + + // And SetMode + BufferMode = mode; + Pos = 0; + DataSize = 0; + return 1; +} + +// Flushes buffer +void BufferedFile::FlushBuffer() { + switch (BufferMode) { + case WriteBuffer: + // Write data in buffer + FilePos += pFile->Write(pBuffer, Pos); + Pos = 0; + break; + + case ReadBuffer: + // Seek back & reset buffer data + if ((DataSize - Pos) > 0) + FilePos = pFile->LSeek(-(int)(DataSize - Pos), Seek_Cur); + DataSize = 0; + Pos = 0; + break; + default: + // not handled! + break; + } +} + +// Reloads data for ReadBuffer +void BufferedFile::LoadBuffer() { + if (BufferMode == ReadBuffer) { + // We should only reload once all of pre-loaded buffer is consumed. + OVR_ASSERT(Pos == DataSize); + + // WARNING: Right now LoadBuffer() assumes the buffer's empty + int sz = pFile->Read(pBuffer, FILEBUFFER_SIZE); + DataSize = sz < 0 ? 0 : (unsigned)sz; + Pos = 0; + FilePos += DataSize; + } +} + +// ** Overridden functions + +// We override all the functions that can possibly +// require buffer mode switch, flush, or extra calculations + +// Tell() requires buffer adjustment +int BufferedFile::Tell() { + if (BufferMode == ReadBuffer) + return int(FilePos - DataSize + Pos); + + int pos = pFile->Tell(); + // Adjust position based on buffer mode & data + if (pos != -1) { + OVR_ASSERT(BufferMode != ReadBuffer); + if (BufferMode == WriteBuffer) + pos += Pos; + } + return pos; +} + +int64_t BufferedFile::LTell() { + if (BufferMode == ReadBuffer) + return FilePos - DataSize + Pos; + + int64_t pos = pFile->LTell(); + if (pos != -1) { + OVR_ASSERT(BufferMode != ReadBuffer); + if (BufferMode == WriteBuffer) + pos += Pos; + } + return pos; +} + +int BufferedFile::GetLength() { + int len = pFile->GetLength(); + // If writing through buffer, file length may actually be bigger + if ((len != -1) && (BufferMode == WriteBuffer)) { + int currPos = pFile->Tell() + Pos; + if (currPos > len) + len = currPos; + } + return len; +} +int64_t BufferedFile::LGetLength() { + int64_t len = pFile->LGetLength(); + // If writing through buffer, file length may actually be bigger + if ((len != -1) && (BufferMode == WriteBuffer)) { + int64_t currPos = pFile->LTell() + Pos; + if (currPos > len) + len = currPos; + } + return len; +} + +/* +bool BufferedFile::Stat(FileStats *pfs) +{ + // Have to fix up length is stat + if (pFile->Stat(pfs)) + { + if (BufferMode==WriteBuffer) + { + int64_t currPos = pFile->LTell() + Pos; + if (currPos > pfs->Size) + { + pfs->Size = currPos; + // ?? + pfs->Blocks = (pfs->Size+511) >> 9; + } + } + return 1; + } + return 0; +} +*/ + +int BufferedFile::Write(const uint8_t* psourceBuffer, int numBytes) { + if ((BufferMode == WriteBuffer) || SetBufferMode(WriteBuffer)) { + // If not data space in buffer, flush + if ((FILEBUFFER_SIZE - (int)Pos) < numBytes) { + FlushBuffer(); + // If bigger then tolerance, just write directly + if (numBytes > FILEBUFFER_TOLERANCE) { + int sz = pFile->Write(psourceBuffer, numBytes); + if (sz > 0) + FilePos += sz; + return sz; + } + } + + // Enough space in buffer.. so copy to it + memcpy(pBuffer + Pos, psourceBuffer, numBytes); + Pos += numBytes; + return numBytes; + } + int sz = pFile->Write(psourceBuffer, numBytes); + if (sz > 0) + FilePos += sz; + return sz; +} + +int BufferedFile::Read(uint8_t* pdestBuffer, int numBytes) { + if ((BufferMode == ReadBuffer) || SetBufferMode(ReadBuffer)) { + // Data in buffer... copy it + if ((int)(DataSize - Pos) >= numBytes) { + memcpy(pdestBuffer, pBuffer + Pos, numBytes); + Pos += numBytes; + return numBytes; + } + + // Not enough data in buffer, copy buffer + int readBytes = DataSize - Pos; + memcpy(pdestBuffer, pBuffer + Pos, readBytes); + numBytes -= readBytes; + pdestBuffer += readBytes; + Pos = DataSize; + + // Don't reload buffer if more then tolerance + // (No major advantage, and we don't want to write a loop) + if (numBytes > FILEBUFFER_TOLERANCE) { + numBytes = pFile->Read(pdestBuffer, numBytes); + if (numBytes > 0) { + FilePos += numBytes; + Pos = DataSize = 0; + } + return readBytes + ((numBytes == -1) ? 0 : numBytes); + } + + // Reload the buffer + // WARNING: Right now LoadBuffer() assumes the buffer's empty + LoadBuffer(); + if ((int)(DataSize - Pos) < numBytes) + numBytes = (int)DataSize - Pos; + + memcpy(pdestBuffer, pBuffer + Pos, numBytes); + Pos += numBytes; + return numBytes + readBytes; + + /* + // Alternative Read implementation. The one above is probably better + // due to FILEBUFFER_TOLERANCE. + int total = 0; + + do { + int bufferBytes = (int)(DataSize-Pos); + int copyBytes = (bufferBytes > numBytes) ? numBytes : bufferBytes; + + memcpy(pdestBuffer, pBuffer+Pos, copyBytes); + numBytes -= copyBytes; + pdestBuffer += copyBytes; + Pos += copyBytes; + total += copyBytes; + + if (numBytes == 0) + break; + LoadBuffer(); + + } while (DataSize > 0); + + return total; + */ + } + int sz = pFile->Read(pdestBuffer, numBytes); + if (sz > 0) + FilePos += sz; + return sz; +} + +int BufferedFile::SkipBytes(int numBytes) { + int skippedBytes = 0; + + // Special case for skipping a little data in read buffer + if (BufferMode == ReadBuffer) { + skippedBytes = (((int)DataSize - (int)Pos) >= numBytes) ? numBytes : (DataSize - Pos); + Pos += skippedBytes; + numBytes -= skippedBytes; + } + + if (numBytes) { + numBytes = pFile->SkipBytes(numBytes); + // Make sure we return the actual number skipped, or error + if (numBytes != -1) { + skippedBytes += numBytes; + FilePos += numBytes; + Pos = DataSize = 0; + } else if (skippedBytes <= 0) + skippedBytes = -1; + } + return skippedBytes; +} + +int BufferedFile::BytesAvailable() { + int available = pFile->BytesAvailable(); + // Adjust available size based on buffers + switch (BufferMode) { + case ReadBuffer: + available += DataSize - Pos; + break; + case WriteBuffer: + available -= Pos; + if (available < 0) + available = 0; + break; + default: + break; + } + return available; +} + +bool BufferedFile::Flush() { + FlushBuffer(); + return pFile->Flush(); +} + +// Seeking could be optimized better.. +int BufferedFile::Seek(int offset, int origin) { + if (BufferMode == ReadBuffer) { + if (origin == Seek_Cur) { + // Seek can fall either before or after Pos in the buffer, + // but it must be within bounds. + if (((unsigned(offset) + Pos)) <= DataSize) { + Pos += offset; + return int(FilePos - DataSize + Pos); + } + + // Lightweight buffer "Flush". We do this to avoid an extra seek + // back operation which would take place if we called FlushBuffer directly. + origin = Seek_Set; + OVR_ASSERT(((FilePos - DataSize + Pos) + (uint64_t)offset) < ~(uint64_t)0); + offset = (int)(FilePos - DataSize + Pos) + offset; + Pos = DataSize = 0; + } else if (origin == Seek_Set) { + if (((unsigned)offset - (FilePos - DataSize)) <= DataSize) { + OVR_ASSERT((FilePos - DataSize) < ~(uint64_t)0); + Pos = (unsigned)offset - (unsigned)(FilePos - DataSize); + return offset; + } + Pos = DataSize = 0; + } else { + FlushBuffer(); + } + } else { + FlushBuffer(); + } + + /* + // Old Seek Logic + if (origin == Seek_Cur && offset + Pos < DataSize) + { + //OVR_ASSERT((FilePos - DataSize) >= (FilePos - DataSize + Pos + offset)); + Pos += offset; + OVR_ASSERT(int (Pos) >= 0); + return int (FilePos - DataSize + Pos); + } + else if (origin == Seek_Set && unsigned(offset) >= FilePos - DataSize && unsigned(offset) < + FilePos) + { + Pos = unsigned(offset - FilePos + DataSize); + OVR_ASSERT(int (Pos) >= 0); + return int (FilePos - DataSize + Pos); + } + + FlushBuffer(); + */ + + FilePos = pFile->Seek(offset, origin); + return int(FilePos); +} + +int64_t BufferedFile::LSeek(int64_t offset, int origin) { + if (BufferMode == ReadBuffer) { + if (origin == Seek_Cur) { + // Seek can fall either before or after Pos in the buffer, + // but it must be within bounds. + if (((unsigned(offset) + Pos)) <= DataSize) { + Pos += (unsigned)offset; + return int64_t(FilePos - DataSize + Pos); + } + + // Lightweight buffer "Flush". We do this to avoid an extra seek + // back operation which would take place if we called FlushBuffer directly. + origin = Seek_Set; + offset = (int64_t)(FilePos - DataSize + Pos) + offset; + Pos = DataSize = 0; + } else if (origin == Seek_Set) { + if (((uint64_t)offset - (FilePos - DataSize)) <= DataSize) { + Pos = (unsigned)((uint64_t)offset - (FilePos - DataSize)); + return offset; + } + Pos = DataSize = 0; + } else { + FlushBuffer(); + } + } else { + FlushBuffer(); + } + + /* + OVR_ASSERT(BufferMode != NoBuffer); + + if (origin == Seek_Cur && offset + Pos < DataSize) + { + Pos += int (offset); + return FilePos - DataSize + Pos; + } + else if (origin == Seek_Set && offset >= int64_t(FilePos - DataSize) && offset < + int64_t(FilePos)) + { + Pos = unsigned(offset - FilePos + DataSize); + return FilePos - DataSize + Pos; + } + + FlushBuffer(); + */ + + FilePos = pFile->LSeek(offset, origin); + return FilePos; +} + +int BufferedFile::CopyFromStream(File* pstream, int byteSize) { + // We can't rely on overridden Write() + // because delegation doesn't override virtual pointers + // So, just re-implement + uint8_t* buff = new uint8_t[0x4000]; + int count = 0; + int szRequest, szRead, szWritten; + + while (byteSize) { + szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize; + + szRead = pstream->Read(buff, szRequest); + szWritten = 0; + if (szRead > 0) + szWritten = Write(buff, szRead); + + count += szWritten; + byteSize -= szWritten; + if (szWritten < szRequest) + break; + } + + delete[] buff; + + return count; +} + +// Closing files +bool BufferedFile::Close() { + switch (BufferMode) { + case WriteBuffer: + FlushBuffer(); + break; + case ReadBuffer: + // No need to seek back on close + BufferMode = NoBuffer; + break; + default: + break; + } + return pFile->Close(); +} + +// ***** Global path helpers + +// Find trailing short filename in a path. +const char* OVR_CDECL GetShortFilename(const char* purl) { + size_t len = OVR_strlen(purl); + for (size_t i = len; i > 0; i--) + if (purl[i] == '\\' || purl[i] == '/') + return purl + i + 1; + return purl; +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_File.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_File.h new file mode 100644 index 0000000..f18c908 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_File.h @@ -0,0 +1,695 @@ +/************************************************************************************ + +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 (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_File_h +#define OVR_File_h + +#include "OVR_Alg.h" +#include "OVR_RefCount.h" +#include "OVR_Std.h" + +#include +#include "OVR_String.h" + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** OVR_MAX_PATH +// +// Max file path length (for most uses). +// To do: move this to OVR_File. +// +#if !defined(OVR_MAX_PATH) +#if defined( \ + _WIN32) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx +#define OVR_MAX_PATH \ + MAX_PATH // Windows can use paths longer than MAX_PATH in some cases (network paths, UNC paths). +#else +#define OVR_MAX_PATH 1024 // This isn't a strict limit on all Unix-based platforms. +#endif +#endif + +// ***** 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, 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 int64_t LTell() = 0; + + // File size + virtual int GetLength() = 0; + virtual int64_t 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 uint8_t* 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(uint8_t* 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 int64_t LSeek(int64_t 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_t PRead64() { + uint64_t v = 0; + Read((uint8_t*)&v, 8); + return v; + } + uint32_t PRead32() { + uint32_t v = 0; + Read((uint8_t*)&v, 4); + return v; + } + uint16_t PRead16() { + uint16_t v = 0; + Read((uint8_t*)&v, 2); + return v; + } + uint8_t PRead8() { + uint8_t v = 0; + Read((uint8_t*)&v, 1); + return v; + } + void PWrite64(uint64_t v) { + Write((uint8_t*)&v, 8); + } + void PWrite32(uint32_t v) { + Write((uint8_t*)&v, 4); + } + void PWrite16(uint16_t v) { + Write((uint8_t*)&v, 2); + } + void PWrite8(uint8_t v) { + Write((uint8_t*)&v, 1); + } + + public: + // Writing primitive types - Little Endian + inline void WriteUByte(uint8_t v) { + PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); + } + inline void WriteSByte(int8_t v) { + PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); + } + inline void WriteUInt8(uint8_t v) { + PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); + } + inline void WriteSInt8(int8_t v) { + PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); + } + inline void WriteUInt16(uint16_t v) { + PWrite16((uint16_t)Alg::ByteUtil::SystemToLE(v)); + } + inline void WriteSInt16(int16_t v) { + PWrite16((uint16_t)Alg::ByteUtil::SystemToLE(v)); + } + inline void WriteUInt32(uint32_t v) { + PWrite32((uint32_t)Alg::ByteUtil::SystemToLE(v)); + } + inline void WriteSInt32(int32_t v) { + PWrite32((uint32_t)Alg::ByteUtil::SystemToLE(v)); + } + inline void WriteUInt64(uint64_t v) { + PWrite64((uint64_t)Alg::ByteUtil::SystemToLE(v)); + } + inline void WriteSInt64(int64_t v) { + PWrite64((uint64_t)Alg::ByteUtil::SystemToLE(v)); + } + inline void WriteFloat(float v) { + v = Alg::ByteUtil::SystemToLE(v); + Write((uint8_t*)&v, 4); + } + inline void WriteDouble(double v) { + v = Alg::ByteUtil::SystemToLE(v); + Write((uint8_t*)&v, 8); + } + // Writing primitive types - Big Endian + inline void WriteUByteBE(uint8_t v) { + PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); + } + inline void WriteSByteBE(int8_t v) { + PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); + } + inline void WriteUInt8BE(uint16_t v) { + PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); + } + inline void WriteSInt8BE(int16_t v) { + PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); + } + inline void WriteUInt16BE(uint16_t v) { + PWrite16((uint16_t)Alg::ByteUtil::SystemToBE(v)); + } + inline void WriteSInt16BE(uint16_t v) { + PWrite16((uint16_t)Alg::ByteUtil::SystemToBE(v)); + } + inline void WriteUInt32BE(uint32_t v) { + PWrite32((uint32_t)Alg::ByteUtil::SystemToBE(v)); + } + inline void WriteSInt32BE(uint32_t v) { + PWrite32((uint32_t)Alg::ByteUtil::SystemToBE(v)); + } + inline void WriteUInt64BE(uint64_t v) { + PWrite64((uint64_t)Alg::ByteUtil::SystemToBE(v)); + } + inline void WriteSInt64BE(uint64_t v) { + PWrite64((uint64_t)Alg::ByteUtil::SystemToBE(v)); + } + inline void WriteFloatBE(float v) { + v = Alg::ByteUtil::SystemToBE(v); + Write((uint8_t*)&v, 4); + } + inline void WriteDoubleBE(double v) { + v = Alg::ByteUtil::SystemToBE(v); + Write((uint8_t*)&v, 8); + } + + // Reading primitive types - Little Endian + inline uint8_t ReadUByte() { + return (uint8_t)Alg::ByteUtil::LEToSystem(PRead8()); + } + inline int8_t ReadSByte() { + return (int8_t)Alg::ByteUtil::LEToSystem(PRead8()); + } + inline uint8_t ReadUInt8() { + return (uint8_t)Alg::ByteUtil::LEToSystem(PRead8()); + } + inline int8_t ReadSInt8() { + return (int8_t)Alg::ByteUtil::LEToSystem(PRead8()); + } + inline uint16_t ReadUInt16() { + return (uint16_t)Alg::ByteUtil::LEToSystem(PRead16()); + } + inline int16_t ReadSInt16() { + return (int16_t)Alg::ByteUtil::LEToSystem(PRead16()); + } + inline uint32_t ReadUInt32() { + return (uint32_t)Alg::ByteUtil::LEToSystem(PRead32()); + } + inline int32_t ReadSInt32() { + return (int32_t)Alg::ByteUtil::LEToSystem(PRead32()); + } + inline uint64_t ReadUInt64() { + return (uint64_t)Alg::ByteUtil::LEToSystem(PRead64()); + } + inline int64_t ReadSInt64() { + return (int64_t)Alg::ByteUtil::LEToSystem(PRead64()); + } + inline float ReadFloat() { + float v = 0.0f; + Read((uint8_t*)&v, 4); + return Alg::ByteUtil::LEToSystem(v); + } + inline double ReadDouble() { + double v = 0.0; + Read((uint8_t*)&v, 8); + return Alg::ByteUtil::LEToSystem(v); + } + // Reading primitive types - Big Endian + inline uint8_t ReadUByteBE() { + return (uint8_t)Alg::ByteUtil::BEToSystem(PRead8()); + } + inline int8_t ReadSByteBE() { + return (int8_t)Alg::ByteUtil::BEToSystem(PRead8()); + } + inline uint8_t ReadUInt8BE() { + return (uint8_t)Alg::ByteUtil::BEToSystem(PRead8()); + } + inline int8_t ReadSInt8BE() { + return (int8_t)Alg::ByteUtil::BEToSystem(PRead8()); + } + inline uint16_t ReadUInt16BE() { + return (uint16_t)Alg::ByteUtil::BEToSystem(PRead16()); + } + inline int16_t ReadSInt16BE() { + return (int16_t)Alg::ByteUtil::BEToSystem(PRead16()); + } + inline uint32_t ReadUInt32BE() { + return (uint32_t)Alg::ByteUtil::BEToSystem(PRead32()); + } + inline int32_t ReadSInt32BE() { + return (int32_t)Alg::ByteUtil::BEToSystem(PRead32()); + } + inline uint64_t ReadUInt64BE() { + return (uint64_t)Alg::ByteUtil::BEToSystem(PRead64()); + } + inline int64_t ReadSInt64BE() { + return (int64_t)Alg::ByteUtil::BEToSystem(PRead64()); + } + inline float ReadFloatBE() { + float v = 0.0f; + Read((uint8_t*)&v, 4); + return Alg::ByteUtil::BEToSystem(v); + } + inline double ReadDoubleBE() { + double v = 0.0; + Read((uint8_t*)&v, 8); + return Alg::ByteUtil::BEToSystem(v); + } +}; + +// *** Delegated File + +class DelegatedFile : public File { + protected: + // Delegating file pointer + Ptr 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 int64_t LTell() { + return pFile->LTell(); + } + + virtual int GetLength() { + return pFile->GetLength(); + } + virtual int64_t 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 uint8_t* pbuffer, int numBytes) { + return pFile->Write(pbuffer, numBytes); + } + virtual int Read(uint8_t* 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 int64_t LSeek(int64_t 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 + uint8_t* pBuffer; + BufferModeType BufferMode; + // Position in buffer + unsigned Pos; + // Data in buffer if reading + unsigned DataSize; + // Underlying file position + uint64_t 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(); + BufferedFile(const BufferedFile&) + : DelegatedFile(), pBuffer(NULL), BufferMode(NoBuffer), Pos(0), DataSize(0), FilePos(0) {} + + 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 int64_t LTell(); + + virtual int GetLength(); + virtual int64_t LGetLength(); + + // virtual bool Stat(GFileStats *pfs); + + virtual int Write(const uint8_t* pbufer, int numBytes); + virtual int Read(uint8_t* pbufer, int numBytes); + + virtual int SkipBytes(int numBytes); + + virtual int BytesAvailable(); + + virtual bool Flush(); + + virtual int Seek(int offset, int origin = Seek_Set); + virtual int64_t LSeek(int64_t 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; + } + int64_t LTell() { + return (int64_t)FileIndex; + } + + int GetLength() { + return FileSize; + } + int64_t LGetLength() { + return (int64_t)FileSize; + } + + bool Close() { + Valid = false; + return false; + } + + int CopyFromStream(File* pstream, int byteSize) { + OVR_UNUSED2(pstream, byteSize); + return 0; + } + + int Write(const uint8_t* pbuffer, int numBytes) { + OVR_UNUSED2(pbuffer, numBytes); + return 0; + } + + int Read(uint8_t* 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; + } + + int64_t LSeek(int64_t offset, int origin = Seek_Set) { + return (int64_t)Seek((int)offset, origin); + } + + public: + MemoryFile(const String& fileName, const uint8_t* 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 uint8_t* pBuffer, int buffSize) : FilePath(pfileName) { + FileData = pBuffer; + FileSize = buffSize; + FileIndex = 0; + Valid = (pfileName && pBuffer && buffSize > 0) ? true : false; + } + + private: + String FilePath; + const uint8_t* 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); + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_FileFILE.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_FileFILE.cpp new file mode 100644 index 0000000..ee71a41 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_FileFILE.cpp @@ -0,0 +1,575 @@ +/************************************************************************** + +Filename : OVR_FileFILE.cpp +Content : File wrapper class implementation (Win32) + +Created : April 5, 1999 +Authors : Michael Antonov + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +**************************************************************************/ + +#define GFILE_CXX + +#include "OVR_Types.h" + +// Standard C library (Captain Obvious guarantees!) +#include +#ifndef OVR_OS_WINCE +#include +#endif + +#include "OVR_SysFile.h" + +#ifndef OVR_OS_WINCE +#include +#endif + +namespace OVR { + +// ***** File interface + +// ***** FILEFile - C streams file + +static int SFerror() { + if (errno == ENOENT) + return FileConstants::Error_FileNotFound; + else if (errno == EACCES || errno == EPERM) + return FileConstants::Error_Access; + else if (errno == ENOSPC) + return FileConstants::Error_DiskFull; + else + return FileConstants::Error_IOError; +}; + +#if defined(OVR_CC_MSVC) +#include "share.h" +#endif + +#if defined(OVR_OS_WIN32) +#include "OVR_Win32_IncludeWindows.h" + +// A simple helper class to disable/enable system error mode, if necessary +// Disabling happens conditionally only if a drive name is involved +class SysErrorModeDisabler { + BOOL Disabled; + UINT OldMode; + + public: + SysErrorModeDisabler(const char* pfileName) { + if (pfileName && (pfileName[0] != 0) && pfileName[1] == ':') { + Disabled = TRUE; + OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS); + } else { + Disabled = 0; + OldMode = 0; + } + } + + ~SysErrorModeDisabler() { + if (Disabled) + ::SetErrorMode(OldMode); + } +}; +#else +class SysErrorModeDisabler { + public: + SysErrorModeDisabler(const char* pfileName) { + OVR_UNUSED(pfileName); + } +}; +#endif // OVR_OS_WIN32 + +// This macro enables verification of I/O results after seeks against a pre-loaded +// full file buffer copy. This is generally not necessary, but can been used to debug +// memory corruptions; we've seen this fail due to EAX2/DirectSound corrupting memory +// under FMOD with XP64 (32-bit) and Realtek HA Audio driver. +//#define GFILE_VERIFY_SEEK_ERRORS + +// This is the simplest possible file implementation, it wraps around the descriptor +// This file is delegated to by SysFile. + +class FILEFile : public File { + protected: + // Allocated filename + String FileName; + + // File handle & open mode + bool Opened; + FILE* fs; + int OpenFlags; + // Error code for last request + int ErrorCode; + + int LastOp; + +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + uint8_t* pFileTestBuffer; + unsigned FileTestLength; + unsigned TestPos; // File pointer position during tests. +#endif + + public: + FILEFile() + : FileName(), + Opened(false), + fs(NULL), + OpenFlags(0), + ErrorCode(0), + LastOp(0) +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + , + pFileTestBuffer(NULL), + FileTestLength(0), + TestPos(0) +#endif + { + } + + // Initialize file by opening it + FILEFile(const String& fileName, int flags, int Mode); + + // The 'pfileName' should be encoded as UTF-8 to support international file names. + FILEFile(const char* pfileName, int flags, int Mode); + + ~FILEFile() { + if (Opened) + Close(); + } + + virtual const char* GetFilePath(); + + // ** File Information + virtual bool IsValid(); + virtual bool IsWritable(); + + // Return position / file size + virtual int Tell(); + virtual int64_t LTell(); + virtual int GetLength(); + virtual int64_t LGetLength(); + + // virtual bool Stat(FileStats *pfs); + virtual int GetErrorCode(); + + // ** Stream implementation & I/O + virtual int Write(const uint8_t* pbuffer, int numBytes); + virtual int Read(uint8_t* pbuffer, int numBytes); + virtual int SkipBytes(int numBytes); + virtual int BytesAvailable(); + virtual bool Flush(); + virtual int Seek(int offset, int origin); + virtual int64_t LSeek(int64_t offset, int origin); + + virtual int CopyFromStream(File* pStream, int byteSize); + virtual bool Close(); + + private: + void init(); +}; + +// Initialize file by opening it +FILEFile::FILEFile(const String& fileName, int flags, int mode) + : FileName(fileName), OpenFlags(flags) { + OVR_UNUSED(mode); + init(); +} + +// The 'pfileName' should be encoded as UTF-8 to support international file names. +FILEFile::FILEFile(const char* pfileName, int flags, int mode) + : FileName(pfileName), OpenFlags(flags) { + OVR_UNUSED(mode); + init(); +} + +void FILEFile::init() { + // Open mode for file's open + const char* omode = "rb"; + + if (OpenFlags & Open_Truncate) { + if (OpenFlags & Open_Read) + omode = "w+b"; + else + omode = "wb"; + } else if (OpenFlags & Open_Create) { + if (OpenFlags & Open_Read) + omode = "a+b"; + else + omode = "ab"; + } else if (OpenFlags & Open_Write) + omode = "r+b"; + +#if defined(OVR_OS_MS) + SysErrorModeDisabler disabler(FileName.ToCStr()); +#endif + +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + wchar_t womode[16]; + auto fileNameLength = (size_t)UTF8Util::GetLength(FileName.ToCStr()) + 1; + wchar_t* pwFileName = (wchar_t*)OVR_ALLOC(fileNameLength * sizeof(pwFileName[0])); + auto requiredUTF8Length = OVR::UTF8Util::Strlcpy(pwFileName, fileNameLength, FileName.ToCStr()); + if (requiredUTF8Length < fileNameLength) { + requiredUTF8Length = OVR::UTF8Util::Strlcpy(womode, OVR_ARRAY_COUNT(womode), omode); + OVR_ASSERT(requiredUTF8Length < OVR_ARRAY_COUNT(womode)); + fs = _wfsopen( + pwFileName, womode, _SH_DENYWR); // Allow others to read the file when we are writing it. + } + OVR_FREE(pwFileName); +#else + fs = fopen(FileName.ToCStr(), omode); +#endif + if (fs) + rewind(fs); + Opened = (fs != NULL); + // Set error code + if (!Opened) + ErrorCode = SFerror(); + else { +// If we are testing file seek correctness, pre-load the entire file so +// that we can do comparison tests later. +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + TestPos = 0; + fseek(fs, 0, SEEK_END); + FileTestLength = ftell(fs); + fseek(fs, 0, SEEK_SET); + pFileTestBuffer = (uint8_t*)OVR_ALLOC(FileTestLength); + if (pFileTestBuffer) { + OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength)); + Seek(0, Seek_Set); + } +#endif + + ErrorCode = 0; + } + LastOp = 0; +} + +const char* FILEFile::GetFilePath() { + return FileName.ToCStr(); +} + +// ** File Information +bool FILEFile::IsValid() { + return Opened; +} +bool FILEFile::IsWritable() { + return IsValid() && (OpenFlags & Open_Write); +} +/* +bool FILEFile::IsRecoverable() +{ + return IsValid() && ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC); +} +*/ + +// Return position / file size +int FILEFile::Tell() { + int pos = (int)ftell(fs); + if (pos < 0) + ErrorCode = SFerror(); + return pos; +} + +int64_t FILEFile::LTell() { + int64_t pos = ftell(fs); + if (pos < 0) + ErrorCode = SFerror(); + return pos; +} + +int FILEFile::GetLength() { + int pos = Tell(); + if (pos >= 0) { + Seek(0, Seek_End); + int size = Tell(); + Seek(pos, Seek_Set); + return size; + } + return -1; +} +int64_t FILEFile::LGetLength() { + int64_t pos = LTell(); + if (pos >= 0) { + LSeek(0, Seek_End); + int64_t size = LTell(); + LSeek(pos, Seek_Set); + return size; + } + return -1; +} + +int FILEFile::GetErrorCode() { + return ErrorCode; +} + +// ** Stream implementation & I/O +int FILEFile::Write(const uint8_t* pbuffer, int numBytes) { + if (LastOp && LastOp != Open_Write) + fflush(fs); + LastOp = Open_Write; + int written = (int)fwrite(pbuffer, 1, numBytes, fs); + if (written < numBytes) + ErrorCode = SFerror(); + +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + if (written > 0) + TestPos += written; +#endif + + return written; +} + +int FILEFile::Read(uint8_t* pbuffer, int numBytes) { + if (LastOp && LastOp != Open_Read) + fflush(fs); + LastOp = Open_Read; + int read = (int)fread(pbuffer, 1, numBytes, fs); + if (read < numBytes) + ErrorCode = SFerror(); + +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + if (read > 0) { + // Read-in data must match our pre-loaded buffer data! + uint8_t* pcompareBuffer = pFileTestBuffer + TestPos; + for (int i = 0; i < read; i++) { + OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]); + } + + // OVR_ASSERT(!memcmp(pFileTestBuffer + TestPos, pbuffer, read)); + TestPos += read; + OVR_ASSERT(ftell(fs) == (int)TestPos); + } +#endif + + return read; +} + +// Seeks ahead to skip bytes +int FILEFile::SkipBytes(int numBytes) { + int64_t pos = LTell(); + int64_t newPos = LSeek(numBytes, Seek_Cur); + + // Return -1 for major error + if ((pos == -1) || (newPos == -1)) { + return -1; + } + // ErrorCode = ((NewPos-Pos) int(sizeof(buff))) ? int(sizeof(buff)) : byteSize; + + szRead = pstream->Read(buff, szRequest); + szWritten = 0; + if (szRead > 0) + szWritten = Write(buff, szRead); + + count += szWritten; + byteSize -= szWritten; + if (szWritten < szRequest) + break; + } + + delete[] buff; + + return count; +} + +bool FILEFile::Close() { +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + if (pFileTestBuffer) { + OVR_FREE(pFileTestBuffer); + pFileTestBuffer = 0; + FileTestLength = 0; + } +#endif + + bool closeRet = !fclose(fs); + + if (!closeRet) { + ErrorCode = SFerror(); + return 0; + } else { + Opened = 0; + fs = 0; + ErrorCode = 0; + } + + // Handle safe truncate + /* + if ((OpenFlags & OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) + { + // Delete original file (if it existed) + DWORD oldAttributes = FileUtilWin32::GetFileAttributes(FileName); + if (oldAttributes!=0xFFFFFFFF) + if (!FileUtilWin32::DeleteFile(FileName)) + { + // Try to remove the readonly attribute + FileUtilWin32::SetFileAttributes(FileName, oldAttributes & (~FILE_ATTRIBUTE_READONLY) + ); + // And delete the file again + if (!FileUtilWin32::DeleteFile(FileName)) + return 0; + } + + // Rename temp file to real filename + if (!FileUtilWin32::MoveFile(TempName, FileName)) + { + //ErrorCode = errno; + return 0; + } + } + */ + return 1; +} + +/* +bool FILEFile::CloseCancel() +{ + bool closeRet = (bool)::CloseHandle(fd); + + if (!closeRet) + { + //ErrorCode = errno; + return 0; + } + else + { + Opened = 0; + fd = INVALID_HANDLE_VALUE; + ErrorCode = 0; + } + + // Handle safe truncate (delete tmp file, leave original unchanged) + if ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) + if (!FileUtilWin32::DeleteFile(TempName)) + { + //ErrorCode = errno; + return 0; + } + return 1; +} +*/ + +Ptr FileFILEOpen(const String& path, int flags, int mode) { + Ptr result = *new FILEFile(path, flags, mode); + return result; +} + +// Helper function: obtain file information time. +bool SysFile::GetFileStat(FileStat* pfileStat, const String& path) { +#if defined(OVR_OS_MS) + // 64-bit implementation on Windows. + struct __stat64 fileStat {}; + auto pathLength = (size_t)UTF8Util::GetLength(path.ToCStr()) + 1; + wchar_t* pwPath = (wchar_t*)OVR_ALLOC(pathLength * sizeof(pwPath[0])); + auto requiredUTF8Length = OVR::UTF8Util::Strlcpy(pwPath, pathLength, path.ToCStr()); + int ret = -1; // Stat returns 0 for success. + if (requiredUTF8Length < pathLength) + ret = _wstat64(pwPath, &fileStat); + OVR_FREE(pwPath); + if (ret) + return false; +#else + struct stat fileStat {}; + // Stat returns 0 for success. + if (stat(path, &fileStat) != 0) + return false; +#endif + pfileStat->AccessTime = fileStat.st_atime; + pfileStat->ModifyTime = fileStat.st_mtime; + pfileStat->FileSize = fileStat.st_size; + return true; +} + +} // Namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Hash.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Hash.h new file mode 100644 index 0000000..7f0f38d --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Hash.h @@ -0,0 +1,1261 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_Hash.h +Content : Template hash-table/set implementation +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Hash_h +#define OVR_Hash_h + +#include "OVR_Alg.h" +#include "OVR_ContainerAllocator.h" + +// 'new' operator is redefined/used in this file. +#undef new + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** Hash Table Implementation + +// HastSet and Hash. +// +// Hash table, linear probing, internal chaining. One interesting/nice thing +// about this implementation is that the table itself is a flat chunk of memory +// containing no pointers, only relative indices. If the key and value types +// of the Hash contain no pointers, then the Hash can be serialized using raw IO. +// +// Never shrinks, unless you explicitly Clear() it. Expands on +// demand, though. For best results, if you know roughly how big your +// table will be, default it to that size when you create it. +// +// Key usability feature: +// +// 1. Allows node hash values to either be cached or not. +// +// 2. Allows for alternative keys with methods such as GetAlt(). Handy +// if you need to search nodes by their components; no need to create +// temporary nodes. +// + +// *** Hash functors: +// +// IdentityHash - use when the key is already a good hash +// HFixedSizeHash - general hash based on object's in-memory representation. + +// Hash is just the input value; can use this for integer-indexed hash tables. +template +class IdentityHash { + public: + size_t operator()(const C& data) const { + return (size_t)data; + } +}; + +// Computes a hash of an object's representation. +template +class FixedSizeHash { + public: + // Alternative: "sdbm" hash function, suggested at same web page + // above, http::/www.cs.yorku.ca/~oz/hash.html + // This is somewhat slower then Bernstein, but it works way better than the above + // hash function for hashing large numbers of 32-bit ints. + static OVR_FORCE_INLINE size_t SDBM_Hash(const void* data_in, size_t size, size_t seed = 5381) { + const uint8_t* data = (const uint8_t*)data_in; + size_t h = seed; + while (size > 0) { + --size; +#ifndef __clang_analyzer__ // It mistakenly thinks data is garbage. + h = (h << 16) + (h << 6) - h + (size_t)data[size]; +#endif + } + return h; + } + + size_t operator()(const C& data) const { + const unsigned char* p = (const unsigned char*)&data; + const size_t size = sizeof(C); + + return SDBM_Hash(p, size); + } +}; + +// *** HashsetEntry Entry types. + +// Compact hash table Entry type that re-computes hash keys during hash traversal. +// Good to use if the hash function is cheap or the hash value is already cached in C. +template +class HashsetEntry { + public: + // Internal chaining for collisions. + intptr_t NextInChain; + C Value; + + HashsetEntry() : NextInChain(-2) {} + HashsetEntry(const HashsetEntry& e) : NextInChain(e.NextInChain), Value(e.Value) {} + HashsetEntry(const C& key, intptr_t next) : NextInChain(next), Value(key) {} + + bool IsEmpty() const { + return NextInChain == -2; + } + bool IsEndOfChain() const { + return NextInChain == -1; + } + + // Cached hash value access - can be optimized bu storing hash locally. + // Mask value only needs to be used if SetCachedHash is not implemented. + size_t GetCachedHash(size_t maskValue) const { + return HashF()(Value) & maskValue; + } + void SetCachedHash(size_t) {} + + void Clear() { + Value.~C(); // placement delete + NextInChain = -2; + } + // Free is only used from dtor of hash; Clear is used during regular operations: + // assignment, hash reallocations, value reassignments, so on. + void Free() { + Clear(); + } +}; + +// Hash table Entry type that caches the Entry hash value for nodes, so that it +// does not need to be re-computed during access. +template +class HashsetCachedEntry { + public: + // Internal chaining for collisions. + intptr_t NextInChain; + size_t HashValue; + C Value; + + HashsetCachedEntry() : NextInChain(-2) {} + HashsetCachedEntry(const HashsetCachedEntry& e) + : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) {} + HashsetCachedEntry(const C& key, intptr_t next) : NextInChain(next), Value(key) {} + + bool IsEmpty() const { + return NextInChain == -2; + } + bool IsEndOfChain() const { + return NextInChain == -1; + } + + // Cached hash value access - can be optimized bu storing hash locally. + // Mask value only needs to be used if SetCachedHash is not implemented. + size_t GetCachedHash(size_t maskValue) const { + OVR_UNUSED(maskValue); + return HashValue; + } + void SetCachedHash(size_t hashValue) { + HashValue = hashValue; + } + + void Clear() { + Value.~C(); + NextInChain = -2; + } + // Free is only used from dtor of hash; Clear is used during regular operations: + // assignment, hash reallocations, value reassignments, so on. + void Free() { + Clear(); + } +}; + +//----------------------------------------------------------------------------------- +// *** HashSet implementation - relies on either cached or regular entries. +// +// Use: Entry = HashsetCachedEntry if hashes are expensive to +// compute and thus need caching in entries. +// Entry = HashsetEntry if hashes are already externally cached. +// +template < + class C, + class HashF = FixedSizeHash, + class AltHashF = HashF, + class Allocator = ContainerAllocator, + class Entry = HashsetCachedEntry> +class HashSetBase { + enum { HashMinSize = 8 }; + + public: + OVR_MEMORY_REDEFINE_NEW(HashSetBase) + + typedef HashSetBase SelfType; + + HashSetBase() : pTable(NULL) {} + HashSetBase(int sizeHint) : pTable(NULL) { + SetCapacity(sizeHint); + } + HashSetBase(const SelfType& src) : pTable(NULL) { + Assign(src); + } + + ~HashSetBase() { + if (pTable) { + // Delete the entries. + for (size_t i = 0, n = pTable->SizeMask; i <= n; i++) { + Entry* e = &E(i); + if (!e->IsEmpty()) + e->Free(); + } + + Allocator::Free(pTable); + pTable = NULL; + } + } + + void Assign(const SelfType& src) { + Clear(); + if (src.IsEmpty() == false) { + SetCapacity(src.GetSize()); + + for (ConstIterator it = src.Begin(); it != src.End(); ++it) { + Add(*it); + } + } + } + + // Remove all entries from the HashSet table. + void Clear() { + if (pTable) { + // Delete the entries. + for (size_t i = 0, n = pTable->SizeMask; i <= n; i++) { + Entry* e = &E(i); + if (!e->IsEmpty()) + e->Clear(); + } + + Allocator::Free(pTable); + pTable = NULL; + } + } + + // Returns true if the HashSet is empty. + bool IsEmpty() const { + return pTable == NULL || pTable->EntryCount == 0; + } + + // Set a new or existing value under the key, to the value. + // Pass a different class of 'key' so that assignment reference object + // can be passed instead of the actual object. + template + void Set(const CRef& key) { + size_t hashValue = HashF()(key); + intptr_t index = (intptr_t)-1; + + if (pTable != NULL) + index = findIndexCore(key, hashValue & pTable->SizeMask); + + if (index >= 0) { + E(index).Value = key; + } else { + // Entry under key doesn't exist. + add(key, hashValue); + } + } + + template + inline void Add(const CRef& key) { + size_t hashValue = HashF()(key); + add(key, hashValue); + } + + // Remove by alternative key. + template + void RemoveAlt(const K& key) { + if (pTable == NULL) + return; + + size_t hashValue = AltHashF()(key); + intptr_t index = hashValue & pTable->SizeMask; + + Entry* e = &E(index); + + // If empty node or occupied by collider, we have nothing to remove. + if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != (size_t)index)) + return; + + // Save index + intptr_t naturalIndex = index; + intptr_t prevIndex = -1; + + while ((e->GetCachedHash(pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key)) { + // Keep looking through the chain. + prevIndex = index; + index = e->NextInChain; + if (index == -1) + return; // End of chain, item not found + e = &E(index); + } + + // Found it - our item is at index + if (naturalIndex == index) { + // If we have a follower, move it to us + if (!e->IsEndOfChain()) { + Entry* enext = &E(e->NextInChain); + e->Clear(); + new (e) Entry(*enext); + // Point us to the follower's cell that will be cleared + e = enext; + } + } else { + // We are not at natural index, so deal with the prev items next index + E(prevIndex).NextInChain = e->NextInChain; + } + + // Clear us, of the follower cell that was moved. + e->Clear(); + pTable->EntryCount--; + // Should we check the size to condense hash? ... + } + + // Remove by main key. + template + void Remove(const CRef& key) { + RemoveAlt(key); + } + + // Retrieve the pointer to a value under the given key. + // - If there's no value under the key, then return NULL. + // - If there is a value, return the pointer. + template + C* Get(const K& key) { + intptr_t index = findIndex(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + template + const C* Get(const K& key) const { + intptr_t index = findIndex(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + // Alternative key versions of Get. Used by Hash. + template + const C* GetAlt(const K& key) const { + intptr_t index = findIndexAlt(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + template + C* GetAlt(const K& key) { + intptr_t index = findIndexAlt(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + template + bool GetAlt(const K& key, C* pval) const { + intptr_t index = findIndexAlt(key); + if (index >= 0) { + if (pval) + *pval = E(index).Value; + return true; + } + return false; + } + + size_t GetSize() const { + return pTable == NULL ? 0 : (size_t)pTable->EntryCount; + } + int GetSizeI() const { + return (int)GetSize(); + } + + // Resize the HashSet table to fit one more Entry. Often this + // doesn't involve any action. + void CheckExpand() { + if (pTable == NULL) { + // Initial creation of table. Make a minimum-sized table. + setRawCapacity(HashMinSize); + } else if (pTable->EntryCount * 5 > (pTable->SizeMask + 1) * 4) { + // pTable is more than 5/4 ths full. Expand. + setRawCapacity((pTable->SizeMask + 1) * 2); + } + } + + // Hint the bucket count to >= n. + void Resize(size_t n) { + // Not really sure what this means in relation to + // STLport's hash_map... they say they "increase the + // bucket count to at least n" -- but does that mean + // their real capacity after Resize(n) is more like + // n*2 (since they do linked-list chaining within + // buckets?). + SetCapacity(n); + } + + // Size the HashSet so that it can comfortably contain the given + // number of elements. If the HashSet already contains more + // elements than newSize, then this may be a no-op. + void SetCapacity(size_t newSize) { + size_t newRawSize = (newSize * 5) / 4; + if (newRawSize <= GetSize()) + return; + setRawCapacity(newRawSize); + } + +// Disable inappropriate 'operator ->' warning on MSVC6. +#ifdef OVR_CC_MSVC +#if (OVR_CC_MSVC < 1300) +#pragma warning(disable : 4284) +#endif +#endif + + // Iterator API, like STL. + struct ConstIterator { + const C& operator*() const { + OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask); + return pHash->E(Index).Value; + } + + const C* operator->() const { + OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask); + return &pHash->E(Index).Value; + } + + void operator++() { + // Find next non-empty Entry. + if (Index <= (intptr_t)pHash->pTable->SizeMask) { + Index++; + while ((size_t)Index <= pHash->pTable->SizeMask && pHash->E(Index).IsEmpty()) { + Index++; + } + } + } + + bool operator==(const ConstIterator& it) const { + if (IsEnd() && it.IsEnd()) { + return true; + } else { + return (pHash == it.pHash) && (Index == it.Index); + } + } + + bool operator!=(const ConstIterator& it) const { + return !(*this == it); + } + + bool IsEnd() const { + return (pHash == NULL) || (pHash->pTable == NULL) || + (Index > (intptr_t)pHash->pTable->SizeMask); + } + + ConstIterator() : pHash(NULL), Index(0) {} + + public: + // Constructor was intentionally made public to allow create + // iterator with arbitrary index. + ConstIterator(const SelfType* h, intptr_t index) : pHash(h), Index(index) {} + + const SelfType* GetContainer() const { + return pHash; + } + intptr_t GetIndex() const { + return Index; + } + + protected: + friend class HashSetBase; + + const SelfType* pHash; + intptr_t Index; + }; + + friend struct ConstIterator; + + // Non-const Iterator; Get most of it from ConstIterator. + struct Iterator : public ConstIterator { + // Allow non-const access to entries. + C& operator*() const { + OVR_ASSERT( + (ConstIterator::pHash) && ConstIterator::pHash->pTable && (ConstIterator::Index >= 0) && + (ConstIterator::Index <= (intptr_t)ConstIterator::pHash->pTable->SizeMask)); + return const_cast(ConstIterator::pHash)->E(ConstIterator::Index).Value; + } + + C* operator->() const { + return &(operator*()); + } + + Iterator() : ConstIterator(NULL, 0) {} + + // Removes current element from Hash + void Remove() { + RemoveAlt(operator*()); + } + + template + void RemoveAlt(const K& key) { + SelfType* phash = const_cast(ConstIterator::pHash); + // Entry* ee = &phash->E(ConstIterator::Index); + // const C& key = ee->Value; + + size_t hashValue = AltHashF()(key); + intptr_t index = hashValue & phash->pTable->SizeMask; + + Entry* e = &phash->E(index); + + // If empty node or occupied by collider, we have nothing to remove. + if (e->IsEmpty() || (e->GetCachedHash(phash->pTable->SizeMask) != (size_t)index)) + return; + + // Save index + intptr_t naturalIndex = index; + intptr_t prevIndex = -1; + + while ((e->GetCachedHash(phash->pTable->SizeMask) != (size_t)naturalIndex) || + !(e->Value == key)) { + // Keep looking through the chain. + prevIndex = index; + index = e->NextInChain; + if (index == -1) + return; // End of chain, item not found + e = &phash->E(index); + } + + if (index == (intptr_t)ConstIterator::Index) { + // Found it - our item is at index + if (naturalIndex == index) { + // If we have a follower, move it to us + if (!e->IsEndOfChain()) { + Entry* enext = &phash->E(e->NextInChain); + e->Clear(); + new (e) Entry(*enext); + // Point us to the follower's cell that will be cleared + e = enext; + --ConstIterator::Index; + } + } else { + // We are not at natural index, so deal with the prev items next index + phash->E(prevIndex).NextInChain = e->NextInChain; + } + + // Clear us, of the follower cell that was moved. + e->Clear(); + phash->pTable->EntryCount--; + } else + OVR_ASSERT(0); //? + } + + private: + friend class HashSetBase; + + Iterator(SelfType* h, intptr_t i0) : ConstIterator(h, i0) {} + }; + + friend struct Iterator; + + Iterator Begin() { + if (pTable == 0) + return Iterator(NULL, 0); + + // Scan till we hit the First valid Entry. + size_t i0 = 0; + while (i0 <= pTable->SizeMask && E(i0).IsEmpty()) { + i0++; + } + return Iterator(this, i0); + } + Iterator End() { + return Iterator(NULL, 0); + } + + ConstIterator Begin() const { + return const_cast(this)->Begin(); + } + ConstIterator End() const { + return const_cast(this)->End(); + } + + template + Iterator Find(const K& key) { + intptr_t index = findIndex(key); + if (index >= 0) + return Iterator(this, index); + return Iterator(NULL, 0); + } + + template + Iterator FindAlt(const K& key) { + intptr_t index = findIndexAlt(key); + if (index >= 0) + return Iterator(this, index); + return Iterator(NULL, 0); + } + + template + ConstIterator Find(const K& key) const { + return const_cast(this)->Find(key); + } + + template + ConstIterator FindAlt(const K& key) const { + return const_cast(this)->FindAlt(key); + } + + private: + // Find the index of the matching Entry. If no match, then return -1. + template + intptr_t findIndex(const K& key) const { + if (pTable == NULL) + return -1; + size_t hashValue = HashF()(key) & pTable->SizeMask; + return findIndexCore(key, hashValue); + } + + template + intptr_t findIndexAlt(const K& key) const { + if (pTable == NULL) + return -1; + size_t hashValue = AltHashF()(key) & pTable->SizeMask; + return findIndexCore(key, hashValue); + } + + // Find the index of the matching Entry. If no match, then return -1. + template + intptr_t findIndexCore(const K& key, size_t hashValue) const { + // Table must exist. + OVR_ASSERT(pTable != 0); + // Hash key must be 'and-ed' by the caller. + OVR_ASSERT((hashValue & ~pTable->SizeMask) == 0); + + size_t index = hashValue; + const Entry* e = &E(index); + + // If empty or occupied by a collider, not found. + if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != index)) + return -1; + + while (1) { + OVR_ASSERT(e->GetCachedHash(pTable->SizeMask) == hashValue); + + if (e->GetCachedHash(pTable->SizeMask) == hashValue && e->Value == key) { + // Found it. + return index; + } + // Values can not be equal at this point. + // That would mean that the hash key for the same value differs. + OVR_ASSERT(!(e->Value == key)); + + // Keep looking through the chain. + index = e->NextInChain; + if (index == (size_t)-1) + break; // end of chain + + e = &E(index); + OVR_ASSERT(!e->IsEmpty()); + } + return -1; + } + + // Add a new value to the HashSet table, under the specified key. + template + void add(const CRef& key, size_t hashValue) { + CheckExpand(); + hashValue &= pTable->SizeMask; + + pTable->EntryCount++; + + intptr_t index = hashValue; + Entry* naturalEntry = &(E(index)); + + if (naturalEntry->IsEmpty()) { + // Put the new Entry in. + new (naturalEntry) Entry(key, -1); + } else { + // Find a blank spot. + intptr_t blankIndex = index; + do { + blankIndex = (blankIndex + 1) & pTable->SizeMask; + } while (!E(blankIndex).IsEmpty()); + + Entry* blankEntry = &E(blankIndex); + + if (naturalEntry->GetCachedHash(pTable->SizeMask) == (size_t)index) { + // Collision. Link into this chain. + + // Move existing list head. + new (blankEntry) Entry(*naturalEntry); // placement new, copy ctor + + // Put the new info in the natural Entry. + naturalEntry->Value = key; + naturalEntry->NextInChain = blankIndex; + } else { + // Existing Entry does not naturally + // belong in this slot. Existing + // Entry must be moved. + + // Find natural location of collided element (i.e. root of chain) + intptr_t collidedIndex = naturalEntry->GetCachedHash(pTable->SizeMask); + OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask); + for (;;) { + Entry* e = &E(collidedIndex); + if (e->NextInChain == index) { + // Here's where we need to splice. + new (blankEntry) Entry(*naturalEntry); + e->NextInChain = blankIndex; + break; + } + collidedIndex = e->NextInChain; + OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask); + } + + // Put the new data in the natural Entry. + naturalEntry->Value = key; + naturalEntry->NextInChain = -1; + } + } + + // Record hash value: has effect only if cached node is used. + naturalEntry->SetCachedHash(hashValue); + } + + // Index access helpers. + Entry& E(size_t index) { + // Must have pTable and access needs to be within bounds. + OVR_ASSERT(index <= pTable->SizeMask); + return *(((Entry*)(pTable + 1)) + index); + } + const Entry& E(size_t index) const { + OVR_ASSERT(index <= pTable->SizeMask); + return *(((Entry*)(pTable + 1)) + index); + } + + // Resize the HashSet table to the given size (Rehash the + // contents of the current table). The arg is the number of + // HashSet table entries, not the number of elements we should + // actually contain (which will be less than this). + void setRawCapacity(size_t newSize) { + if (newSize == 0) { + // Special case. + Clear(); + return; + } + + // Minimum size; don't incur rehashing cost when expanding + // very small tables. Not that we perform this check before + // 'log2f' call to avoid fp exception with newSize == 1. + if (newSize < HashMinSize) + newSize = HashMinSize; + else { + // Force newSize to be a power of two. + int bits = Alg::UpperBit(newSize - 1) + 1; // Chop( Log2f((float)(newSize-1)) + 1); + OVR_ASSERT((size_t(1) << bits) >= newSize); + newSize = size_t(1) << bits; + } + + SelfType newHash; + newHash.pTable = (TableType*)Allocator::Alloc(sizeof(TableType) + sizeof(Entry) * newSize); + // Need to do something on alloc failure! + OVR_ASSERT(newHash.pTable); + + newHash.pTable->EntryCount = 0; + newHash.pTable->SizeMask = newSize - 1; + size_t i, n; + + // Mark all entries as empty. + for (i = 0; i < newSize; i++) + newHash.E(i).NextInChain = -2; + + // Copy stuff to newHash + if (pTable) { + for (i = 0, n = pTable->SizeMask; i <= n; i++) { + Entry* e = &E(i); + if (e->IsEmpty() == false) { + // Insert old Entry into new HashSet. + newHash.Add(e->Value); + // placement delete of old element + e->Clear(); + } + } + + // Delete our old data buffer. + Allocator::Free(pTable); + } + + // Steal newHash's data. + pTable = newHash.pTable; + newHash.pTable = NULL; + } + + struct TableType { + size_t EntryCount; + size_t SizeMask; + // Entry array follows this structure + // in memory. + }; + TableType* pTable; +}; + +//----------------------------------------------------------------------------------- +template < + class C, + class HashF = FixedSizeHash, + class AltHashF = HashF, + class Allocator = ContainerAllocator, + class Entry = HashsetCachedEntry> +class HashSet : public HashSetBase { + public: + typedef HashSetBase BaseType; + typedef HashSet SelfType; + + HashSet() {} + HashSet(int sizeHint) : BaseType(sizeHint) {} + HashSet(const SelfType& src) : BaseType(src) {} + ~HashSet() {} + + void operator=(const SelfType& src) { + BaseType::Assign(src); + } + + // Set a new or existing value under the key, to the value. + // Pass a different class of 'key' so that assignment reference object + // can be passed instead of the actual object. + template + void Set(const CRef& key) { + BaseType::Set(key); + } + + template + inline void Add(const CRef& key) { + BaseType::Add(key); + } + + // Hint the bucket count to >= n. + void Resize(size_t n) { + BaseType::SetCapacity(n); + } + + // Size the HashSet so that it can comfortably contain the given + // number of elements. If the HashSet already contains more + // elements than newSize, then this may be a no-op. + void SetCapacity(size_t newSize) { + BaseType::SetCapacity(newSize); + } +}; + +// HashSet with uncached hash code; declared for convenience. +template < + class C, + class HashF = FixedSizeHash, + class AltHashF = HashF, + class Allocator = ContainerAllocator> +class HashSetUncached : public HashSet> { + public: + typedef HashSetUncached SelfType; + typedef HashSet> BaseType; + + // Delegated constructors. + HashSetUncached() {} + HashSetUncached(int sizeHint) : BaseType(sizeHint) {} + HashSetUncached(const SelfType& src) : BaseType(src) {} + ~HashSetUncached() {} + + void operator=(const SelfType& src) { + BaseType::operator=(src); + } +}; + +//----------------------------------------------------------------------------------- +// ***** Hash hash table implementation + +// Node for Hash - necessary so that Hash can delegate its implementation +// to HashSet. +template +struct HashNode { + typedef HashNode SelfType; + typedef C FirstType; + typedef U SecondType; + + C First; + U Second; + + // NodeRef is used to allow passing of elements into HashSet + // without using a temporary object. + struct NodeRef { + const C* pFirst; + const U* pSecond; + + NodeRef(const C& f, const U& s) : pFirst(&f), pSecond(&s) {} + NodeRef(const NodeRef& src) : pFirst(src.pFirst), pSecond(src.pSecond) {} + + // Enable computation of ghash_node_hashf. + inline size_t GetHash() const { + return HashF()(*pFirst); + } + // Necessary conversion to allow HashNode::operator == to work. + operator const C&() const { + return *pFirst; + } + }; + + // Note: No default constructor is necessary. + HashNode(const HashNode& src) : First(src.First), Second(src.Second) {} + HashNode(const NodeRef& src) : First(*src.pFirst), Second(*src.pSecond) {} + void operator=(const NodeRef& src) { + First = *src.pFirst; + Second = *src.pSecond; + } + + template + bool operator==(const K& src) const { + return (First == src); + } + + template + static size_t CalcHash(const K& data) { + return HashF()(data); + } + inline size_t GetHash() const { + return HashF()(First); + } + + // Hash functors used with this node. A separate functor is used for alternative + // key lookup so that it does not need to access the '.First' element. + struct NodeHashF { + template + size_t operator()(const K& data) const { + return data.GetHash(); + } + }; + struct NodeAltHashF { + template + size_t operator()(const K& data) const { + return HashNode::CalcHash(data); + } + }; +}; + +// **** Extra hashset_entry types to allow NodeRef construction. + +// The big difference between the below types and the ones used in hash_set is that +// these allow initializing the node with 'typename C::NodeRef& keyRef', which +// is critical to avoid temporary node allocation on stack when using placement new. + +// Compact hash table Entry type that re-computes hash keys during hash traversal. +// Good to use if the hash function is cheap or the hash value is already cached in C. +template +class HashsetNodeEntry { + public: + // Internal chaining for collisions. + intptr_t NextInChain; + C Value; + + HashsetNodeEntry() : NextInChain(-2) {} + HashsetNodeEntry(const HashsetNodeEntry& e) : NextInChain(e.NextInChain), Value(e.Value) {} + HashsetNodeEntry(const C& key, intptr_t next) : NextInChain(next), Value(key) {} + HashsetNodeEntry(const typename C::NodeRef& keyRef, intptr_t next) + : NextInChain(next), Value(keyRef) {} + + bool IsEmpty() const { + return NextInChain == -2; + } + bool IsEndOfChain() const { + return NextInChain == -1; + } + size_t GetCachedHash(size_t maskValue) const { + return HashF()(Value) & maskValue; + } + void SetCachedHash(size_t hashValue) { + OVR_UNUSED(hashValue); + } + + void Clear() { + Value.~C(); // placement delete + NextInChain = -2; + } + // Free is only used from dtor of hash; Clear is used during regular operations: + // assignment, hash reallocations, value reassignments, so on. + void Free() { + Clear(); + } +}; + +// Hash table Entry type that caches the Entry hash value for nodes, so that it +// does not need to be re-computed during access. +template +class HashsetCachedNodeEntry { + public: + // Internal chaining for collisions. + intptr_t NextInChain; + size_t HashValue; + C Value; + + HashsetCachedNodeEntry() : NextInChain(-2) {} + HashsetCachedNodeEntry(const HashsetCachedNodeEntry& e) + : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) {} + HashsetCachedNodeEntry(const C& key, intptr_t next) : NextInChain(next), Value(key) {} + HashsetCachedNodeEntry(const typename C::NodeRef& keyRef, intptr_t next) + : NextInChain(next), Value(keyRef) {} + + bool IsEmpty() const { + return NextInChain == -2; + } + bool IsEndOfChain() const { + return NextInChain == -1; + } + size_t GetCachedHash(size_t maskValue) const { + OVR_UNUSED(maskValue); + return HashValue; + } + void SetCachedHash(size_t hashValue) { + HashValue = hashValue; + } + + void Clear() { + Value.~C(); + NextInChain = -2; + } + // Free is only used from dtor of hash; Clear is used during regular operations: + // assignment, hash reallocations, value reassignments, so on. + void Free() { + Clear(); + } +}; + +//----------------------------------------------------------------------------------- +template < + class C, + class U, + class HashF = FixedSizeHash, + class Allocator = ContainerAllocator, + class HashNode = OVR::HashNode, + class Entry = HashsetCachedNodeEntry, + class Container = HashSet< + HashNode, + typename HashNode::NodeHashF, + typename HashNode::NodeAltHashF, + Allocator, + Entry>> +class Hash { + public: + OVR_MEMORY_REDEFINE_NEW(Hash) + + // Types used for hash_set. + typedef U ValueType; + typedef Hash SelfType; + + // Actual hash table itself, implemented as hash_set. + Container mHash; + + public: + Hash() {} + Hash(int sizeHint) : mHash(sizeHint) {} + Hash(const SelfType& src) : mHash(src.mHash) {} + ~Hash() {} + + void operator=(const SelfType& src) { + mHash = src.mHash; + } + + // Remove all entries from the Hash table. + inline void Clear() { + mHash.Clear(); + } + // Returns true if the Hash is empty. + inline bool IsEmpty() const { + return mHash.IsEmpty(); + } + + // Access (set). + inline void Set(const C& key, const U& value) { + typename HashNode::NodeRef e(key, value); + mHash.Set(e); + } + inline void Add(const C& key, const U& value) { + typename HashNode::NodeRef e(key, value); + mHash.Add(e); + } + + // Removes an element by clearing its Entry. + inline void Remove(const C& key) { + mHash.RemoveAlt(key); + } + template + inline void RemoveAlt(const K& key) { + mHash.RemoveAlt(key); + } + + // Retrieve the value under the given key. + // - If there's no value under the key, then return false and leave *pvalue alone. + // - If there is a value, return true, and Set *Pvalue to the Entry's value. + // - If value == NULL, return true or false according to the presence of the key. + bool Get(const C& key, U* pvalue) const { + const HashNode* p = mHash.GetAlt(key); + if (p) { + if (pvalue) + *pvalue = p->Second; + return true; + } + return false; + } + + template + bool GetAlt(const K& key, U* pvalue) const { + const HashNode* p = mHash.GetAlt(key); + if (p) { + if (pvalue) + *pvalue = p->Second; + return true; + } + return false; + } + + // Retrieve the pointer to a value under the given key. + // - If there's no value under the key, then return NULL. + // - If there is a value, return the pointer. + inline U* Get(const C& key) { + HashNode* p = mHash.GetAlt(key); + return p ? &p->Second : 0; + } + inline const U* Get(const C& key) const { + const HashNode* p = mHash.GetAlt(key); + return p ? &p->Second : 0; + } + + template + inline U* GetAlt(const K& key) { + HashNode* p = mHash.GetAlt(key); + return p ? &p->Second : 0; + } + template + inline const U* GetAlt(const K& key) const { + const HashNode* p = mHash.GetAlt(key); + return p ? &p->Second : 0; + } + + // Sizing methods - delegate to Hash. + inline size_t GetSize() const { + return mHash.GetSize(); + } + inline int GetSizeI() const { + return (int)GetSize(); + } + inline void Resize(size_t n) { + mHash.Resize(n); + } + inline void SetCapacity(size_t newSize) { + mHash.SetCapacity(newSize); + } + + // Iterator API, like STL. + typedef typename Container::ConstIterator ConstIterator; + typedef typename Container::Iterator Iterator; + + inline Iterator Begin() { + return mHash.Begin(); + } + inline Iterator End() { + return mHash.End(); + } + inline ConstIterator Begin() const { + return mHash.Begin(); + } + inline ConstIterator End() const { + return mHash.End(); + } + + Iterator Find(const C& key) { + return mHash.FindAlt(key); + } + ConstIterator Find(const C& key) const { + return mHash.FindAlt(key); + } + + template + Iterator FindAlt(const K& key) { + return mHash.FindAlt(key); + } + template + ConstIterator FindAlt(const K& key) const { + return mHash.FindAlt(key); + } +}; + +// Hash with uncached hash code; declared for convenience. +template , class Allocator = ContainerAllocator> +class HashUncached + : public Hash< + C, + U, + HashF, + Allocator, + HashNode, + HashsetNodeEntry, typename HashNode::NodeHashF>> { + public: + typedef HashUncached SelfType; + typedef Hash< + C, + U, + HashF, + Allocator, + HashNode, + HashsetNodeEntry, typename HashNode::NodeHashF>> + BaseType; + + // Delegated constructors. + HashUncached() {} + HashUncached(int sizeHint) : BaseType(sizeHint) {} + HashUncached(const SelfType& src) : BaseType(src) {} + ~HashUncached() {} + void operator=(const SelfType& src) { + BaseType::operator=(src); + } +}; + +// And identity hash in which keys serve as hash value. Can be uncached, +// since hash computation is assumed cheap. +template , class HashF = IdentityHash> +class HashIdentity : public HashUncached { + public: + typedef HashIdentity SelfType; + typedef HashUncached BaseType; + + // Delegated constructors. + HashIdentity() {} + HashIdentity(int sizeHint) : BaseType(sizeHint) {} + HashIdentity(const SelfType& src) : BaseType(src) {} + ~HashIdentity() {} + void operator=(const SelfType& src) { + BaseType::operator=(src); + } +}; + +} // namespace OVR + +#ifdef OVR_DEFINE_NEW +#define new OVR_DEFINE_NEW +#endif + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_JSON.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_JSON.cpp new file mode 100644 index 0000000..b52b75f --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_JSON.cpp @@ -0,0 +1,1202 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_JSON.h +Content : JSON format reader and writer +Created : April 9, 2013 +Author : Brant Lewis +Notes : + The code is a derivative of the cJSON library written by Dave Gamble and subject + to the following permissive copyright. + + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_JSON.h" +#include +#include +#include +#include +#include +#include +#include +#include "OVR_SysFile.h" + +namespace OVR { + +//----------------------------------------------------------------------------- +// Create a new copy of a string +static char* JSON_strdup(const char* str) { + size_t len = OVR_strlen(str) + 1; + char* copy = (char*)OVR_ALLOC(len); + if (!copy) + return 0; + memcpy(copy, str, len); + return copy; +} + +//----------------------------------------------------------------------------- +// Render the number from the given item into a string. +static char* PrintInt(int valueint) { + char* str; + str = (char*)OVR_ALLOC(21); // 2^64+1 can be represented in 21 chars. + if (str) { + snprintf(str, 21, "%d", valueint); + } + return str; +} + +//----------------------------------------------------------------------------- +// Render the number from the given item into a string. +static char* PrintNumber(double d) { + char* str; + int valueint = (int)d; + + if ((fabs(((double)valueint) - d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN)) { + return PrintInt(valueint); + } else { + const size_t kCapacity = 64; + + str = (char*)OVR_ALLOC(kCapacity); // This is a nice tradeoff. + if (str) { + // The JSON Standard, section 7.8.3, specifies that decimals are always expressed with '.' and + // not some locale-specific decimal such as ',' or ' '. However, since we are using the C + // standard + // library below to write a floating point number, we need to make sure that it's writing a + // '.' + // and not something else. We can't change the locale (even temporarily) here, as it will + // affect + // the whole process by default. That are compiler-specific ways to change this per-thread, + // but + // below we implement the simple solution of simply fixing the decimal after the string was + // written. + + if ((fabs(floor(d) - d) <= DBL_EPSILON) && (fabs(d) < 1.0e60)) { + // Write integral values with no decimals + snprintf(str, kCapacity, "%.0f", d); + } else if ((fabs(d) < 1.0) || (fabs(d) > 1.0e9)) { + // Write numbers < 1 or larger than 1e9 with 7 significant digits + snprintf(str, kCapacity, "%.7g", d); + } else { + // Write numbers >= 1 and <= 1e9 with 6 decimals (7 to 15 sig digits) + snprintf(str, kCapacity, "%.6f", d); + } + + // Convert any found ',' or ''' char to '.'. This will happen only if the locale was set to + // write a ',' + // instead of a '.' for the decimal point. Decimal points are represented only by one of these + // three characters in practice. + for (char* p = str; *p; p++) { + if ((*p == ',') || (*p == '\'')) { + *p = '.'; + break; + } + } + } + } + return str; +} + +// Parse the input text into an un-escaped cstring, and populate item. +static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC}; + +// Helper to assign error sting and return 0. +const char* AssignError(const char** perror, const char* errorMessage) { + if (perror) + *perror = errorMessage; + return 0; +} + +//----------------------------------------------------------------------------- +// ***** JSON Node class + +JSON::JSON(JSONItemType itemType) : Type(itemType), dValue(0.) {} + +JSON::~JSON() { + JSON* child = Children.GetFirst(); + while (!Children.IsNull(child)) { + child->RemoveNode(); + child->Release(); + child = Children.GetFirst(); + } +} + +//----------------------------------------------------------------------------- +// Parse the input text to generate a number, and populate the result into item +// Returns the text position after the parsed number +const char* JSON::parseNumber(const char* num) { + const char* num_start = num; + double n = 0, scale = 0; + int subscale = 0, signsubscale = 1; + bool positiveSign = true; + const char decimalSeparator = + '.'; // The JSON standard specifies that numbers use '.' regardless of locale. + + // Could use sscanf for this? + if (*num == '-') { + positiveSign = false; + num++; // Has sign? + } + if (*num == '0') { + num++; // is zero + } + + if (*num >= '1' && *num <= '9') { + do { + n = (n * 10.0) + (*num++ - '0'); + } while (*num >= '0' && *num <= '9'); // Number? + } + + if ((*num == '.' || *num == decimalSeparator) && num[1] >= '0' && num[1] <= '9') { + num++; + do { + n = (n * 10.0) + (*num++ - '0'); + scale--; + } while (*num >= '0' && *num <= '9'); // Fractional part? + } + + if (*num == 'e' || *num == 'E') // Exponent? + { + num++; + if (*num == '+') { + num++; + } else if (*num == '-') { + signsubscale = -1; + num++; // With sign? + } + + while (*num >= '0' && *num <= '9') { + subscale = (subscale * 10) + (*num++ - '0'); // Number? + } + } + + // Number = +/- number.fraction * 10^+/- exponent + n *= pow(10.0, (scale + subscale * signsubscale)); + + if (!positiveSign) { + n = -n; + } + + // Assign parsed value. + Type = JSON_Number; + dValue = n; + Value.AssignString(num_start, num - num_start); + + return num; +} + +// Parses a hex string up to the specified number of digits. +// Returns the first character after the string. +const char* ParseHex(unsigned* val, unsigned digits, const char* str) { + *val = 0; + + for (unsigned digitCount = 0; digitCount < digits; digitCount++, str++) { + unsigned v = *str; + + if ((v >= '0') && (v <= '9')) + v -= '0'; + else if ((v >= 'a') && (v <= 'f')) + v = 10 + v - 'a'; + else if ((v >= 'A') && (v <= 'F')) + v = 10 + v - 'A'; + else + break; + + *val = *val * 16 + v; + } + + return str; +} + +//----------------------------------------------------------------------------- +// Parses the input text into a string item and returns the text position after +// the parsed string +const char* JSON::parseString(const char* str, const char** perror) { + const char* ptr = str + 1; + const char* p; + char* ptr2; + char* out; + int len = 0; + unsigned uc, uc2; + + if (*str != '\"') { + return AssignError(perror, "Syntax Error: Missing quote"); + } + + while (*ptr != '\"' && *ptr && ++len) { + if (*ptr++ == '\\') + ptr++; // Skip escaped quotes. + } + + // This is how long we need for the string, roughly. + out = (char*)OVR_ALLOC(len + 1); + if (!out) + return 0; + + ptr = str + 1; + ptr2 = out; + + while (*ptr != '\"' && *ptr) { + if (*ptr != '\\') { + *ptr2++ = *ptr++; + } else { + ptr++; + switch (*ptr) { + case 'b': + *ptr2++ = '\b'; + break; + case 'f': + *ptr2++ = '\f'; + break; + case 'n': + *ptr2++ = '\n'; + break; + case 'r': + *ptr2++ = '\r'; + break; + case 't': + *ptr2++ = '\t'; + break; + + // Transcode utf16 to utf8. + case 'u': + + // Get the unicode char. + p = ParseHex(&uc, 4, ptr + 1); + if (ptr != p) + ptr = p - 1; + + if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) + break; // Check for invalid. + + // UTF16 surrogate pairs. + if (uc >= 0xD800 && uc <= 0xDBFF) { + if (ptr[1] != '\\' || ptr[2] != 'u') + break; // Missing second-half of surrogate. + + p = ParseHex(&uc2, 4, ptr + 3); + if (ptr != p) + ptr = p - 1; + + if (uc2 < 0xDC00 || uc2 > 0xDFFF) + break; // Invalid second-half of surrogate. + + uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF)); + } + + len = 4; + + if (uc < 0x80) + len = 1; + else if (uc < 0x800) + len = 2; + else if (uc < 0x10000) + len = 3; + + ptr2 += len; + + switch (len) { + case 4: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + // no break, fall through + case 3: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + // no break + case 2: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + // no break + case 1: + *--ptr2 = (char)(uc | firstByteMark[len]); + // no break + } + ptr2 += len; + break; + + default: + *ptr2++ = *ptr; + break; + } + ptr++; + } + } + + *ptr2 = 0; + if (*ptr == '\"') + ptr++; + + // Make a copy of the string + Value = out; + OVR_FREE(out); + Type = JSON_String; + + return ptr; +} + +//----------------------------------------------------------------------------- +// Render the string provided to an escaped version that can be printed. +char* PrintString(const char* str) { + const char* ptr; + char *ptr2, *out; + int len = 0; + unsigned char token; + + if (!str) + return JSON_strdup(""); + ptr = str; + + token = *ptr; + while (token && ++len) { + if (strchr("\"\\\b\f\n\r\t", token)) + len++; + else if (token < 32) + len += 5; + ptr++; + token = *ptr; + } + + int buff_size = len + 3; + out = (char*)OVR_ALLOC(buff_size); + if (!out) + return 0; + + ptr2 = out; + ptr = str; + *ptr2++ = '\"'; + + while (*ptr) { + if ((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\') + *ptr2++ = *ptr++; + else { + *ptr2++ = '\\'; + switch (token = *ptr++) { + case '\\': + *ptr2++ = '\\'; + break; + case '\"': + *ptr2++ = '\"'; + break; + case '\b': + *ptr2++ = 'b'; + break; + case '\f': + *ptr2++ = 'f'; + break; + case '\n': + *ptr2++ = 'n'; + break; + case '\r': + *ptr2++ = 'r'; + break; + case '\t': + *ptr2++ = 't'; + break; + default: + snprintf(ptr2, buff_size - (ptr2 - out), "u%04x", token); + ptr2 += 5; + break; // Escape and print. + } + } + } + *ptr2++ = '\"'; + *ptr2++ = 0; + return out; +} + +//----------------------------------------------------------------------------- +// Utility to jump whitespace and cr/lf +static const char* skip(const char* in) { + while (in && *in && (unsigned char)*in <= ' ') + in++; + return in; +} + +//----------------------------------------------------------------------------- +// Parses the supplied buffer of JSON text and returns a JSON object tree +// The returned object must be Released after use +JSON* JSON::Parse(const char* buff, const char** perror) { + const char* end = 0; + JSON* json = new JSON(); + + if (!json) { + AssignError(perror, "Error: Failed to allocate memory"); + return 0; + } + + end = json->parseValue(skip(buff), perror); + if (!end) { + json->Release(); + return NULL; + } // parse failure. ep is set. + + return json; +} + +//----------------------------------------------------------------------------- +// This version works for buffers that are not null terminated strings. +JSON* JSON::ParseBuffer(const char* buff, int len, const char** perror) { + // Our JSON parser does not support length-based parsing, + // so ensure it is null-terminated. + char* termStr = new char[len + 1]; + memcpy(termStr, buff, len); + termStr[len] = '\0'; + + JSON* objJson = Parse(termStr, perror); + + delete[] termStr; + + return objJson; +} + +//----------------------------------------------------------------------------- +// Parser core - when encountering text, process appropriately. +const char* JSON::parseValue(const char* buff, const char** perror) { + if (perror) + *perror = 0; + + if (!buff) + return NULL; // Fail on null. + + if (!OVR_strncmp(buff, "null", 4)) { + Type = JSON_Null; + return buff + 4; + } + if (!OVR_strncmp(buff, "false", 5)) { + Type = JSON_Bool; + Value = "false"; + dValue = 0.; + return buff + 5; + } + if (!OVR_strncmp(buff, "true", 4)) { + Type = JSON_Bool; + Value = "true"; + dValue = 1.; + return buff + 4; + } + if (*buff == '\"') { + return parseString(buff, perror); + } + if (*buff == '-' || (*buff >= '0' && *buff <= '9')) { + return parseNumber(buff); + } + if (*buff == '[') { + return parseArray(buff, perror); + } + if (*buff == '{') { + return parseObject(buff, perror); + } + + return AssignError(perror, "Syntax Error: Invalid syntax"); +} + +//----------------------------------------------------------------------------- +// Render a value to text. +char* JSON::PrintValue(int depth, bool fmt) { + char* out = 0; + + switch (Type) { + case JSON_Null: + out = JSON_strdup("null"); + break; + case JSON_Bool: + if ((int)dValue == 0) + out = JSON_strdup("false"); + else + out = JSON_strdup("true"); + break; + case JSON_Number: + out = PrintNumber(dValue); + break; + case JSON_String: + out = PrintString(Value); + break; + case JSON_Array: + out = PrintArray(depth, fmt); + break; + case JSON_Object: + out = PrintObject(depth, fmt); + break; + case JSON_None: + OVR_FAIL(); + break; + } + return out; +} + +//----------------------------------------------------------------------------- +// Build an array object from input text and returns the text position after +// the parsed array +const char* JSON::parseArray(const char* buff, const char** perror) { + JSON* child; + if (*buff != '[') { + return AssignError(perror, "Syntax Error: Missing opening bracket"); + } + + Type = JSON_Array; + buff = skip(buff + 1); + + if (*buff == ']') + return buff + 1; // empty array. + + child = new JSON(); + if (!child) + return 0; // memory fail + Children.PushBack(child); + + buff = skip(child->parseValue(skip(buff), perror)); // skip any spacing, get the buff. + if (!buff) + return 0; + + while (*buff == ',') { + JSON* new_item = new JSON(); + if (!new_item) + return AssignError(perror, "Error: Failed to allocate memory"); + + Children.PushBack(new_item); + + buff = skip(new_item->parseValue(skip(buff + 1), perror)); + if (!buff) + return AssignError(perror, "Error: Failed to allocate memory"); + } + + if (*buff == ']') + return buff + 1; // end of array + + return AssignError(perror, "Syntax Error: Missing ending bracket"); +} + +//----------------------------------------------------------------------------- +// Render an array to text. The returned text must be freed +char* JSON::PrintArray(int depth, bool fmt) { + char** entries; + char *out = 0, *ptr, *ret; + intptr_t len = 5; + + bool fail = false; + + // How many entries in the array? + int numentries = GetItemCount(); + if (!numentries) { + out = (char*)OVR_ALLOC(3); + if (out) + OVR_strcpy(out, 3, "[]"); + return out; + } + // Allocate an array to hold the values for each + entries = (char**)OVR_ALLOC(numentries * sizeof(char*)); + if (!entries) + return 0; + memset(entries, 0, numentries * sizeof(char*)); + + //// Retrieve all the results: + JSON* child = Children.GetFirst(); + for (int i = 0; i < numentries; i++) { + // JSON* child = Children[i]; + ret = child->PrintValue(depth + 1, fmt); + entries[i] = ret; + if (ret) + len += OVR_strlen(ret) + 2 + (fmt ? 1 : 0); + else { + fail = true; + break; + } + child = Children.GetNext(child); + } + + // If we didn't fail, try to malloc the output string + if (!fail) + out = (char*)OVR_ALLOC(len); + // If that fails, we fail. + if (!out) + fail = true; + + // Handle failure. + if (fail) { + for (int i = 0; i < numentries; i++) { + if (entries[i]) + OVR_FREE(entries[i]); + } + OVR_FREE(entries); + return 0; + } + + // Compose the output array. + *out = '['; + ptr = out + 1; + *ptr = 0; + for (int i = 0; i < numentries; i++) { + OVR_strcpy(ptr, len - (ptr - out), entries[i]); + ptr += OVR_strlen(entries[i]); + if (i != numentries - 1) { + *ptr++ = ','; + if (fmt) + *ptr++ = ' '; + *ptr = 0; + } + OVR_FREE(entries[i]); + } + OVR_FREE(entries); + *ptr++ = ']'; + *ptr++ = 0; + return out; +} + +//----------------------------------------------------------------------------- +// Build an object from the supplied text and returns the text position after +// the parsed object +const char* JSON::parseObject(const char* buff, const char** perror) { + if (*buff != '{') { + return AssignError(perror, "Syntax Error: Missing opening brace"); + } + + Type = JSON_Object; + buff = skip(buff + 1); + if (*buff == '}') + return buff + 1; // empty array. + + JSON* child = new JSON(); + Children.PushBack(child); + + buff = skip(child->parseString(skip(buff), perror)); + if (!buff) + return 0; + child->Name = child->Value; + child->Value.Clear(); + + if (*buff != ':') { + return AssignError(perror, "Syntax Error: Missing colon"); + } + + buff = skip(child->parseValue(skip(buff + 1), perror)); // skip any spacing, get the value. + if (!buff) + return 0; + + while (*buff == ',') { + child = new JSON(); + if (!child) + return 0; // memory fail + + Children.PushBack(child); + + buff = skip(child->parseString(skip(buff + 1), perror)); + if (!buff) + return 0; + + child->Name = child->Value; + child->Value.Clear(); + + if (*buff != ':') { + return AssignError(perror, "Syntax Error: Missing colon"); + } // fail! + + // Skip any spacing, get the value. + buff = skip(child->parseValue(skip(buff + 1), perror)); + if (!buff) + return 0; + } + + if (*buff == '}') + return buff + 1; // end of array + + return AssignError(perror, "Syntax Error: Missing closing brace"); +} + +//----------------------------------------------------------------------------- +// Render an object to text. The returned string must be freed +char* JSON::PrintObject(int depth, bool fmt) { + char **entries = 0, **names = 0; + char* out = 0; + char *ptr, *ret, *str; + intptr_t len = 7, i = 0, j; + bool fail = false; + + // Count the number of entries. + int numentries = GetItemCount(); + + // Explicitly handle empty object case + if (numentries == 0) { + out = (char*)OVR_ALLOC(fmt ? depth + 4 : 4); + if (!out) + return 0; + ptr = out; + *ptr++ = '{'; + + if (fmt) { +#ifdef OVR_OS_WIN32 + *ptr++ = '\r'; +#endif + *ptr++ = '\n'; + for (i = 0; i < depth - 1; i++) + *ptr++ = '\t'; + } + *ptr++ = '}'; + *ptr++ = 0; + return out; + } + // Allocate space for the names and the objects + entries = (char**)OVR_ALLOC(numentries * sizeof(char*)); + if (!entries) + return 0; + names = (char**)OVR_ALLOC(numentries * sizeof(char*)); + + if (!names) { + OVR_FREE(entries); + return 0; + } + memset(entries, 0, sizeof(char*) * numentries); + memset(names, 0, sizeof(char*) * numentries); + + // Collect all the results into our arrays: + depth++; + if (fmt) + len += depth; + + JSON* child = Children.GetFirst(); + while (!Children.IsNull(child)) { + names[i] = str = PrintString(child->Name); + entries[i++] = ret = child->PrintValue(depth, fmt); + + if (str && ret) { + len += OVR_strlen(ret) + OVR_strlen(str) + 2 + (fmt ? 3 + depth : 0); + } else { + fail = true; + break; + } + + child = Children.GetNext(child); + } + + // Try to allocate the output string + if (!fail) + out = (char*)OVR_ALLOC(len); + if (!out) + fail = true; + + // Handle failure + if (fail) { + for (i = 0; i < numentries; i++) { + if (names[i]) + OVR_FREE(names[i]); + + if (entries[i]) + OVR_FREE(entries[i]); + } + + OVR_FREE(names); + OVR_FREE(entries); + return 0; + } + + // Compose the output: + *out = '{'; + ptr = out + 1; + if (fmt) { +#ifdef OVR_OS_WIN32 + *ptr++ = '\r'; +#endif + *ptr++ = '\n'; + } + *ptr = 0; + + for (i = 0; i < numentries; i++) { + if (fmt) { + for (j = 0; j < depth; j++) { + *ptr++ = '\t'; + } + } + OVR_strcpy(ptr, len - (ptr - out), names[i]); + ptr += OVR_strlen(names[i]); + *ptr++ = ':'; + + if (fmt) { + *ptr++ = '\t'; + } + + OVR_strcpy(ptr, len - (ptr - out), entries[i]); + ptr += OVR_strlen(entries[i]); + + if (i != numentries - 1) { + *ptr++ = ','; + } + + if (fmt) { +#ifdef OVR_OS_WIN32 + *ptr++ = '\r'; +#endif + *ptr++ = '\n'; + } + *ptr = 0; + + OVR_FREE(names[i]); + OVR_FREE(entries[i]); + } + + OVR_FREE(names); + OVR_FREE(entries); + + if (fmt) { + for (i = 0; i < depth - 1; i++) { + *ptr++ = '\t'; + } + } + *ptr++ = '}'; + *ptr++ = 0; + + return out; +} + +// Returns the number of child items in the object +// Counts the number of items in the object. +unsigned JSON::GetItemCount() const { + unsigned count = 0; + for (const JSON* p = Children.GetFirst(); !Children.IsNull(p); p = Children.GetNext(p)) { + count++; + } + return count; +} + +JSON* JSON::GetItemByIndex(unsigned index) { + unsigned i = 0; + JSON* child = 0; + + if (!Children.IsEmpty()) { + child = Children.GetFirst(); + + while (i < index) { + if (Children.IsLast(child)) { + child = 0; + break; + } + child = child->GetNext(); + i++; + } + } + + return child; +} + +// Returns the child item with the given name or NULL if not found +JSON* JSON::GetItemByName(const char* name) { + JSON* child = 0; + + if (!Children.IsEmpty()) { + child = Children.GetFirst(); + + while (OVR_strcmp(child->Name, name) != 0) { + if (Children.IsLast(child)) { + child = 0; + break; + } + child = child->GetNext(); + } + } + + return child; +} + +//----------------------------------------------------------------------------- +// Adds a new item to the end of the child list +void JSON::AddItem(const char* string, JSON* item) { + if (item) { + item->Name = string; + Children.PushBack(item); + } +} + +/* + +// Removes and frees the items at the given index +void JSON::DeleteItem(unsigned int index) +{ + unsigned int num_items = 0; + JSON* child = Children.GetFirst(); + while (!Children.IsNull(child) && num_items < index) + { + num_items++; + child = Children.GetNext(child); + } + + if (!Children.IsNull(child)) + + child->RemoveNode(); + child->Release(); + } +} + +// Replaces and frees the item at the give index with the new item +void JSON::ReplaceItem(unsigned int index, JSON* new_item) +{ + unsigned int num_items = 0; + JSON* child = Children.GetFirst(); + while (!Children.IsNull(child) && num_items < index) + { + num_items++; + child = Children.GetNext(child); + } + + if (!Children.IsNull(child)) + { + child->ReplaceNodeWith(new_item); + child->Release(); + } +} +*/ + +// Removes and frees the last child item +void JSON::RemoveLast() { + JSON* child = Children.GetLast(); + if (!Children.IsNull(child)) { + child->RemoveNode(); + child->Release(); + } +} + +JSON* JSON::CreateBool(bool b) { + JSON* item = new JSON(JSON_Bool); + if (item) { + item->dValue = b ? 1. : 0.; + item->Value = b ? "true" : "false"; + } + return item; +} + +JSON* JSON::CreateNumber(double num) { + JSON* item = new JSON(JSON_Number); + if (item) { + item->dValue = num; + } + return item; +} + +JSON* JSON::CreateInt(int num) { + JSON* item = new JSON(JSON_Number); + if (item) { + item->dValue = num; + } + return item; +} + +JSON* JSON::CreateString(const char* s) { + JSON* item = new JSON(JSON_String); + if (item && s) { + item->Value = s; + } + return item; +} + +//----------------------------------------------------------------------------- +// Get elements by name +double JSON::GetNumberByName(const char* name, double defValue) { + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_Number) { + return defValue; + } else { + return item->dValue; + } +} + +int JSON::GetIntByName(const char* name, int defValue) { + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_Number) { + return defValue; + } else { + return (int)item->dValue; + } +} + +bool JSON::GetBoolByName(const char* name, bool defValue) { + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_Bool) { + return defValue; + } else { + return (int)item->dValue != 0; + } +} + +String JSON::GetStringByName(const char* name, const String& defValue) { + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_String) { + return defValue; + } else { + return item->Value; + } +} + +//----------------------------------------------------------------------------- +// Adds an element to an array object type +void JSON::AddArrayElement(JSON* item) { + if (item) { + Children.PushBack(item); + } +} + +// Inserts an element into a valid array position +void JSON::InsertArrayElement(int index, JSON* item) { + if (!item) { + return; + } + + if (index == 0) { + Children.PushFront(item); + return; + } + + JSON* iter = Children.GetFirst(); + int i = 0; + while (iter && i < index) { + iter = Children.GetNext(iter); + i++; + } + + if (iter) + iter->InsertNodeBefore(item); + else + Children.PushBack(item); +} + +// Returns the size of an array +int JSON::GetArraySize() { + if (Type == JSON_Array) { + return GetItemCount(); + } + + return 0; +} + +// Returns the number value an the give array index +double JSON::GetArrayNumber(int index) { + if (Type == JSON_Array) { + JSON* number = GetItemByIndex(index); + return number ? number->dValue : 0.0; + } + + return 0; +} + +// Returns the string value at the given array index +const char* JSON::GetArrayString(int index) { + if (Type == JSON_Array) { + JSON* number = GetItemByIndex(index); + return number ? number->Value : 0; + } + + return 0; +} + +JSON* JSON::Copy() { + JSON* copy = new JSON(Type); + copy->Name = Name; + copy->Value = Value; + copy->dValue = dValue; + + JSON* child = Children.GetFirst(); + while (!Children.IsNull(child)) { + copy->Children.PushBack(child->Copy()); + child = Children.GetNext(child); + } + + return copy; +} + +char* JSON::PrintValue(bool fmt) { + return PrintValue(0, fmt); +} + +//----------------------------------------------------------------------------- +// Loads and parses the given JSON file pathname and returns a JSON object tree. +// The returned object must be Released after use. +JSON* JSON::Load(const char* path, const char** perror) { + SysFile f; + if (!f.Open(path, File::Open_Read, File::Mode_Read)) { + AssignError(perror, "Failed to open file"); + return NULL; + } + + int len = f.GetLength(); + uint8_t* buff = (uint8_t*)OVR_ALLOC(len + 1); + int bytes = f.Read(buff, len); + f.Close(); + + if (bytes == 0 || bytes != len) { + OVR_FREE(buff); + return NULL; + } + + // Ensure the result is null-terminated since Parse() expects null-terminated input. + buff[len] = '\0'; + + JSON* json = JSON::Parse((char*)buff, perror); + OVR_FREE(buff); + return json; +} + +//----------------------------------------------------------------------------- +// Serializes the JSON object and writes to the give file path +bool JSON::Save(const char* path) { + SysFile f; + if (!f.Open(path, File::Open_Write | File::Open_Create | File::Open_Truncate, File::Mode_Write)) + return false; + + char* text = PrintValue(0, true); + if (text) { + intptr_t len = OVR_strlen(text); + OVR_ASSERT(len <= (intptr_t)(int)len); + + int bytes = f.Write((uint8_t*)text, (int)len); + f.Close(); + OVR_FREE(text); + return (bytes == len); + } else { + return false; + } +} + +//----------------------------------------------------------------------------- +// Serializes the JSON object to a String +String JSON::Stringify(bool fmt) { + char* text = PrintValue(0, fmt); + String copy(text); + OVR_FREE(text); + return copy; +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_JSON.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_JSON.h new file mode 100644 index 0000000..71b5e28 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_JSON.h @@ -0,0 +1,228 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_JSON.h +Content : JSON format reader and writer +Created : April 9, 2013 +Author : Brant Lewis +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_JSON_h +#define OVR_JSON_h + +#include "OVR_List.h" +#include "OVR_RefCount.h" +#include "OVR_String.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, public ListNode { + protected: + List 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); + static JSON* CreateNumber(double num); + static JSON* CreateInt(int num); + static JSON* CreateString(const char* 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); + + // This version works for buffers that are not null terminated strings. + static JSON* ParseBuffer(const char* buff, int len, 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); + + // Return the String representation of a JSON object. + String Stringify(bool fmt); + + // *** 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); + + // Accessors by name + double GetNumberByName(const char* name, double defValue = 0.0); + int GetIntByName(const char* name, int defValue = 0); + bool GetBoolByName(const char* name, bool defValue = false); + String GetStringByName(const char* name, const String& defValue = ""); + + template + int GetArrayByName(const char* name, T values[], int count, T defaultValue = T(0)) { + // Zero values in case one or more elements not present in JSON + for (int i = 0; i < count; i++) + values[i] = defaultValue; + + JSON* array = GetItemByName(name); + if (!array || array->Type != JSON_Array) + return 0; + + int i = 0; + for (JSON* child = array->Children.GetFirst(); !array->Children.IsNull(child); + child = array->Children.GetNext(child)) { + if (i >= count) + break; + values[i++] = (T)child->dValue; + } + + OVR_ASSERT(i <= count); + return i; + } + + // Returns next item in a list of children; 0 if no more items exist. + JSON* GetNextItem(JSON* item) { + return Children.IsLast(item) ? nullptr : item->GetNext(); + } + JSON* GetPrevItem(JSON* item) { + return Children.IsFirst(item) ? nullptr : item->GetPrev(); + } + + // 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 AddIntItem(const char* name, int n) { + AddItem(name, CreateInt(n)); + } + 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); + void RemoveLast(); + + // *** Array Element Access + + // Add new elements to the end of array. + void AddArrayElement(JSON* item); + void InsertArrayElement(int index, JSON* item); + void AddArrayNumber(double n) { + AddArrayElement(CreateNumber(n)); + } + void AddArrayInt(int n) { + AddArrayElement(CreateInt(n)); + } + void AddArrayString(const char* s) { + AddArrayElement(CreateString(s)); + } + + template + void AddNumberArray(const char* name, const T array[], int arraySize) { + JSON* node = JSON::CreateArray(); + AddItem(name, node); + for (int i = 0; i < arraySize; i++) + node->AddArrayNumber((double)array[i]); + } + + // Accessed array elements; currently inefficient. + int GetArraySize(); + double GetArrayNumber(int index); + const char* GetArrayString(int index); + + JSON* Copy(); // Create a copy of this object + + // Return text value of JSON. Use OVR_FREE when done with return value + char* PrintValue(bool fmt); + + protected: + JSON(JSONItemType itemType = JSON_Object); + + // 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); +}; +} // namespace OVR + +#endif // OVR_JSON_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_KeyCodes.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_KeyCodes.h new file mode 100644 index 0000000..22d1edd --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_KeyCodes.h @@ -0,0 +1,281 @@ +/************************************************************************************ + +Filename : OVR_KeyCodes.h +Content : Common keyboard constants +Created : September 19, 2012 + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#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, + + // Synthetic mouse wheel state + Key_MouseWheelAwayFromUser, // "forwards" or "up" + Key_MouseWheelTowardUser, // "backwards" or "down" + + 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_Backtick = 96, // ` and tilda~ when shifted (US keyboard) + 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; +}; +*/ + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_List.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_List.h new file mode 100644 index 0000000..2b70def --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_List.h @@ -0,0 +1,389 @@ +/************************************************************************************ + +PublicHeader: OVR +Filename : OVR_List.h +Content : Template implementation for doubly-connected linked List +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#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: +// +// class MyData : ListNode +// { +// . . . +// }; + +template +class ListNode { + private: + ListNode* pPrev; + ListNode* pNext; + + template + friend class List; + +#ifdef OVR_BUILD_DEBUG + bool marker; // Is this a marker node (rather than an actual data node)? +#endif + + public: +#ifdef OVR_BUILD_DEBUG + T* GetPrev() const { + if (pPrev && !pPrev->marker) { + return (T*)(pPrev); + } else { + OVR_FAIL_M("Unstable call to ListNode<>::GetPrev() without first checking List<>IsFirst()"); + return nullptr; + } + } + T* GetNext() const { + if (pNext && !pNext->marker) { + return (T*)(pNext); + } else { + OVR_FAIL_M("Unstable call to ListNode<>::GetNext() without first checking List<>IsLast()"); + return nullptr; + } + } +#else + T* GetPrev() const { + return (T*)(pPrev); + } + T* GetNext() const { + return (T*)(pNext); + } +#endif + + ListNode() { +#ifdef OVR_BUILD_DEBUG + marker = false; // Most nodes are data nodes, so that is the default. +#endif + pPrev = nullptr; + pNext = nullptr; + } + + bool IsInList() { + return (pNext != nullptr); + } + + void RemoveNode() { + pPrev->pNext = pNext; + pNext->pPrev = pPrev; + pPrev = nullptr; + pNext = nullptr; + } + + // 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; + pPrev = nullptr; + pNext = nullptr; + } + + // 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* pdest) { + pdest->pNext = pNext; + pdest->pPrev = pPrev; + pPrev->pNext = pdest; + pNext->pPrev = pdest; + pPrev = nullptr; + pNext = nullptr; + } +}; + +//------------------------------------------------------------------------ +// ***** 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 specifies the base class that was directly +// derived from ListNode, and is only necessary if there is an intermediate +// inheritance chain. + +template +class List { + public: + typedef T ValueType; + + List() { + Root.pNext = Root.pPrev = &Root; +#ifdef OVR_BUILD_DEBUG + Root.marker = true; // This is a marker node. +#endif + } + + void Clear() { + Root.pNext = Root.pPrev = &Root; + } + + size_t GetSize() const { + size_t n = 0; + + for (const ListNode* pNode = Root.pNext; pNode != &Root; pNode = pNode->pNext) + ++n; + + return n; + } + + const ValueType* GetFirst() const { + return IsEmpty() ? nullptr : (const ValueType*)Root.pNext; + } + const ValueType* GetLast() const { + return IsEmpty() ? nullptr : (const ValueType*)Root.pPrev; + } + ValueType* GetFirst() { + return IsEmpty() ? nullptr : (ValueType*)Root.pNext; + } + ValueType* GetLast() { + return IsEmpty() ? nullptr : (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.pNext == &Root; + } + bool IsFirst(const ValueType* p) const { + return p == Root.pNext; + } + bool IsLast(const ValueType* p) const { + return p == Root.pPrev; + } + bool IsNull(const ListNode* p) const { + return p == nullptr || p == &Root; + } + + inline const ValueType* GetPrev(const ValueType* p) const { + return IsNull(p->pPrev) ? nullptr : (const ValueType*)p->pPrev; + } + inline const ValueType* GetNext(const ValueType* p) const { + return IsNull(p->pNext) ? nullptr : (const ValueType*)p->pNext; + } + inline ValueType* GetPrev(ValueType* p) { + return IsNull(p->pPrev) ? nullptr : (ValueType*)p->pPrev; + } + inline ValueType* GetNext(ValueType* p) { + return IsNull(p->pNext) ? nullptr : (ValueType*)p->pNext; + } + + void PushFront(ValueType* p) { + p->pNext = Root.pNext; + p->pPrev = &Root; + Root.pNext->pPrev = p; + Root.pNext = p; + } + + void PushBack(ValueType* p) { + p->pPrev = Root.pPrev; + p->pNext = &Root; + Root.pPrev->pNext = p; + Root.pPrev = p; + } + + static void Remove(ValueType* p) { + p->pPrev->pNext = p->pNext; + p->pNext->pPrev = p->pPrev; + p->pPrev = nullptr; + p->pNext = nullptr; + } + + 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& src) { + if (!src.IsEmpty()) { + ValueType* pfirst = src.GetFirst(); + ValueType* plast = src.GetLast(); + src.Clear(); + plast->pNext = Root.pNext; + pfirst->pPrev = &Root; + Root.pNext->pPrev = plast; + Root.pNext = pfirst; + } + } + + void PushListToBack(List& src) { + if (!src.IsEmpty()) { + ValueType* pfirst = src.GetFirst(); + ValueType* plast = src.GetLast(); + src.Clear(); + plast->pNext = &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& src, ValueType* pfirst) { + if (pfirst != &src.Root) { + ValueType* plast = src.Root.pPrev; + + // Remove list remainder from source. + pfirst->pPrev->pNext = &src.Root; + src.Root.pPrev = pfirst->pPrev; + // Add the rest of the items to list. + plast->pNext = Root.pNext; + pfirst->pPrev = &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& src, ValueType* ptail) { + if (src.GetFirst() != ptail) { + ValueType* pfirst = src.Root.pNext; + ValueType* plast = ptail->pPrev; + + // Remove list remainder from source. + ptail->pPrev = &src.Root; + src.Root.pNext = ptail; + + // Add the rest of the items to list. + plast->pNext = Root.pNext; + pfirst->pPrev = &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 = &Root; + Root.pNext->pPrev = plast; + Root.pNext = pfirst; + } + } + + void Alloc_MoveTo(List* pdest) { + if (IsEmpty()) + pdest->Clear(); + else { + pdest->Root.pNext = Root.pNext; + pdest->Root.pPrev = Root.pPrev; + + Root.pNext->pPrev = &pdest->Root; + Root.pPrev->pNext = &pdest->Root; + } + } + + private: + // Copying is prohibited + List(const List&); + const List& operator=(const List&); + + ListNode Root; +}; + +//------------------------------------------------------------------------ +// ***** FreeListElements +// +// Remove all elements in the list and free them in the allocator + +template +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(); +} + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Lockless.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Lockless.h new file mode 100644 index 0000000..a3fbac5 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Lockless.h @@ -0,0 +1,202 @@ +/************************************************************************************ + +Filename : OVR_Lockless.h +Content : Lock-less classes for producer/consumer communication +Created : November 9, 2013 +Authors : John Carmack + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Lockless_h +#define OVR_Lockless_h + +#include +using std::memcpy; + +#include "OVR_Atomic.h" + +// Define this to compile-in Lockless test logic +//#define OVR_LOCKLESS_TEST + +namespace OVR { + +// ***** LocklessUpdater + +// For single producer cases where you only care about the most recent update, not +// necessarily getting every one that happens (vsync timing, SensorFusion updates). +// +// This is multiple consumer safe, but is currently only used with a single consumer. +// +// The SlotType can be the same as T, but should probably be a larger fixed size. +// This allows for forward compatibility when the updater is shared between processes. + +template +class LocklessUpdater { + public: + LocklessUpdater() { + OVR_COMPILER_ASSERT(sizeof(T) <= sizeof(SlotType)); + } + + T GetState() const { + // Copy the state out, then retry with the alternate slot + // if we determine that our copy may have been partially + // stepped on by a new update. + T state; + int begin, end, final; + + for (;;) { + // We are adding 0, only using these as atomic memory barriers, so it + // is ok to cast off the const, allowing GetState() to remain const. + end = UpdateEnd.load(std::memory_order_acquire); + state = Slots[end & 1]; + begin = UpdateBegin.load(std::memory_order_acquire); + if (begin == end) { + break; + } + + // The producer is potentially blocked while only having partially + // written the update, so copy out the other slot. + state = Slots[(begin & 1) ^ 1]; + final = UpdateBegin.load(std::memory_order_acquire); + if (final == begin) { + break; + } + + // The producer completed the last update and started a new one before + // we got it copied out, so try fetching the current buffer again. + } + return state; + } + + void SetState(const T& state) { + const int slot = UpdateBegin.fetch_add(1) & 1; + // Write to (slot ^ 1) because ExchangeAdd returns 'previous' value before add. + Slots[slot ^ 1] = state; + UpdateEnd.fetch_add(1); + } + + std::atomic UpdateBegin = {0}; + std::atomic UpdateEnd = {0}; + SlotType Slots[2]; +}; + +#pragma pack(push, 8) + +// Padded out version stored in the updater slots +// Designed to be a larger fixed size to allow the data to grow in the future +// without breaking older compiled code. +OVR_DISABLE_MSVC_WARNING(4351) +template +struct LocklessPadding { + uint8_t buffer[PaddingSize]; + + LocklessPadding() : buffer() {} + + LocklessPadding& operator=(const Payload& rhs) { + // if this fires off, then increase PaddingSize + // IMPORTANT: this WILL break backwards compatibility + static_assert(sizeof(buffer) >= sizeof(Payload), "PaddingSize is too small"); + + memcpy(buffer, &rhs, sizeof(Payload)); + return *this; + } + + operator Payload() const { + Payload result; + memcpy(&result, buffer, sizeof(Payload)); + return result; + } +}; +OVR_RESTORE_MSVC_WARNING() + +#pragma pack(pop) + +// FIXME: Move this somewhere else + +// ***** LocklessBuffer + +// FIXME: update these comments +// For single producer cases where you only care about the most recent update, not +// necessarily getting every one that happens (vsync timing, SensorFusion updates, external camera +// frames). +// +// The writer writes an incrementing generation # for each write start, and write end +// The reader reads the last written generation number, saves it, does its operations, then +// reads the latest value of the last written generation number. If they match, there was no +// collision, and the work is done. If not, the reader has to loop until it gets a matching +// Last written generation number +// +// This is to update & read a dynamically sized object in shared memory. +// Initial use case is for frame buffers for cameras, which are an unknown size until runtime + +#pragma pack(push, 1) + +class LocklessBuffer { + public: + LocklessBuffer() { + ; + } + + void Initialize(unsigned bufferSize) { + BufferSize = bufferSize; + LastWrittenGeneration = 0; + } + + char* StartWrite(unsigned offset) { + ++LastWrittenGeneration; + return GetDataForWrite(offset); + } + + unsigned GetBufferSize() const { + return BufferSize; + } + + int EndWrite() { + return ++LastWrittenGeneration; + } + + int GetLastWrittenGeneration() const { + return LastWrittenGeneration; + } + + const char* GetDataForRead(unsigned offset = 0) const { + return &(Data[offset]); + } + char* GetDataForWrite(unsigned offset = 0) { + return &(Data[offset]); + } + + bool DidReadCollide(int lastReadGeneration) const { + return lastReadGeneration != LastWrittenGeneration; + } + + private: + unsigned BufferSize = 0; + std::atomic LastWrittenGeneration; + + // Data starts here... + char Data[1]; +}; + +#pragma pack(pop) + +} // namespace OVR + +#endif // OVR_Lockless_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_NewOverride.inl b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_NewOverride.inl new file mode 100644 index 0000000..9447b11 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_NewOverride.inl @@ -0,0 +1,207 @@ +/************************************************************************************ + +Filename : OVR_NewOverride.inl +Content : New override for LibOVR Allocator +Created : April 7, 2015 +Authors : Paul Pedriana, Chris Taylor + +Copyright : Copyright 2015-2016 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.3 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.3 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_NewOverride_inl +#define OVR_NewOverride_inl + +#include "OVR_Allocator.h" + +#include + +#if defined(_MSC_VER) + #pragma warning(push, 0) + #include + #include + + #include // Work around VS header bug by #including math.h then intrin.h. + #if (_MSC_VER >= 1500) + #include + #endif + #pragma warning(pop) + + #if (_MSC_VER >= 1600) // VS2010+ + #pragma warning(disable : 4986) // 'operator delete[]': exception specification does not match previous declaration. + #endif +#endif + + + +#if defined(_MSC_VER) + +#if !defined(__clang__) && (_MSC_VER <= 1900) + // avoid clang.exe guessing _MSC_VER based on the machine's MSVS installation + #define OVR_THROW_SPEC_NEW(X) __pragma(warning(push)) __pragma(warning(disable: 4290 4987)) _THROW(,X) __pragma(warning(pop)) + #define OVR_THROW_SPEC_NEW_NONE() _THROW(,) + #define OVR_THROW_SPEC_DELETE_NONE() _THROW(,) +#else + #define OVR_THROW_SPEC_NEW(x) __pragma(warning(push)) __pragma(warning(disable: 4290 4987)) noexcept(false) __pragma(warning(pop)) + #define OVR_THROW_SPEC_NEW_NONE() noexcept + #define OVR_THROW_SPEC_DELETE_NONE() noexcept +#endif + +#else + #define OVR_THROW_SPEC_NEW(x) throw(x) + #define OVR_THROW_SPEC_NEW_NONE() throw() + #define OVR_THROW_SPEC_DELETE_NONE() throw() +#endif + + +// Add common decorators here as neeeded. +#define OVR_NEW_OVERRIDE_INLINE + + +OVR_NEW_OVERRIDE_INLINE void* operator new(size_t size) OVR_THROW_SPEC_NEW(std::bad_alloc) +{ + void* p = OVR_ALLOC(size); + + #if !defined(OVR_CPP_NO_EXCEPTIONS) + if(!p) + throw std::bad_alloc(); + #endif + + return p; +} + +OVR_NEW_OVERRIDE_INLINE void* operator new[](size_t size) OVR_THROW_SPEC_NEW(std::bad_alloc) +{ + void* p = OVR_ALLOC(size); + + #if !defined(OVR_CPP_NO_EXCEPTIONS) + if(!p) + throw std::bad_alloc(); + #endif + + return p; +} + + +OVR_NEW_OVERRIDE_INLINE void* operator new(size_t size, std::nothrow_t&) OVR_THROW_SPEC_NEW_NONE() +{ + return OVR_ALLOC(size); +} + +OVR_NEW_OVERRIDE_INLINE void* operator new[](size_t size, std::nothrow_t&) OVR_THROW_SPEC_NEW_NONE() +{ + return OVR_ALLOC(size); +} + + + +OVR_NEW_OVERRIDE_INLINE void* operator new(size_t size, const std::nothrow_t&) OVR_THROW_SPEC_NEW_NONE() +{ + return OVR_ALLOC(size); +} + +OVR_NEW_OVERRIDE_INLINE void* operator new[](size_t size, const std::nothrow_t&) OVR_THROW_SPEC_NEW_NONE() +{ + return OVR_ALLOC(size); +} + + +OVR_NEW_OVERRIDE_INLINE void operator delete(void* p) OVR_THROW_SPEC_DELETE_NONE() +{ + OVR_FREE(p); +} + +OVR_NEW_OVERRIDE_INLINE void operator delete[](void* p) OVR_THROW_SPEC_DELETE_NONE() +{ + OVR_FREE(p); +} + + +OVR_NEW_OVERRIDE_INLINE void operator delete(void* p, std::nothrow_t&) OVR_THROW_SPEC_DELETE_NONE() +{ + OVR_FREE(p); +} + +OVR_NEW_OVERRIDE_INLINE void operator delete[](void* p, std::nothrow_t&) OVR_THROW_SPEC_DELETE_NONE() +{ + OVR_FREE(p); +} + + +OVR_NEW_OVERRIDE_INLINE void operator delete(void* p, const std::nothrow_t&) OVR_THROW_SPEC_DELETE_NONE() +{ + OVR_FREE(p); +} + +OVR_NEW_OVERRIDE_INLINE void operator delete[](void* p, const std::nothrow_t&) OVR_THROW_SPEC_DELETE_NONE() +{ + OVR_FREE(p); +} + + + +// The following new/delete overrides are required under VC++ because it defines the following operator new versions of its own. +#if defined(_MSC_VER) + +OVR_NEW_OVERRIDE_INLINE void* operator new(size_t n, const char* /*fileName*/, int /*line*/) +{ + return ::operator new(n); +} + +OVR_NEW_OVERRIDE_INLINE void* operator new[](size_t n, const char* /*fileName*/, int /*line*/) +{ + return ::operator new[](n); +} + +OVR_NEW_OVERRIDE_INLINE void operator delete(void* p, const char* /*fileName*/, int /*line*/) +{ + ::operator delete(p); +} + +OVR_NEW_OVERRIDE_INLINE void operator delete[](void* p, const char* /*fileName*/, int /*line*/) +{ + ::operator delete[](p); +} + +OVR_NEW_OVERRIDE_INLINE void* operator new(size_t n, int /*debug*/, const char* /*fileName*/, int /*line*/) +{ + return ::operator new (n); +} + +OVR_NEW_OVERRIDE_INLINE void* operator new[](size_t n, int /*debug*/, const char* /*fileName*/, int /*line*/) +{ + return ::operator new[](n); +} + +OVR_NEW_OVERRIDE_INLINE void __CRTDECL +operator delete(void* p, int /*debug*/, const char* /*fileName*/, int /*line*/) + OVR_THROW_SPEC_DELETE_NONE() { + ::operator delete(p); +} + +OVR_NEW_OVERRIDE_INLINE void __CRTDECL +operator delete[](void* p, int /*debug*/, const char* /*fileName*/, int /*line*/) + OVR_THROW_SPEC_DELETE_NONE() { + ::operator delete[](p); +} + +#endif + + + +#endif // OVR_NewOverride_inl diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Nullptr.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Nullptr.h new file mode 100644 index 0000000..9a6494f --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Nullptr.h @@ -0,0 +1,159 @@ +/************************************************************************************ + +Filename : OVR_Nullptr.h +Content : Implements C++11 nullptr for the case that the compiler doesn't. +Created : June 19, 2014 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Nullptr_h +#define OVR_Nullptr_h + +#pragma once + +#include "OVR_Types.h" + +//----------------------------------------------------------------------------------- +// ***** OVR_HAVE_std_nullptr_t +// +// Identifies if includes std::nullptr_t. +// +#if !defined(OVR_HAVE_std_nullptr_t) && defined(OVR_CPP11_ENABLED) +#if defined(OVR_STDLIB_LIBCPP) +#define OVR_HAVE_std_nullptr_t 1 +#elif defined(OVR_STDLIB_LIBSTDCPP) +#if (__GLIBCXX__ >= 20110325) && (__GLIBCXX__ != 20110428) && (__GLIBCXX__ != 20120702) +#define OVR_HAVE_std_nullptr_t 1 +#endif +#elif defined(_MSC_VER) && (_MSC_VER >= 1600) // VS2010+ +#define OVR_HAVE_std_nullptr_t 1 +#elif defined(__clang__) +#define OVR_HAVE_std_nullptr_t 1 +#elif defined(OVR_CPP_GNUC) && (OVR_CC_VERSION >= 406) // GCC 4.6+ +#define OVR_HAVE_std_nullptr_t 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** nullptr / std::nullptr_t +// +// Declares and defines nullptr and related types. +// +#if defined(OVR_CPP_NO_NULLPTR) +namespace std { +class nullptr_t { + public: + template + operator T*() const { + return 0; + } + + template + operator T C::*() const { + return 0; + } + +#if OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS + typedef void* (nullptr_t::*bool_)() + const; // 4.12,p1. We can't portably use operator bool(){ return false; } because bool + operator bool_() const // is convertable to int which breaks other required functionality. + { + return false; + } +#else + operator bool() const { + return false; + } +#endif + + private: + void operator&() const; // 5.2.10,p9 +}; + +inline nullptr_t nullptr_get() { + nullptr_t n = {}; + return n; +} + +#if !defined(nullptr) +#define nullptr nullptr_get() +#endif + +} // namespace std + +// 5.9,p2 p4 +// 13.6, p13 +template +inline bool operator==(T* pT, const std::nullptr_t) { + return pT == 0; +} + +template +inline bool operator==(const std::nullptr_t, T* pT) { + return pT == 0; +} + +template +inline bool operator==(const std::nullptr_t, T U::*pU) { + return pU == 0; +} + +template +inline bool operator==(T U::*pTU, const std::nullptr_t) { + return pTU == 0; +} + +inline bool operator==(const std::nullptr_t, const std::nullptr_t) { + return true; +} + +inline bool operator!=(const std::nullptr_t, const std::nullptr_t) { + return false; +} + +inline bool operator<(const std::nullptr_t, const std::nullptr_t) { + return false; +} + +inline bool operator<=(const std::nullptr_t, const std::nullptr_t) { + return true; +} + +inline bool operator>(const std::nullptr_t, const std::nullptr_t) { + return false; +} + +inline bool operator>=(const std::nullptr_t, const std::nullptr_t) { + return true; +} + +using std::nullptr_get; +using std::nullptr_t; + +// Some compilers natively support C++11 nullptr but the standard library being used +// doesn't declare std::nullptr_t, in which case we provide one ourselves. +#elif !defined(OVR_HAVE_std_nullptr_t) && !defined(OVR_CPP_NO_DECLTYPE) +namespace std { +typedef decltype(nullptr) nullptr_t; +} +#endif + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_RefCount.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_RefCount.cpp new file mode 100644 index 0000000..e319063 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_RefCount.cpp @@ -0,0 +1,90 @@ +/************************************************************************************ + +Filename : OVR_RefCount.cpp +Content : Reference counting implementation +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_RefCount.h" +#include "OVR_Atomic.h" + +namespace OVR { + +// ***** Reference Count Base implementation + +RefCountImplCore::~RefCountImplCore() { + // RefCount can be either 1 or 0 here. + // 0 if Release() was properly called. + // 1 if the object was declared on stack or as an aggregate. + OVR_ASSERT(RefCount <= 1); +} + +#ifdef OVR_BUILD_DEBUG +void RefCountImplCore::reportInvalidDelete(void* /*pmem*/) { + // Invalid delete call on ref-counted object. Please use Release() + OVR_FAIL(); +} +#endif + +RefCountNTSImplCore::~RefCountNTSImplCore() { + // RefCount can be either 1 or 0 here. + // 0 if Release() was properly called. + // 1 if the object was declared on stack or as an aggregate. + OVR_ASSERT(RefCount <= 1); +} + +#ifdef OVR_BUILD_DEBUG +void RefCountNTSImplCore::reportInvalidDelete(void* /*pmem*/) { + // Invalid delete call on ref-counted object. Please use Release() + OVR_FAIL(); +} +#endif + +// *** Thread-Safe RefCountImpl + +void RefCountImpl::AddRef() { + RefCount.fetch_add(1, std::memory_order_relaxed); +} +void RefCountImpl::Release() { + if (RefCount.fetch_add(-1, std::memory_order_relaxed) - 1 == 0) + delete this; +} + +// *** Thread-Safe RefCountVImpl w/virtual AddRef/Release + +void RefCountVImpl::AddRef() { + RefCount.fetch_add(1, std::memory_order_relaxed); +} +void RefCountVImpl::Release() { + if (RefCount.fetch_add(-1, std::memory_order_relaxed) - 1 == 0) + delete this; +} + +// *** NON-Thread-Safe RefCountImpl + +void RefCountNTSImpl::Release() const { + RefCount--; + if (RefCount == 0) + delete this; +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_RefCount.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_RefCount.h new file mode 100644 index 0000000..452cdf1 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_RefCount.h @@ -0,0 +1,495 @@ +/************************************************************************************ + +PublicHeader: Kernel +Filename : OVR_RefCount.h +Content : Reference counting implementation headers +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_RefCount_h +#define OVR_RefCount_h + +#include "OVR_Allocator.h" +#include "OVR_Types.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 RefCountBase; +template +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: + std::atomic RefCount = {1}; + + public: + // RefCountImpl constructor always initializes RefCount to 1 by default. + OVR_FORCE_INLINE RefCountImplCore() {} + + // 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 : virtual 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 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) + +#undef OVR_REFCOUNTALLOC_CHECK_DELETE + +#ifdef OVR_DEFINE_NEW +#define new OVR_DEFINE_NEW +#endif + // OVR_BUILD_DEFINE_NEW + // DOM-IGNORE-END +}; + +template +class RefCountBaseStatVImpl : virtual public Base { + public: + RefCountBaseStatVImpl() {} + +// *** Override New and Delete + +// DOM-IGNORE-BEGIN +// Undef new temporarily if it is being redefined +#ifdef OVR_DEFINE_NEW +#undef new +#endif + +#define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) + + // Redefine all new & delete operators. + OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE) + +#undef 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 RefCountBase : public RefCountBaseStatImpl { + public: + // Constructor. + OVR_FORCE_INLINE RefCountBase() : RefCountBaseStatImpl() {} +}; + +// RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release + +template +class RefCountBaseV : virtual public RefCountBaseStatVImpl { + public: + // Constructor. + OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatVImpl() {} +}; + +// 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 RefCountBaseNTS : public RefCountBaseStatImpl { + public: + // Constructor. + OVR_FORCE_INLINE RefCountBaseNTS() : RefCountBaseStatImpl() {} +}; + +//----------------------------------------------------------------------------------- +// ***** Ref-Counted template pointer +// +// Automatically AddRefs and Releases interfaces +// +// Note: Some of the member functions take C& as opposed to C* arguments: +// Ptr(C&) +// const Ptr& operator= (C&) +// Ptr& SetPtr(C&) +// These functions do not AddRef the assigned C& value, unlike the C* assignment +// functions. Thus the purpose of these functions is for the Ptr instance to +// assume ownership of a C reference count. Example usage: +// Ptr w = *new Widget; // Calls the Ptr(C&) constructor. Note that the Widget +// constructor sets initial refcount to 1. +// + +template +class Ptr { + protected: + C* pObject; + + public: + // Constructors + OVR_FORCE_INLINE Ptr() : pObject(0) {} + + // This constructor adopts the object's existing reference count rather than increment it. + OVR_FORCE_INLINE Ptr(C& robj) : pObject(&robj) {} + + OVR_FORCE_INLINE Ptr(C* pobj) { + if (pobj) + pobj->AddRef(); + pObject = pobj; + } + + OVR_FORCE_INLINE Ptr(const Ptr& src) { + if (src.pObject) + src.pObject->AddRef(); + pObject = src.pObject; + } + + template + OVR_FORCE_INLINE Ptr(Ptr& src) { + if (src) + src->AddRef(); + pObject = src; + } + + // 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 + OVR_FORCE_INLINE const Ptr& operator=(const Ptr& src) { + // By design we don't check for src == pObject, as we don't expect that to be the case the large + // majority of the time. + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + + // Specialization + OVR_FORCE_INLINE const Ptr& operator=(const Ptr& src) { + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + + OVR_FORCE_INLINE const Ptr& operator=(C* psrc) { + if (psrc) + psrc->AddRef(); + if (pObject) + pObject->Release(); + pObject = psrc; + return *this; + } + + // This operator adopts the object's existing reference count rather than increment it. + OVR_FORCE_INLINE const Ptr& operator=(C& src) { + if (pObject) + pObject->Release(); + pObject = &src; + return *this; + } + + // Set Assignment + template + OVR_FORCE_INLINE Ptr& SetPtr(const Ptr& src) { + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + // Specialization + OVR_FORCE_INLINE Ptr& SetPtr(const Ptr& src) { + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + + OVR_FORCE_INLINE Ptr& SetPtr(C* psrc) { + if (psrc) + psrc->AddRef(); + if (pObject) + pObject->Release(); + pObject = psrc; + return *this; + } + + // This function adopts the object's existing reference count rather than increment it. + OVR_FORCE_INLINE Ptr& SetPtr(C& src) { + if (pObject) + pObject->Release(); + pObject = &src; + return *this; + } + + // 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; + } +}; + +// LockedPtr +// +// Helper class to simplify thread-safety of the TrackingManager. +// It wraps the Ptr<> object it contains in a Lock. +template +class LockedPtr { + public: + LockedPtr(Lock* lock = nullptr) : TheLock(lock) {} + + void Set(T* value) { + OVR_ASSERT(TheLock); + TheLock->DoLock(); + Ptr oldPtr = ThePtr; // Keep a reference to the old ptr + ThePtr = value; // Change/decrement the old ptr (cannot die here due to oldPtr) + TheLock->Unlock(); + + // Release the old Ptr reference here, outside of the lock + // so that the object will not die while TheLock is held. + } + + template + void Get(Ptr& outputPtr) const { + OVR_ASSERT(TheLock); + TheLock->DoLock(); + Ptr retval = ThePtr; + TheLock->Unlock(); + outputPtr = retval; + } + + protected: + mutable Lock* TheLock; + Ptr ThePtr; +}; + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SharedMemory.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SharedMemory.cpp new file mode 100644 index 0000000..c8561c1 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SharedMemory.cpp @@ -0,0 +1,695 @@ +/************************************************************************************ + +Filename : OVR_SharedMemory.cpp +Content : Inter-process shared memory subsystem +Created : June 1, 2014 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_SharedMemory.h" +#include "Logging/Logging_Library.h" +#include "OVR_Array.h" +#include "OVR_Atomic.h" +#include "OVR_String.h" + +#if defined(OVR_OS_WIN32) +#include // ConvertStringSecurityDescriptorToSecurityDescriptor +#endif // OVR_OS_WIN32 + +#if defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) +#include // error results for mmap +#include // O_ constants +#include // shm_open(), mmap() +#include // mode constants +#include // close() +#endif // OVR_OS_LINUX + +OVR_DEFINE_SINGLETON(OVR::SharedMemoryFactory); + +namespace OVR { + +static ovrlog::Channel Logger("SharedMemory"); + +//----------------------------------------------------------------------------- +// SharedMemoryInternalBase + +class SharedMemoryInternalBase : public NewOverrideBase { + public: + SharedMemoryInternalBase() {} + virtual ~SharedMemoryInternalBase() {} + + virtual void* GetFileView() = 0; +}; + +//----------------------------------------------------------------------------- +// FakeMemoryBlock + +class FakeMemoryBlock : public RefCountBase { + String Name; + std::unique_ptr Data; + int SizeBytes; + int References; + + public: + FakeMemoryBlock(const String& name, int size) + : Name(name), Data(new char[size]), SizeBytes(size), References(1) {} + + bool IsNamed(const String& name) { + return Name.CompareNoCase(name) == 0; + } + void* GetData() { + return Data.get(); + } + int GetSizeI() { + return SizeBytes; + } + void IncrementReferences() { + ++References; + } + bool DecrementReferences() { + return --References <= 0; + } +}; + +class FakeMemoryInternal : public SharedMemoryInternalBase { + public: + void* FileView; + Ptr Block; + + FakeMemoryInternal(FakeMemoryBlock* block); + ~FakeMemoryInternal(); + + virtual void* GetFileView() override { + return FileView; + } +}; + +//----------------------------------------------------------------------------- +// FakeMemoryManager + +class FakeMemoryManager : public NewOverrideBase, public SystemSingletonBase { + OVR_DECLARE_SINGLETON(FakeMemoryManager); + + Lock FakeLock; + Array> FakeArray; + + public: + FakeMemoryInternal* Open(const char* name, int bytes, bool openOnly) { + Lock::Locker locker(&FakeLock); + + const int count = FakeArray.GetSizeI(); + for (int ii = 0; ii < count; ++ii) { + if (FakeArray[ii]->IsNamed(name)) { + FakeArray[ii]->IncrementReferences(); + return new FakeMemoryInternal(FakeArray[ii]); + } + } + + if (openOnly) { + return NULL; + } + + Ptr data = *new FakeMemoryBlock(name, bytes); + FakeArray.PushBack(data); + return new FakeMemoryInternal(data); + } + + void Free(FakeMemoryBlock* block) { + Lock::Locker locker(&FakeLock); + + const int count = FakeArray.GetSizeI(); + for (int ii = 0; ii < count; ++ii) { + if (FakeArray[ii].GetPtr() == block) { + // If the reference count hit zero, + if (FakeArray[ii]->DecrementReferences()) { + // Toast + FakeArray.RemoveAtUnordered(ii); + } + break; + } + } + } +}; + +FakeMemoryManager::FakeMemoryManager() { + // Must be at end of function + PushDestroyCallbacks(); +} + +FakeMemoryManager::~FakeMemoryManager() { + // If this assertion trips it is because we have not cleanly released shared memory resources. + OVR_ASSERT(FakeArray.GetSizeI() == 0); +} + +void FakeMemoryManager::OnSystemDestroy() { + delete this; +} + +FakeMemoryInternal::FakeMemoryInternal(FakeMemoryBlock* block) : Block(block) { + FileView = Block->GetData(); +} + +FakeMemoryInternal::~FakeMemoryInternal() { + FakeMemoryManager::GetInstance()->Free(Block); + Block.Clear(); +} + +} // namespace OVR + +OVR_DEFINE_SINGLETON(FakeMemoryManager); + +namespace OVR { + +static SharedMemoryInternalBase* CreateFakeSharedMemory( + const SharedMemory::OpenParameters& params) { + return FakeMemoryManager::GetInstance()->Open( + params.globalName, params.minSizeBytes, params.openMode == SharedMemory::OpenMode_OpenOnly); +} + +//// Windows version + +#if defined(OVR_OS_WIN32) + +#pragma comment(lib, "advapi32.lib") + +// Hidden implementation class for OS-specific behavior +class SharedMemoryInternal : public SharedMemoryInternalBase { + public: + HANDLE FileMapping; + void* FileView; + + SharedMemoryInternal(HANDLE fileMapping, void* fileView) + : FileMapping(fileMapping), FileView(fileView) {} + + ~SharedMemoryInternal() { + // If file view is set, + if (FileView) { + UnmapViewOfFile(FileView); + FileView = NULL; + } + + // If file mapping is set, + if (FileMapping != NULL) { + CloseHandle(FileMapping); + FileMapping = NULL; + } + } + + virtual void* GetFileView() override { + return FileView; + } +}; + +static SharedMemoryInternal* +DoFileMap(HANDLE hFileMapping, const char* fileName, bool openReadOnly, int minSize) { + // Interpret the access mode as a map desired access code + DWORD mapDesiredAccess = openReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE; + + // Map view of the file to this process + void* pFileView = MapViewOfFile(hFileMapping, mapDesiredAccess, 0, 0, minSize); + + // If mapping could not be created, + if (!pFileView) { + CloseHandle(hFileMapping); + + Logger.LogDebugF( + "FAILURE: Unable to map view of file for %s error code = %d", fileName, GetLastError()); + OVR_UNUSED(fileName); + return NULL; + } + + // Create internal representation + SharedMemoryInternal* pimple = new SharedMemoryInternal(hFileMapping, pFileView); + + // If memory allocation fails, + if (!pimple) { + UnmapViewOfFile(pFileView); + CloseHandle(hFileMapping); + + Logger.LogDebugF("FAILURE: Out of memory"); + return NULL; + } + + return pimple; +} + +static SharedMemoryInternal* +AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly) { + // Interpret the access mode as a map desired access code + DWORD mapDesiredAccess = openReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE; + + // Open file mapping + std::wstring wFileName = UTF8StringToUCSString(fileName); + HANDLE hFileMapping = OpenFileMappingW(mapDesiredAccess, TRUE, wFileName.c_str()); + + // If file was mapped unsuccessfully, + if (NULL == hFileMapping) { + Logger.LogTraceF( + "WARNING: Unable to open file mapping for %s error code = %d (not necessarily bad)", + fileName, + GetLastError()); + return NULL; + } + + // Map the file + return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); +} + +static SharedMemoryInternal* AttemptCreateSharedMemory( + const char* fileName, + int minSize, + bool openReadOnly, + bool allowRemoteWrite) { + // Prepare a SECURITY_ATTRIBUTES object + SECURITY_ATTRIBUTES security; + ZeroMemory(&security, sizeof(security)); + security.nLength = sizeof(security); + + // Security descriptor by DACL strings: + // ACE strings grant Allow(A), Object/Contains Inheritance (OICI) of: + // + Grant All (GA) to System (SY) + // + Grant All (GA) to Built-in Administrators (BA) + // + Grant Read-Only (GR) or Read-Write (GWGR) to Interactive Users (IU) - ie. games + // For well-known SIDs (misdocumented as ALL_APP_PACKAGES) see: + // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/81d92bba-d22b-4a8c-908a-554ab29148ab + static const wchar_t* DACLString_ReadOnly = + L"D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GR;;;IU)" + // To do: Remove this Minecraft-specific SID, ALL APPLICATION PACKAGES should suffice. + L"(A;OICI;GR;;;S-1-15-3-191680118-1275207936-1426169489-1705429854)" + // ALL APPLICATION PACKAGES + L"(A;OICI;GR;;;S-1-15-2-1)"; + static const wchar_t* DACLString_ReadWrite = + L"D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GWGR;;;IU)" + // To do: Remove this Minecraft-specific SID, ALL APPLICATION PACKAGES should suffice. + L"(A;OICI;GWGR;;;S-1-15-3-191680118-1275207936-1426169489-1705429854)" + // ALL APPLICATION PACKAGES + L"(A;OICI;GWGR;;;S-1-15-2-1)"; + + // HACK: https://our.intern.facebook.com/intern/tasks/?t=10698852 + // The extra SIDs above give access to our named pipe to UWP apps + + // Select the remote process access mode + const wchar_t* remoteAccessString = allowRemoteWrite ? DACLString_ReadWrite : DACLString_ReadOnly; + + // Attempt to convert access string to security attributes + // Note: This will allocate the security descriptor with LocalAlloc() and must be freed later + BOOL bConvertOkay = ConvertStringSecurityDescriptorToSecurityDescriptorW( + remoteAccessString, SDDL_REVISION_1, &security.lpSecurityDescriptor, NULL); + + // If conversion fails, + if (!bConvertOkay) { + Logger.LogDebugF("FAILURE: Unable to convert access string, error code = %d", GetLastError()); + return NULL; + } + + // Interpret the access mode as a page protection code + int pageProtectCode = openReadOnly ? PAGE_READONLY : PAGE_READWRITE; + + std::wstring wFileName = UTF8StringToUCSString(fileName); + + // Attempt to create a file mapping + HANDLE hFileMapping = CreateFileMappingW( + INVALID_HANDLE_VALUE, // From page file + &security, // Security attributes + pageProtectCode, // Read-only? + 0, // High word for size = 0 + minSize, // Low word for size + wFileName.c_str()); // Name of global shared memory file + + // Free the security descriptor buffer + LocalFree(security.lpSecurityDescriptor); + + // If mapping could not be created, + if (NULL == hFileMapping) { + Logger.LogDebugF( + "FAILURE: Unable to create file mapping for %s error code = %d", fileName, GetLastError()); + return NULL; + } + +#ifndef OVR_ALLOW_CREATE_FILE_MAPPING_IF_EXISTS + // If the file mapping already exists, + if (GetLastError() == ERROR_ALREADY_EXISTS) { + CloseHandle(hFileMapping); + + Logger.LogDebugF("FAILURE: File mapping at %s already exists", fileName); + return NULL; + } +#endif + + // Map the file + return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); +} + +static SharedMemoryInternal* CreateSharedMemory(const SharedMemory::OpenParameters& params) { + SharedMemoryInternal* retval = NULL; + + // Construct the file mapping name in a Windows-specific way + OVR::String fileMappingName = params.globalName; + const char* fileName = fileMappingName.ToCStr(); + + // Is being opened read-only? + const bool openReadOnly = (params.accessMode == SharedMemory::AccessMode_ReadOnly); + + // Try up to 3 times to reduce low-probability failures: + static const int ATTEMPTS_MAX = 3; + for (int attempts = 0; attempts < ATTEMPTS_MAX; ++attempts) { + // If opening should be attempted first, + if (params.openMode != SharedMemory::OpenMode_CreateOnly) { + // Attempt to open a shared memory map + retval = AttemptOpenSharedMemory(fileName, params.minSizeBytes, openReadOnly); + + // If successful, + if (retval) { + // Done! + break; + } + } + + // If creating the shared memory is also acceptable, + if (params.openMode != SharedMemory::OpenMode_OpenOnly) { + // Interpret create mode + const bool allowRemoteWrite = (params.remoteMode == SharedMemory::RemoteMode_ReadWrite); + + // Attempt to create a shared memory map + retval = + AttemptCreateSharedMemory(fileName, params.minSizeBytes, openReadOnly, allowRemoteWrite); + + // If successful, + if (retval) { + // Done! + break; + } + } + } // Re-attempt create/open + + // Note: On Windows the initial contents of the region are guaranteed to be zero. + return retval; +} + +#endif // OVR_OS_WIN32 + +#if (defined(OVR_OS_LINUX) || defined(OVR_OS_MAC)) + +// Hidden implementation class for OS-specific behavior +class SharedMemoryInternal : public SharedMemoryInternalBase { + public: + int FileMapping; + void* FileView; + int FileSize; + + SharedMemoryInternal(int fileMapping, void* fileView, int fileSize) + : FileMapping(fileMapping), FileView(fileView), FileSize(fileSize) {} + + virtual ~SharedMemoryInternal() { + // If file view is set, + if (FileView) { + munmap(FileView, FileSize); + FileView = MAP_FAILED; + } + + // If file mapping is set, + if (FileMapping >= 0) { + close(FileMapping); + FileMapping = -1; + } + } + + virtual void* GetFileView() override { + return FileView; + } +}; + +static SharedMemoryInternal* +DoFileMap(int hFileMapping, const char* fileName, bool openReadOnly, int minSize) { + // Calculate the required flags based on read/write mode + int prot = openReadOnly ? PROT_READ : (PROT_READ | PROT_WRITE); + + // Map the file view + void* pFileView = mmap(NULL, minSize, prot, MAP_SHARED, hFileMapping, 0); + + if (pFileView == MAP_FAILED) { + close(hFileMapping); + + Logger.LogDebugF("FAILURE: Unable to map view of file for %s error code = %d", fileName, errno); + OVR_UNUSED(fileName); + return NULL; + } + + // Create internal representation + SharedMemoryInternal* pimple = new SharedMemoryInternal(hFileMapping, pFileView, minSize); + + // If memory allocation fails, + if (!pimple) { + munmap(pFileView, minSize); + close(hFileMapping); + + Logger.LogDebugF("FAILURE: Out of memory"); + return NULL; + } + + return pimple; +} + +static SharedMemoryInternal* +AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly) { + // Calculate permissions and flags based on read/write mode + int flags = openReadOnly ? O_RDONLY : O_RDWR; + int perms = openReadOnly ? S_IRUSR : (S_IRUSR | S_IWUSR); + + // Attempt to open the shared memory file + int hFileMapping = shm_open(fileName, flags, perms); + + // If file was not opened successfully, + if (hFileMapping < 0) { + Logger.LogDebugF( + "WARNING: Unable to open file mapping for %s error code = %d (not necessarily bad)", + fileName, + errno); + return NULL; + } + + // Map the file + return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); +} + +static SharedMemoryInternal* AttemptCreateSharedMemory( + const char* fileName, + int minSize, + bool openReadOnly, + bool allowRemoteWrite) { + // Create mode + // Note: Cannot create the shared memory file read-only because then ftruncate() will fail. + int flags = O_CREAT | O_RDWR; + +#ifndef OVR_ALLOW_CREATE_FILE_MAPPING_IF_EXISTS + // Require exclusive access when creating (seems like a good idea without trying it yet..) + if (shm_unlink(fileName) < 0) { + Logger.LogDebugF( + "WARNING: Unable to unlink shared memory file %s error code = %d", fileName, errno); + } + flags |= O_EXCL; +#endif + + // Set own read/write permissions + int perms = openReadOnly ? S_IRUSR : (S_IRUSR | S_IWUSR); + + // Allow other users to read/write the shared memory file + perms |= allowRemoteWrite ? (S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH) : (S_IRGRP | S_IROTH); + + // Attempt to open the shared memory file + int hFileMapping = shm_open(fileName, flags, perms); + + // If file was not opened successfully, + if (hFileMapping < 0) { + Logger.LogDebugF( + "FAILURE: Unable to create file mapping for %s error code = %d", fileName, errno); + return NULL; + } + + int truncRes = ftruncate(hFileMapping, minSize); + + // If file was not opened successfully, + if (truncRes < 0) { + close(hFileMapping); + Logger.LogDebugF( + "FAILURE: Unable to truncate file for %s to %d error code = %d", fileName, minSize, errno); + return NULL; + } + + // Map the file + return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); +} + +static SharedMemoryInternal* CreateSharedMemory(const SharedMemory::OpenParameters& params) { + SharedMemoryInternal* retval = NULL; + + // Construct the file mapping name in a Linux-specific way + OVR::String fileMappingName = "/"; + fileMappingName += params.globalName; + const char* fileName = fileMappingName.ToCStr(); + + // Is being opened read-only? + const bool openReadOnly = (params.accessMode == SharedMemory::AccessMode_ReadOnly); + + // Try up to 3 times to reduce low-probability failures: + static const int ATTEMPTS_MAX = 3; + for (int attempts = 0; attempts < ATTEMPTS_MAX; ++attempts) { + // If opening should be attempted first, + if (params.openMode != SharedMemory::OpenMode_CreateOnly) { + // Attempt to open a shared memory map + retval = AttemptOpenSharedMemory(fileName, params.minSizeBytes, openReadOnly); + + // If successful, + if (retval) { + // Done! + break; + } + } + + // If creating the shared memory is also acceptable, + if (params.openMode != SharedMemory::OpenMode_OpenOnly) { + // Interpret create mode + const bool allowRemoteWrite = (params.remoteMode == SharedMemory::RemoteMode_ReadWrite); + + // Attempt to create a shared memory map + retval = + AttemptCreateSharedMemory(fileName, params.minSizeBytes, openReadOnly, allowRemoteWrite); + + // If successful, + if (retval) { + // Done! + break; + } + } + } // Re-attempt create/open + + // Note: On Windows the initial contents of the region are guaranteed to be zero. + return retval; +} + +#endif // OVR_OS_LINUX + +//----------------------------------------------------------------------------- +// SharedMemory + +static bool FakingSharedMemory = false; + +void SharedMemory::SetFakeSharedMemory(bool enabled) { + FakingSharedMemory = enabled; +} + +bool SharedMemory::IsFakingSharedMemory() { + return FakingSharedMemory; +} + +SharedMemory::SharedMemory( + int size, + void* data, + const String& name, + SharedMemoryInternalBase* pInternal) + : Size(size), Data(data), Name(name), Internal(pInternal) {} + +SharedMemory::~SharedMemory() { + // Call close when it goes out of scope + Close(); + delete Internal; +} + +void SharedMemory::Close() { + if (Internal) { + delete Internal; + Internal = NULL; + } +} + +//----------------------------------------------------------------------------- +// SharedMemoryFactory + +Ptr SharedMemoryFactory::Open(const SharedMemory::OpenParameters& params) { + Ptr retval; + + // Return if no name specified or invalid size requested + // 0 is a valid option, it means 'map the whole region' + // In this case, the client must know the valid size of the region + if (!params.globalName || (params.minSizeBytes < 0)) { + Logger.LogDebug("FAILURE: Invalid parameters to Create()"); + return NULL; + } + +#ifdef OVR_BUILD_DEBUG + if (Logger.GetMinimumOutputLevel() <= ovrlog::Level::Trace) { + const char* OpType = "{Unknown}"; + switch (params.openMode) { + case SharedMemory::OpenMode_CreateOnly: + OpType = "Creating"; + break; + case SharedMemory::OpenMode_CreateOrOpen: + OpType = "Creating/Opening"; + break; + case SharedMemory::OpenMode_OpenOnly: + OpType = "Opening"; + break; + default: + OVR_ASSERT(false); + break; + } + + Logger.LogTraceF( + "%s shared memory region: %s > %d bytes", OpType, params.globalName, params.minSizeBytes); + } +#endif + + // Attempt to create a shared memory region from the parameters + SharedMemoryInternalBase* pInternal; + if (SharedMemory::IsFakingSharedMemory()) { + pInternal = CreateFakeSharedMemory(params); + } else { + pInternal = CreateSharedMemory(params); + } + + if (pInternal) { + // Create the wrapper object + retval = *new SharedMemory( + params.minSizeBytes, pInternal->GetFileView(), params.globalName, pInternal); + } + + return retval; +} + +SharedMemoryFactory::SharedMemoryFactory() { + Logger.LogDebug("Creating factory"); + + FakeMemoryManager::GetInstance(); // Make sure the fake memory manager is destroyed at the right + // time + + // Must be at end of function + PushDestroyCallbacks(); +} + +SharedMemoryFactory::~SharedMemoryFactory() { + Logger.LogDebug("Destroying factory"); +} + +void SharedMemoryFactory::OnSystemDestroy() { + delete this; +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SharedMemory.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SharedMemory.h new file mode 100644 index 0000000..15a2e08 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SharedMemory.h @@ -0,0 +1,229 @@ +/************************************************************************************ + +PublicHeader: OVR +Filename : OVR_SharedMemory.h +Content : Inter-process shared memory subsystem +Created : June 1, 2014 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_SharedMemory_h +#define OVR_SharedMemory_h + +#include "OVR_Allocator.h" +#include "OVR_RefCount.h" +#include "OVR_String.h" +#include "OVR_System.h" +#include "OVR_Types.h" + +namespace OVR { + +class SharedMemoryInternalBase; // Opaque + +// SharedMemory +// Note: Safe when used between 32-bit and 64-bit processes +class SharedMemory : public RefCountBase { + friend class SharedMemoryFactory; + + OVR_NON_COPYABLE(SharedMemory); + + public: + // Only constructed by the SharedMemory Factory + SharedMemory(int size, void* data, const String& name, SharedMemoryInternalBase* pInternal); + // Call close when it goes out of scope + ~SharedMemory(); + + // Modes for opening a new shared memory region + enum OpenMode { + // Note: On Windows, Create* requires Administrator priviledges or running as a Service. + OpenMode_CreateOnly, // Must not already exist + OpenMode_OpenOnly, // Must already exist + OpenMode_CreateOrOpen // May exist or not + }; + + // Local access restrictions + enum AccessMode { + AccessMode_ReadOnly, // Acquire read-only access + AccessMode_ReadWrite, // Acquire read or write access + }; + + // Remote access restrictions + enum RemoteMode { + RemoteMode_ReadOnly, // Other processes will need to open in read-only mode + RemoteMode_ReadWrite // Other processes can open in read-write mode + }; + + // Modes for opening a new shared memory region + struct OpenParameters { + OpenParameters() + : globalName(NULL), + minSizeBytes(0), + openMode(SharedMemory::OpenMode_CreateOrOpen), + remoteMode(SharedMemory::RemoteMode_ReadWrite), + accessMode(SharedMemory::AccessMode_ReadWrite) {} + + // Creation parameters + const char* globalName; // Name of the shared memory region + int minSizeBytes; // Minimum number of bytes to request + SharedMemory::OpenMode openMode; // Creating the file or opening the file? + SharedMemory::RemoteMode remoteMode; // When creating, what access should other processes get? + SharedMemory::AccessMode + accessMode; // When opening/creating, what access should this process get? + }; + + public: + // Returns the size of the shared memory region + int GetSizeI() const { + return Size; + } + + // Returns the process-local pointer to the shared memory region + // Note: This may be different on different processes + void* GetData() const { + return Data; + } + + // Returns the name of the shared memory region + String GetName() { + return Name; + } + + protected: + int Size; // How many shared bytes are shared at the pointer address? + void* Data; // Pointer to the shared memory region. + String Name; // Name that can be used to access this region + + // Hidden implementation class for OS-specific behavior + SharedMemoryInternalBase* Internal; + + // Close and cleanup the shared memory region + // Note: This is called on destruction + void Close(); + + public: + static void SetFakeSharedMemory(bool enabled); + static bool IsFakingSharedMemory(); +}; + +// SharedMemoryFactory +class SharedMemoryFactory : public NewOverrideBase, + public SystemSingletonBase { + OVR_DECLARE_SINGLETON(SharedMemoryFactory); + + public: + // Construct a SharedMemory object. + // Note: The new object is reference-counted so it should be stored with Ptr<>. Initial reference + // count is 1. + Ptr Open(const SharedMemory::OpenParameters&); +}; + +// A shared object +// Its constructor will be called when creating a writer +// Its destructor will not be called +template +class ISharedObject : public RefCountBase> { + public: + static const int RegionSize = (int)sizeof(SharedType); + + protected: + Ptr pSharedMemory; + + bool Open(const char* name, bool readOnly) { + // Configure open parameters based on read-only mode + SharedMemory::OpenParameters params; + + // FIXME: This is a hack. We currently need to allow clients to open this for read-write even + // though they only need read-only access. This is because in the first 0.4 release the + // LocklessUpdater class technically writes to it (increments by 0) to read from the space. + // This was quickly corrected in 0.4.1 and we are waiting for the right time to disallow write + // access when everyone upgrades to 0.4.1+. + // params.remoteMode = SharedMemory::RemoteMode_ReadOnly; + params.remoteMode = SharedMemory::RemoteMode_ReadWrite; + params.globalName = name; + params.accessMode = + readOnly ? SharedMemory::AccessMode_ReadOnly : SharedMemory::AccessMode_ReadWrite; + params.minSizeBytes = RegionSize; + params.openMode = + readOnly ? SharedMemory::OpenMode_OpenOnly : SharedMemory::OpenMode_CreateOrOpen; + + // Attempt to open the shared memory file + pSharedMemory = SharedMemoryFactory::GetInstance()->Open(params); + + // If it was not able to be opened, + if (pSharedMemory && pSharedMemory->GetSizeI() >= RegionSize && pSharedMemory->GetData()) { + // If writing, + if (!readOnly) { + // Construct the object also + Construct(pSharedMemory->GetData()); + } + + return true; + } + + return false; + } + + SharedType* Get() const { + if (!pSharedMemory) { + return NULL; + } + + void* data = pSharedMemory->GetData(); + if (!data) { + return NULL; + } + + return reinterpret_cast(data); + } + + public: + String GetName() const { + return pSharedMemory ? pSharedMemory->GetName() : String{""}; + } +}; + +// Writer specialized shared object: Ctor will be called on Open() +template +class SharedObjectWriter : public ISharedObject { + public: + OVR_FORCE_INLINE bool Open(const char* name) { + return ISharedObject::Open(name, false); + } + OVR_FORCE_INLINE SharedType* Get() { + return ISharedObject::Get(); + } +}; + +// Reader specialized shared object: Ctor will not be called +template +class SharedObjectReader : public ISharedObject { + public: + OVR_FORCE_INLINE bool Open(const char* name) { + return ISharedObject::Open(name, true); + } + OVR_FORCE_INLINE const SharedType* Get() const { + return ISharedObject::Get(); + } +}; + +} // namespace OVR + +#endif // OVR_SharedMemory_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Std.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Std.cpp new file mode 100644 index 0000000..2444233 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Std.cpp @@ -0,0 +1,1225 @@ +/************************************************************************************ + +Filename : OVR_Std.cpp +Content : Standard C function implementation +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Std.h" +#include "OVR_Alg.h" + +// localeconv() call in OVR_strtod() +#include + +namespace OVR { + +// Source for functions not available on all platforms is included here. + +const char* OVR_CDECL OVR_strrchr(const char* pString, int c) { + const char* pFound = nullptr; + + for (char cCurrent; cCurrent = *pString, cCurrent != '\0'; ++pString) { + if (cCurrent == c) + pFound = pString; + } + + if (pFound) + return pFound; + + if (c == '\0') + return pString; + + return nullptr; +} + +char* OVR_CDECL OVR_stristr(const char* s1, const char* s2) { + const char* cp = s1; + + if (!*s2) + return (char*)s1; + + while (*cp) { + const char* s = cp; + const char* t = s2; + + while (*s && *t && (tolower((uint8_t)*s) == tolower((uint8_t)*t))) + ++s, ++t; + + if (*t == 0) + return const_cast(cp); + ++cp; + } + + return 0; +} + +wchar_t* OVR_CDECL OVR_stristr(const wchar_t* s1, const wchar_t* s2) { + const wchar_t* cp = s1; + + if (!*s2) + return (wchar_t*)s1; + + while (*cp) { + const wchar_t* s = cp; + const wchar_t* t = s2; + + while (*s && *t && (towlower(*s) == towlower(*t))) + ++s, ++t; + + if (*t == 0) + return const_cast(cp); + ++cp; + } + + return 0; +} + +size_t OVR_CDECL OVR_strlcpy(char* dest, const char* src, size_t destsize) { + const char* s = src; + size_t n = destsize; + + if (n && --n) { + do { + if ((*dest++ = *s++) == 0) + break; + } while (--n); + } + + if (!n) { + if (destsize) + *dest = 0; + while (*s++) { + } + } + + return (size_t)((s - src) - 1); +} + +size_t OVR_CDECL OVR_strlcpy(wchar_t* dest, const wchar_t* src, size_t destsize) { + const wchar_t* s = src; + size_t n = destsize; + + if (n && --n) { + do { + if ((*dest++ = *s++) == 0) + break; + } while (--n); + } + + if (!n) { + if (destsize) + *dest = 0; + while (*s++) { + } + } + + return (size_t)((s - src) - 1); +} + +size_t OVR_CDECL OVR_strlcat(char* dest, const char* src, size_t destsize) { + const size_t d = destsize ? OVR_strlen(dest) : 0; + const size_t s = OVR_strlen(src); + const size_t t = s + d; + + OVR_ASSERT((destsize == 0) || (d < destsize)); + + if (t < destsize) + memcpy(dest + d, src, (s + 1) * sizeof(*src)); + else { + if (destsize) { + memcpy(dest + d, src, ((destsize - d) - 1) * sizeof(*src)); + dest[destsize - 1] = 0; + } + } + + return t; +} + +size_t OVR_CDECL OVR_strlcat(wchar_t* dest, const wchar_t* src, size_t destsize) { + const size_t d = destsize ? OVR_strlen(dest) : 0; + const size_t s = OVR_strlen(src); + const size_t t = s + d; + + OVR_ASSERT((destsize == 0) || (d < destsize)); + + if (t < destsize) + memcpy(dest + d, src, (s + 1) * sizeof(*src)); + else { + if (destsize) { + memcpy(dest + d, src, ((destsize - d) - 1) * sizeof(*src)); + dest[destsize - 1] = 0; + } + } + + return t; +} + +// Case insensitive compare implemented in platform-specific way. +int OVR_CDECL OVR_stricmp(const char* a, const char* b) { +#if defined(OVR_OS_MS) +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_stricmp(a, b); +#else + return ::stricmp(a, b); +#endif + +#else + return strcasecmp(a, b); +#endif +} + +int OVR_CDECL OVR_strnicmp(const char* a, const char* b, size_t count) { +#if defined(OVR_OS_MS) +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_strnicmp(a, b, count); +#else + return ::strnicmp(a, b, count); +#endif + +#else + return strncasecmp(a, b, count); +#endif +} + +wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, size_t destsize, const wchar_t* src) { +#if defined(OVR_MSVC_SAFESTRING) + wcscpy_s(dest, destsize, src); + return dest; +#elif defined(OVR_OS_MS) + OVR_UNUSED(destsize); + wcscpy(dest, src); + return dest; +#else + size_t l = OVR_wcslen(src) + 1; // incl term null + l = (l < destsize) ? l : destsize; + memcpy(dest, src, l * sizeof(wchar_t)); + return dest; +#endif +} + +wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, size_t destsize, const wchar_t* src, size_t count) { +#if defined(OVR_MSVC_SAFESTRING) + wcsncpy_s(dest, destsize, src, count); + return dest; +#else + size_t srclen = OVR_wcslen(src); + size_t l = Alg::Min(srclen, count); + l = (l < destsize) ? l : destsize; + memcpy(dest, src, l * sizeof(wchar_t)); + if (count > srclen) { + size_t remLen = Alg::Min(destsize - l, (count - srclen)); + memset(&dest[l], 0, sizeof(wchar_t) * remLen); + } else if (l < destsize) + dest[l] = 0; + return dest; +#endif +} + +wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src) { +#if defined(OVR_MSVC_SAFESTRING) + wcscat_s(dest, destsize, src); + return dest; +#elif defined(OVR_OS_MS) + OVR_UNUSED(destsize); + wcscat(dest, src); + return dest; +#else + size_t dstlen = OVR_wcslen(dest); // do not incl term null + size_t srclen = OVR_wcslen(src) + 1; // incl term null + size_t copylen = (dstlen + srclen < destsize) ? srclen : destsize - dstlen; + memcpy(dest + dstlen, src, copylen * sizeof(wchar_t)); + return dest; +#endif +} + +size_t OVR_CDECL OVR_wcslen(const wchar_t* str) { +#if defined(OVR_OS_MS) + return wcslen(str); +#else + size_t i = 0; + while (str[i] != '\0') + ++i; + return i; +#endif +} + +int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b) { +#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) + return wcscmp(a, b); +#else + // not supported, use custom implementation + const wchar_t *pa = a, *pb = b; + while (*pa && *pb) { + wchar_t ca = *pa; + wchar_t cb = *pb; + if (ca < cb) + return -1; + else if (ca > cb) + return 1; + pa++; + pb++; + } + if (*pa) + return 1; + else if (*pb) + return -1; + else + return 0; +#endif +} + +int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b) { +#if defined(OVR_OS_MS) +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_wcsicmp(a, b); +#else + return ::wcsicmp(a, b); +#endif +#elif defined(OVR_OS_MAC) || defined(__CYGWIN__) || defined(OVR_OS_ANDROID) || \ + defined(OVR_OS_IPHONE) + // not supported, use custom implementation + const wchar_t *pa = a, *pb = b; + while (*pa && *pb) { + wchar_t ca = OVR_towlower(*pa); + wchar_t cb = OVR_towlower(*pb); + if (ca < cb) + return -1; + else if (ca > cb) + return 1; + pa++; + pb++; + } + if (*pa) + return 1; + else if (*pb) + return -1; + else + return 0; +#else + return wcscasecmp(a, b); +#endif +} + +// This function is not inline because of dependency on +double OVR_CDECL OVR_strtod(const char* str, char** tailptr) { +#if !defined(OVR_OS_ANDROID) // The Android C library doesn't have localeconv. + const char s = *localeconv()->decimal_point; + + // Always do the locale switch to spot problem files early. + { + // I don't know why 347, that's just what was in this code before I got here. + const int MaxStringLength = 347; + OVR_ASSERT(OVR_strlen(str) <= MaxStringLength); + char buffer[MaxStringLength + 1]; + OVR_strcpy(buffer, sizeof(buffer), str); + + // Ensure null-termination of string + buffer[sizeof(buffer) - 1] = '\0'; + + for (char* c = buffer; *c != '\0'; ++c) { + if (*c == '.') { + *c = s; + break; + } + } + + char* nextPtr = NULL; + double retval = strtod(buffer, &nextPtr); + + // If a tail pointer is requested, + if (tailptr) { + // Return a tail pointer that points to the same offset as nextPtr, in the orig string + *tailptr = !nextPtr ? NULL : (char*)str + (int)(nextPtr - buffer); + } + + return retval; + } +#else + return strtod(str, tailptr); +#endif +} + +#ifndef OVR_NO_WCTYPE + +//// Use this class to generate Unicode bitsets. For example: +//// +//// UnicodeBitSet bitSet; +//// for(unsigned i = 0; i < 65536; ++i) +//// { +//// if (iswalpha(i)) +//// bitSet.Set(i); +//// } +//// bitSet.Dump(); +//// +////--------------------------------------------------------------- +// class UnicodeBitSet +//{ +// public: +// UnicodeBitSet() +// { +// memset(Offsets, 0, sizeof(Offsets)); +// memset(Bits, 0, sizeof(Bits)); +// } +// +// void Set(unsigned bit) { Bits[bit >> 8][(bit >> 4) & 15] |= 1 << (bit & 15); } +// +// void Dump() +// { +// unsigned i, j; +// unsigned offsetCount = 0; +// for(i = 0; i < 256; ++i) +// { +// if (isNull(i)) Offsets[i] = 0; +// else +// if (isFull(i)) Offsets[i] = 1; +// else Offsets[i] = uint16_t(offsetCount++ * 16 + 256); +// } +// for(i = 0; i < 16; ++i) +// { +// for(j = 0; j < 16; ++j) +// { +// printf("%5u,", Offsets[i*16+j]); +// } +// printf("\n"); +// } +// for(i = 0; i < 256; ++i) +// { +// if (Offsets[i] > 255) +// { +// for(j = 0; j < 16; j++) +// { +// printf("%5u,", Bits[i][j]); +// } +// printf("\n"); +// } +// } +// } +// +// private: +// bool isNull(unsigned n) const +// { +// const uint16_t* p = Bits[n]; +// for(unsigned i = 0; i < 16; ++i) +// if (p[i] != 0) return false; +// return true; +// } +// +// bool isFull(unsigned n) const +// { +// const uint16_t* p = Bits[n]; +// for(unsigned i = 0; i < 16; ++i) +// if (p[i] != 0xFFFF) return false; +// return true; +// } +// +// uint16_t Offsets[256]; +// uint16_t Bits[256][16]; +//}; + +const uint16_t UnicodeAlnumBits[] = { + 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, + 432, 448, 464, 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, + 0, 0, 0, 0, 608, 624, 640, 656, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 672, 688, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 704, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 720, 1, 1, 1, 1, 736, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 768, 784, 1, 800, 816, 832, 0, 0, 0, 1023, + 65534, 2047, 65534, 2047, 0, 0, 0, 524, 65535, 65407, 65535, 65407, 65535, + 65535, 65532, 15, 0, 65535, 65535, 65535, 65535, 65535, 16383, 63999, 3, 0, + 16415, 0, 0, 0, 0, 0, 32, 0, 0, 1024, 55104, 65535, 65531, + 65535, 32767, 64767, 65535, 15, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 61443, 65535, 65535, 65535, 6559, 65535, 65535, 831, 0, 0, 0, 65534, 65535, + 639, 65534, 65535, 255, 0, 0, 0, 0, 65535, 2047, 7, 0, 0, + 65534, 2047, 65534, 63, 1023, 65535, 65535, 65535, 65535, 65535, 65535, 8175, 8702, + 8191, 0, 65535, 8191, 65535, 0, 0, 0, 0, 65535, 65535, 65535, 1, + 0, 0, 0, 0, 65518, 65535, 65535, 58367, 8191, 65281, 65487, 0, 40942, + 65529, 65023, 50117, 6559, 45184, 65487, 3, 34788, 65529, 65023, 50029, 6535, 24064, + 65472, 31, 45038, 65531, 65023, 58349, 7103, 1, 65473, 0, 40942, 65529, 65023, + 58317, 6543, 45248, 65475, 0, 51180, 54845, 50968, 50111, 7623, 128, 65408, 0, + 57326, 65533, 65023, 50159, 7647, 96, 65475, 0, 57324, 65533, 65023, 50159, 7647, + 16480, 65475, 0, 57324, 65533, 65023, 50175, 7631, 128, 65475, 0, 65516, 64639, + 65535, 12283, 32895, 65375, 0, 12, 65534, 65535, 65535, 2047, 32767, 1023, 0, + 0, 9622, 65264, 60590, 15359, 8223, 13311, 0, 0, 1, 0, 1023, 0, + 65279, 65535, 2047, 65534, 3843, 65279, 65535, 8191, 0, 0, 0, 0, 65535, + 65535, 63227, 327, 1023, 1023, 0, 0, 0, 0, 65535, 65535, 63, 65535, + 65535, 127, 65535, 65535, 65535, 65535, 65535, 33791, 65535, 65535, 65535, 65535, 65287, + 65535, 65535, 65535, 65535, 1023, 65407, 65535, 65535, 65535, 15743, 15743, 65535, 65535, + 15743, 65535, 32767, 32573, 32573, 65407, 32767, 65535, 32767, 32573, 65535, 65535, 65407, + 2047, 65024, 3, 0, 0, 65535, 65535, 65535, 65535, 65535, 31, 65534, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 40959, 127, 65534, 2047, 65535, 65535, + 65535, 65535, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65535, + 65535, 65535, 65535, 511, 0, 1023, 0, 0, 1023, 65535, 65535, 65527, 65535, + 65535, 255, 65535, 65535, 1023, 0, 0, 0, 0, 0, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 4095, 65535, 65535, 65535, 65535, 65535, 1023, + 65535, 16191, 65535, 65535, 16191, 43775, 65535, 16383, 65535, 65535, 65535, 24543, 8156, + 4047, 8191, 8156, 0, 0, 0, 0, 0, 0, 0, 32768, 0, 0, + 0, 0, 0, 0, 0, 0, 64644, 15919, 48464, 1019, 0, 0, 65535, + 65535, 15, 0, 0, 0, 0, 0, 0, 0, 192, 0, 1022, 1792, + 65534, 65535, 65535, 65535, 65535, 31, 65534, 65535, 65535, 65535, 65535, 2047, 65504, + 65535, 8191, 65534, 65535, 65535, 65535, 65535, 32767, 0, 65535, 255, 0, 0, + 0, 0, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 63, 0, 0, 0, 0, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 63, 0, 0, 0, 0, 0, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 8191, 0, 0, 0, 0, 0, 0, 0, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 15, 0, 0, 0, 0, + 0, 65535, 65535, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 127, 41208, 65023, 24447, 65499, 65535, 65535, 65535, 65535, + 65535, 65535, 3, 0, 65528, 65535, 65535, 65535, 65535, 65535, 16383, 0, 65535, + 65535, 65535, 65535, 65532, 65535, 65535, 255, 0, 0, 4095, 0, 0, 0, + 0, 0, 0, 0, 65495, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 8191, + 0, 1023, 65534, 2047, 65534, 2047, 65472, 65534, 65535, 16383, 65535, 32767, 64764, + 7420, 0, 0}; + +const uint16_t UnicodeAlphaBits[] = { + 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, + 432, 448, 464, 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, + 0, 0, 0, 0, 608, 624, 640, 656, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 672, 688, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 704, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 720, 1, 1, 1, 1, 736, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 768, 784, 1, 800, 816, 832, 0, 0, 0, 0, + 65534, 2047, 65534, 2047, 0, 0, 0, 0, 65535, 65407, 65535, 65407, 65535, + 65535, 65532, 15, 0, 65535, 65535, 65535, 65535, 65535, 16383, 63999, 3, 0, + 16415, 0, 0, 0, 0, 0, 32, 0, 0, 1024, 55104, 65535, 65531, + 65535, 32767, 64767, 65535, 15, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 61443, 65535, 65535, 65535, 6559, 65535, 65535, 831, 0, 0, 0, 65534, 65535, + 639, 65534, 65535, 255, 0, 0, 0, 0, 65535, 2047, 7, 0, 0, + 65534, 2047, 65534, 63, 0, 65535, 65535, 65535, 65535, 65535, 65535, 8175, 8702, + 7168, 0, 65535, 8191, 65535, 0, 0, 0, 0, 65535, 65535, 65535, 1, + 0, 0, 0, 0, 65518, 65535, 65535, 58367, 8191, 65281, 15, 0, 40942, + 65529, 65023, 50117, 6559, 45184, 15, 3, 34788, 65529, 65023, 50029, 6535, 24064, + 0, 31, 45038, 65531, 65023, 58349, 7103, 1, 1, 0, 40942, 65529, 65023, + 58317, 6543, 45248, 3, 0, 51180, 54845, 50968, 50111, 7623, 128, 0, 0, + 57326, 65533, 65023, 50159, 7647, 96, 3, 0, 57324, 65533, 65023, 50159, 7647, + 16480, 3, 0, 57324, 65533, 65023, 50175, 7631, 128, 3, 0, 65516, 64639, + 65535, 12283, 32895, 65375, 0, 12, 65534, 65535, 65535, 2047, 32767, 0, 0, + 0, 9622, 65264, 60590, 15359, 8223, 12288, 0, 0, 1, 0, 0, 0, + 65279, 65535, 2047, 65534, 3843, 65279, 65535, 8191, 0, 0, 0, 0, 65535, + 65535, 63227, 327, 0, 1023, 0, 0, 0, 0, 65535, 65535, 63, 65535, + 65535, 127, 65535, 65535, 65535, 65535, 65535, 33791, 65535, 65535, 65535, 65535, 65287, + 65535, 65535, 65535, 65535, 1023, 65407, 65535, 65535, 65535, 15743, 15743, 65535, 65535, + 15743, 65535, 32767, 32573, 32573, 65407, 32767, 65535, 32767, 32573, 65535, 65535, 65407, + 2047, 0, 0, 0, 0, 65535, 65535, 65535, 65535, 65535, 31, 65534, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 40959, 127, 65534, 2047, 65535, 65535, + 65535, 65535, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65535, + 65535, 65535, 65535, 511, 0, 0, 0, 0, 0, 65535, 65535, 65527, 65535, + 65535, 255, 65535, 65535, 1023, 0, 0, 0, 0, 0, 65535, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 4095, 65535, 65535, 65535, 65535, 65535, 1023, + 65535, 16191, 65535, 65535, 16191, 43775, 65535, 16383, 65535, 65535, 65535, 24543, 8156, + 4047, 8191, 8156, 0, 0, 0, 0, 0, 0, 0, 32768, 0, 0, + 0, 0, 0, 0, 0, 0, 64644, 15919, 48464, 1019, 0, 0, 65535, + 65535, 15, 0, 0, 0, 0, 0, 0, 0, 192, 0, 1022, 1792, + 65534, 65535, 65535, 65535, 65535, 31, 65534, 65535, 65535, 65535, 65535, 2047, 65504, + 65535, 8191, 65534, 65535, 65535, 65535, 65535, 32767, 0, 65535, 255, 0, 0, + 0, 0, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 63, 0, 0, 0, 0, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 63, 0, 0, 0, 0, 0, 65535, 65535, 65535, 65535, 65535, + 65535, 65535, 65535, 8191, 0, 0, 0, 0, 0, 0, 0, 65535, 65535, + 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 15, 0, 0, 0, 0, + 0, 65535, 65535, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 127, 41208, 65023, 24447, 65499, 65535, 65535, 65535, 65535, + 65535, 65535, 3, 0, 65528, 65535, 65535, 65535, 65535, 65535, 16383, 0, 65535, + 65535, 65535, 65535, 65532, 65535, 65535, 255, 0, 0, 4095, 0, 0, 0, + 0, 0, 0, 0, 65495, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 8191, + 0, 0, 65534, 2047, 65534, 2047, 65472, 65534, 65535, 16383, 65535, 32767, 64764, + 7420, 0, 0}; + +const uint16_t UnicodeDigitBits[] = { + 256, 0, 0, 0, 0, 0, 272, 0, 0, 288, 304, 320, 336, 352, 368, 384, + 400, 0, 0, 416, 0, 0, 0, 432, 448, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 464, + 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 1023, + 0, 0, 0, 0, 0, 0, 65472, 0, 0, 0, 0, 0, 0, 0, 65472, 0, + 0, 0, 0, 0, 0, 0, 65472, 0, 0, 0, 0, 0, 0, 0, 65472, 0, + 0, 0, 0, 0, 0, 0, 65472, 0, 0, 0, 0, 0, 0, 0, 65408, 0, + 0, 0, 0, 0, 0, 0, 65472, 0, 0, 0, 0, 0, 0, 0, 65472, 0, + 0, 0, 0, 0, 0, 0, 65472, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 1023, 0, 0, + 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 65024, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1023, 0, + 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +const uint16_t UnicodeSpaceBits[] = { + 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 304, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 15872, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4095, 0, 33536, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +const uint16_t UnicodeXDigitBits[] = { + 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 1023, 126, 0, 126, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1023, 126, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +// Uncomment if necessary +// const uint16_t UnicodeCntrlBits[] = { +// 256, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, +// 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 336, +// 65535,65535, 0, 0, 0, 0, 0,32768,65535,65535, 0, 0, 0, 0, 0, 0, +// 32768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 30720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 61440, 0,31744, 0, 0, 0,64512, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32768, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3584}; +// +// const uint16_t UnicodeGraphBits[] = { +// 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, +// 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, +// 640, 656, 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 688, 704, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 736, +// 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 768, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 784, 800, 1, 816, 832, 848, +// 0, 0,65534,65535,65535,65535,65535,32767, 0, 0,65534,65535,65535,65535,65535,65535, +// 65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, +// 0, 0, 0, 0, 32, 0, 0,17408,55232,65535,65531,65535,32767,64767,65535, 15, +// 65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, +// 0, 0, 0,65534,65535,65151,65534,65535, 1791, 0, 0,16384, 9,65535, 2047, 31, +// 4096,34816,65534, 2047,65534, 63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191, +// 16383,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, +// 65518,65535,65535,58367, 8191,65281,65535, 1,40942,65529,65023,50117, 6559,45184,65487, 3, +// 34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, +// 40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, +// 57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, +// 57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 28, +// 65534,65535,65535, 2047,65535, 4095, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, +// 65521, 7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191, 0, 0, 0, 0, +// 65535,65535,63227, 327,65535, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 2175, +// 65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, +// 65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, +// 32767,32573,65535,65535,65407, 2047,65534, 3, 0, 0,65535,65535,65535,65535,65535, 31, +// 65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, +// 65535,65535,65535,65535,65535,65535,65535, 127,65534, 8191,65535,65535,65535,65535,16383, 0, +// 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 6128, 1023, 0, +// 2047, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, +// 65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, +// 65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, +// 0,65535, 255,65535,16239, 0, 0,57344,24576, 0, 0, 0, 0, 0, 0, 0, +// 64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 65486,65523, 1022, 1793,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 4095, +// 65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, +// 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, +// 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, +// 65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, +// 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, +// 65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, +// 65535,65535,65535,65535, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, +// 0, 0, 0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535, 8191, +// 63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; +// +// const uint16_t UnicodePrintBits[] = { +// 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, +// 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, +// 640, 656, 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 688, 704, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 736, +// 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 768, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 784, 800, 1, 816, 832, 848, +// 512, 0,65535,65535,65535,65535,65535,32767, 0, 0,65535,65535,65535,65535,65535,65535, +// 65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, +// 0, 0, 0, 0, 32, 0, 0,17408,55232,65535,65531,65535,32767,64767,65535, 15, +// 65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, +// 0, 0, 0,65534,65535,65151,65534,65535, 1791, 0, 0,16384, 9,65535, 2047, 31, +// 4096,34816,65534, 2047,65534, 63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191, +// 16383,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, +// 65518,65535,65535,58367, 8191,65281,65535, 1,40942,65529,65023,50117, 6559,45184,65487, 3, +// 34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, +// 40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, +// 57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, +// 57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 28, +// 65534,65535,65535, 2047,65535, 4095, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, +// 65521, 7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191, 0, 0, 0, 0, +// 65535,65535,63227, 327,65535, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 2175, +// 65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, +// 65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, +// 32767,32573,65535,65535,65407, 2047,65534, 3, 0, 0,65535,65535,65535,65535,65535, 31, +// 65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, +// 65535,65535,65535,65535,65535,65535,65535, 127,65534, 8191,65535,65535,65535,65535,16383, 0, +// 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 6128, 1023, 0, +// 2047, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, +// 65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, +// 65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, +// 0,65535, 255,65535,16239, 0, 0,57344,24576, 0, 0, 0, 0, 0, 0, 0, +// 64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 65487,65523, 1022, 1793,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 4095, +// 65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, +// 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, +// 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, +// 65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, +// 65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, +// 65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, +// 65535,65535,65535,65535, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, +// 0, 0, 0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535,40959, +// 63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; +// +// const uint16_t UnicodePunctBits[] = { +// 256, 0, 0, 272, 0, 288, 304, 320, 0, 336, 0, 0, 0, 352, 368, 384, +// 400, 0, 0, 416, 0, 0, 432, 448, 464, 0, 0, 0, 0, 0, 0, 0, +// 480, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 528, 544, 560, +// 0, 0,65534,64512, 1,63488, 1,30720, 0, 0,65534,65535, 0, 128, 0, 128, +// 0, 0, 0, 0, 0, 0, 0,16384, 128, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0,64512, 0, 0, 1536, 0, 0,16384, 9, 0, 0, 24, +// 4096,34816, 0, 0, 0, 0,15360, 0, 0, 0, 0, 0, 0, 16, 0, 0, +// 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, +// 0, 0, 0, 0,32768, 3072, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 65520, 7, 0,15360, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0,64512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, +// 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0,24576, 0, 0, 6144, 0, 0, 0, 0,14336, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6128, 0, 0, +// 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0,65535, 255,65535,16239, 0, 0,24576,24576, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 65294,65523, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, +// 0, 0, 0,49152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0,65535,65055,65527, 3339, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 63470,35840, 1,47104, 0,10240, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +// +// const uint16_t UnicodeLowerBits[] = { +// 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 368, +// 384, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 432, +// 0, 0, 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0,32768,65535,65407, +// 43690,43690,43690,21930,43861,43690,43690,54442,12585,20004,11562,58961,23392,46421,43690,43565, +// 43690,43690,43688, 10, 0,65535,65535,65535,65535,65535,16383, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,61440,65535,32767,43235,43690, 15, +// 0, 0, 0,65535,65535,65535,43690,43690,40962,43690,43690,43690, 4372,43690,43690, 554, +// 0, 0, 0, 0, 0, 0,65534,65535, 255, 0, 0, 0, 0, 0, 0, 0, +// 43690,43690,43690,43690,43690,43690,43690,43690,43690, 4074,43690,43690,43690,43690,43690, 682, +// 255, 63, 255, 255, 63, 255, 255,16383,65535,65535,65535,20703, 4316, 207, 255, 4316, +// 0, 0, 0, 0, 0, 0, 0,32768, 0, 0, 0, 0, 0, 0, 0, 0, +// 50176, 8,32768, 528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 127, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +// +// const uint16_t UnicodeUpperBits[] = { +// 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 384, +// 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, +// 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0,65535,32639, 0, 0, +// 21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53973, 4526,44464,19114,21845,21974, +// 21845,21845,21844, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0,55104,65534, 4091, 0, 0,21532,21845, 0, +// 65535,65535,65535, 0, 0, 0,21845,21845,20481,21845,21845,21845, 2187,21845,21845, 277, +// 0, 0, 0,65534,65535, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65535,65535, 63, 0, 0, 0, +// 21845,21845,21845,21845,21845,21845,21845,21845,21845, 21,21845,21845,21845,21845,21845, 341, +// 65280,16128,65280,65280,16128,43520,65280, 0,65280,65280,65280, 7936, 7936, 3840, 7936, 7936, +// 14468,15911,15696, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +// MA: March 19, 2010 +// Modified ToUpper and ToLower tables to match values expected by AS3 tests. +// ToLower modifications: +// 304 -> 105 +// 1024 -> 1104 * +// 1037 -> 1117 * +// UoUpper modifications: +// 255 -> 376 +// 305 -> 73 +// 383 -> 83 +// 1104 -> 1024 * +// 1117 -> 1037 * +// Entries marked with a '*' don't make complete sense based on Unicode manual, although +// they match AS3. + +static const uint16_t UnicodeToUpperBits[] = { + 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 352, 368, 0, 384, 0, 0, 400, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, + 0, 0, 65534, 2047, 0, 0, 0, 0, 0, 0, 65535, 65407, 43690, + 43690, 43690, 21674, 43349, 43690, 43690, 54442, 4392, 516, 8490, 8785, 21056, 46421, + 43690, 43048, // MA: Modified for AS3. + 43690, 170, 0, 0, 0, 2776, 33545, 36, 3336, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 61440, 65534, 32767, 0, 43688, 0, 0, 0, 0, 65535, 65535, 65535, 43690, + 43690, 2, 43690, 43690, 43690, 4372, 43690, 35498, 554, // MA: Modified for AS3. + 0, 0, 0, 0, 0, 0, 65534, 65535, 127, 0, 0, 0, 0, + 0, 0, 0, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 42, + 43690, 43690, 43690, 43690, 43690, 682, 255, 63, 255, 255, 63, 170, 255, + 16383, 0, 0, 0, 3, 0, 3, 35, 0, 0, 0, 0, 0, + 0, 0, 0, 65535, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65535, + 1023, 0, 0, 0, 0, 0, 65534, 2047, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0}; + +static const uint16_t UnicodeToLowerBits[] = { + 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 368, 384, 0, 400, 0, 0, 416, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 432, 0, 0, 0, 0, + 65534, 2047, 0, 0, 0, 0, 0, 0, 65535, 32639, 0, 0, 21845, + 21845, 21845, 43605, 21674, 21845, 21845, 11093, 52950, 45531, 53909, 4526, 42128, 19114, + 21845, 21522, // MA: Modidied for AS3. + 21845, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55104, 65534, + 4091, 0, 0, 0, 21844, 0, 65535, 65535, 65535, 0, 0, 0, 21845, + 21845, 1, 21845, 21845, 21845, 2186, 21845, 17749, 277, 0, 0, 0, 65534, + 65535, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 65535, 65535, 63, 0, + 0, 0, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21845, 21, 21845, + 21845, 21845, 21845, 21845, 341, 65280, 16128, 65280, 65280, 16128, 43520, 65280, 0, + 0, 0, 0, 3840, 3840, 3840, 7936, 3840, 0, 0, 0, 0, 0, + 0, 65535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 65472, 65535, 0, 0, + 0, 0, 0, 65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; + +struct GUnicodePairType { + uint16_t Key, Value; +}; + +static inline bool CmpUnicodeKey(const GUnicodePairType& a, uint16_t key) { + return a.Key < key; +} + +static const GUnicodePairType UnicodeToUpperTable[] = { + {97, 65}, {98, 66}, {99, 67}, {100, 68}, {101, 69}, {102, 70}, + {103, 71}, {104, 72}, {105, 73}, {106, 74}, {107, 75}, {108, 76}, + {109, 77}, {110, 78}, {111, 79}, {112, 80}, {113, 81}, {114, 82}, + {115, 83}, {116, 84}, {117, 85}, {118, 86}, {119, 87}, {120, 88}, + {121, 89}, {122, 90}, {224, 192}, {225, 193}, {226, 194}, {227, 195}, + {228, 196}, {229, 197}, {230, 198}, {231, 199}, {232, 200}, {233, 201}, + {234, 202}, {235, 203}, {236, 204}, {237, 205}, {238, 206}, {239, 207}, + {240, 208}, {241, 209}, {242, 210}, {243, 211}, {244, 212}, {245, 213}, + {246, 214}, {248, 216}, {249, 217}, {250, 218}, {251, 219}, {252, 220}, + {253, 221}, {254, 222}, {255, 376}, {257, 256}, {259, 258}, {261, 260}, + {263, 262}, {265, 264}, {267, 266}, {269, 268}, {271, 270}, {273, 272}, + {275, 274}, {277, 276}, {279, 278}, {281, 280}, {283, 282}, {285, 284}, + {287, 286}, {289, 288}, {291, 290}, {293, 292}, {295, 294}, {297, 296}, + {299, 298}, {301, 300}, {303, 302}, {305, 73}, {307, 306}, {309, 308}, + {311, 310}, {314, 313}, {316, 315}, {318, 317}, {320, 319}, {322, 321}, + {324, 323}, {326, 325}, {328, 327}, {331, 330}, {333, 332}, {335, 334}, + {337, 336}, {339, 338}, {341, 340}, {343, 342}, {345, 344}, {347, 346}, + {349, 348}, {351, 350}, {353, 352}, {355, 354}, {357, 356}, {359, 358}, + {361, 360}, {363, 362}, {365, 364}, {367, 366}, {369, 368}, {371, 370}, + {373, 372}, {375, 374}, {378, 377}, {380, 379}, {382, 381}, {383, 83}, + {387, 386}, {389, 388}, {392, 391}, {396, 395}, {402, 401}, {409, 408}, + {417, 416}, {419, 418}, {421, 420}, {424, 423}, {429, 428}, {432, 431}, + {436, 435}, {438, 437}, {441, 440}, {445, 444}, {454, 452}, {457, 455}, + {460, 458}, {462, 461}, {464, 463}, {466, 465}, {468, 467}, {470, 469}, + {472, 471}, {474, 473}, {476, 475}, {477, 398}, {479, 478}, {481, 480}, + {483, 482}, {485, 484}, {487, 486}, {489, 488}, {491, 490}, {493, 492}, + {495, 494}, {499, 497}, {501, 500}, {507, 506}, {509, 508}, {511, 510}, + {513, 512}, {515, 514}, {517, 516}, {519, 518}, {521, 520}, {523, 522}, + {525, 524}, {527, 526}, {529, 528}, {531, 530}, {533, 532}, {535, 534}, + {595, 385}, {596, 390}, {598, 393}, {599, 394}, {601, 399}, {603, 400}, + {608, 403}, {611, 404}, {616, 407}, {617, 406}, {623, 412}, {626, 413}, + {629, 415}, {643, 425}, {648, 430}, {650, 433}, {651, 434}, {658, 439}, + {940, 902}, {941, 904}, {942, 905}, {943, 906}, {945, 913}, {946, 914}, + {947, 915}, {948, 916}, {949, 917}, {950, 918}, {951, 919}, {952, 920}, + {953, 921}, {954, 922}, {955, 923}, {956, 924}, {957, 925}, {958, 926}, + {959, 927}, {960, 928}, {961, 929}, {962, 931}, {963, 931}, {964, 932}, + {965, 933}, {966, 934}, {967, 935}, {968, 936}, {969, 937}, {970, 938}, + {971, 939}, {972, 908}, {973, 910}, {974, 911}, {995, 994}, {997, 996}, + {999, 998}, {1001, 1000}, {1003, 1002}, {1005, 1004}, {1007, 1006}, {1072, 1040}, + {1073, 1041}, {1074, 1042}, {1075, 1043}, {1076, 1044}, {1077, 1045}, {1078, 1046}, + {1079, 1047}, {1080, 1048}, {1081, 1049}, {1082, 1050}, {1083, 1051}, {1084, 1052}, + {1085, 1053}, {1086, 1054}, {1087, 1055}, {1088, 1056}, {1089, 1057}, {1090, 1058}, + {1091, 1059}, {1092, 1060}, {1093, 1061}, {1094, 1062}, {1095, 1063}, {1096, 1064}, + {1097, 1065}, {1098, 1066}, {1099, 1067}, {1100, 1068}, {1101, 1069}, {1102, 1070}, + {1103, 1071}, {1104, 1024}, {1105, 1025}, {1106, 1026}, {1107, 1027}, {1108, 1028}, + {1109, 1029}, {1110, 1030}, {1111, 1031}, {1112, 1032}, {1113, 1033}, {1114, 1034}, + {1115, 1035}, {1116, 1036}, {1117, 1037}, {1118, 1038}, {1119, 1039}, {1121, 1120}, + {1123, 1122}, {1125, 1124}, {1127, 1126}, {1129, 1128}, {1131, 1130}, {1133, 1132}, + {1135, 1134}, {1137, 1136}, {1139, 1138}, {1141, 1140}, {1143, 1142}, {1145, 1144}, + {1147, 1146}, {1149, 1148}, {1151, 1150}, {1153, 1152}, {1169, 1168}, {1171, 1170}, + {1173, 1172}, {1175, 1174}, {1177, 1176}, {1179, 1178}, {1181, 1180}, {1183, 1182}, + {1185, 1184}, {1187, 1186}, {1189, 1188}, {1191, 1190}, {1193, 1192}, {1195, 1194}, + {1197, 1196}, {1199, 1198}, {1201, 1200}, {1203, 1202}, {1205, 1204}, {1207, 1206}, + {1209, 1208}, {1211, 1210}, {1213, 1212}, {1215, 1214}, {1218, 1217}, {1220, 1219}, + {1224, 1223}, {1228, 1227}, {1233, 1232}, {1235, 1234}, {1237, 1236}, {1239, 1238}, + {1241, 1240}, {1243, 1242}, {1245, 1244}, {1247, 1246}, {1249, 1248}, {1251, 1250}, + {1253, 1252}, {1255, 1254}, {1257, 1256}, {1259, 1258}, {1263, 1262}, {1265, 1264}, + {1267, 1266}, {1269, 1268}, {1273, 1272}, {1377, 1329}, {1378, 1330}, {1379, 1331}, + {1380, 1332}, {1381, 1333}, {1382, 1334}, {1383, 1335}, {1384, 1336}, {1385, 1337}, + {1386, 1338}, {1387, 1339}, {1388, 1340}, {1389, 1341}, {1390, 1342}, {1391, 1343}, + {1392, 1344}, {1393, 1345}, {1394, 1346}, {1395, 1347}, {1396, 1348}, {1397, 1349}, + {1398, 1350}, {1399, 1351}, {1400, 1352}, {1401, 1353}, {1402, 1354}, {1403, 1355}, + {1404, 1356}, {1405, 1357}, {1406, 1358}, {1407, 1359}, {1408, 1360}, {1409, 1361}, + {1410, 1362}, {1411, 1363}, {1412, 1364}, {1413, 1365}, {1414, 1366}, {7681, 7680}, + {7683, 7682}, {7685, 7684}, {7687, 7686}, {7689, 7688}, {7691, 7690}, {7693, 7692}, + {7695, 7694}, {7697, 7696}, {7699, 7698}, {7701, 7700}, {7703, 7702}, {7705, 7704}, + {7707, 7706}, {7709, 7708}, {7711, 7710}, {7713, 7712}, {7715, 7714}, {7717, 7716}, + {7719, 7718}, {7721, 7720}, {7723, 7722}, {7725, 7724}, {7727, 7726}, {7729, 7728}, + {7731, 7730}, {7733, 7732}, {7735, 7734}, {7737, 7736}, {7739, 7738}, {7741, 7740}, + {7743, 7742}, {7745, 7744}, {7747, 7746}, {7749, 7748}, {7751, 7750}, {7753, 7752}, + {7755, 7754}, {7757, 7756}, {7759, 7758}, {7761, 7760}, {7763, 7762}, {7765, 7764}, + {7767, 7766}, {7769, 7768}, {7771, 7770}, {7773, 7772}, {7775, 7774}, {7777, 7776}, + {7779, 7778}, {7781, 7780}, {7783, 7782}, {7785, 7784}, {7787, 7786}, {7789, 7788}, + {7791, 7790}, {7793, 7792}, {7795, 7794}, {7797, 7796}, {7799, 7798}, {7801, 7800}, + {7803, 7802}, {7805, 7804}, {7807, 7806}, {7809, 7808}, {7811, 7810}, {7813, 7812}, + {7815, 7814}, {7817, 7816}, {7819, 7818}, {7821, 7820}, {7823, 7822}, {7825, 7824}, + {7827, 7826}, {7829, 7828}, {7841, 7840}, {7843, 7842}, {7845, 7844}, {7847, 7846}, + {7849, 7848}, {7851, 7850}, {7853, 7852}, {7855, 7854}, {7857, 7856}, {7859, 7858}, + {7861, 7860}, {7863, 7862}, {7865, 7864}, {7867, 7866}, {7869, 7868}, {7871, 7870}, + {7873, 7872}, {7875, 7874}, {7877, 7876}, {7879, 7878}, {7881, 7880}, {7883, 7882}, + {7885, 7884}, {7887, 7886}, {7889, 7888}, {7891, 7890}, {7893, 7892}, {7895, 7894}, + {7897, 7896}, {7899, 7898}, {7901, 7900}, {7903, 7902}, {7905, 7904}, {7907, 7906}, + {7909, 7908}, {7911, 7910}, {7913, 7912}, {7915, 7914}, {7917, 7916}, {7919, 7918}, + {7921, 7920}, {7923, 7922}, {7925, 7924}, {7927, 7926}, {7929, 7928}, {7936, 7944}, + {7937, 7945}, {7938, 7946}, {7939, 7947}, {7940, 7948}, {7941, 7949}, {7942, 7950}, + {7943, 7951}, {7952, 7960}, {7953, 7961}, {7954, 7962}, {7955, 7963}, {7956, 7964}, + {7957, 7965}, {7968, 7976}, {7969, 7977}, {7970, 7978}, {7971, 7979}, {7972, 7980}, + {7973, 7981}, {7974, 7982}, {7975, 7983}, {7984, 7992}, {7985, 7993}, {7986, 7994}, + {7987, 7995}, {7988, 7996}, {7989, 7997}, {7990, 7998}, {7991, 7999}, {8000, 8008}, + {8001, 8009}, {8002, 8010}, {8003, 8011}, {8004, 8012}, {8005, 8013}, {8017, 8025}, + {8019, 8027}, {8021, 8029}, {8023, 8031}, {8032, 8040}, {8033, 8041}, {8034, 8042}, + {8035, 8043}, {8036, 8044}, {8037, 8045}, {8038, 8046}, {8039, 8047}, {8048, 8122}, + {8049, 8123}, {8050, 8136}, {8051, 8137}, {8052, 8138}, {8053, 8139}, {8054, 8154}, + {8055, 8155}, {8056, 8184}, {8057, 8185}, {8058, 8170}, {8059, 8171}, {8060, 8186}, + {8061, 8187}, {8112, 8120}, {8113, 8121}, {8144, 8152}, {8145, 8153}, {8160, 8168}, + {8161, 8169}, {8165, 8172}, {8560, 8544}, {8561, 8545}, {8562, 8546}, {8563, 8547}, + {8564, 8548}, {8565, 8549}, {8566, 8550}, {8567, 8551}, {8568, 8552}, {8569, 8553}, + {8570, 8554}, {8571, 8555}, {8572, 8556}, {8573, 8557}, {8574, 8558}, {8575, 8559}, + {9424, 9398}, {9425, 9399}, {9426, 9400}, {9427, 9401}, {9428, 9402}, {9429, 9403}, + {9430, 9404}, {9431, 9405}, {9432, 9406}, {9433, 9407}, {9434, 9408}, {9435, 9409}, + {9436, 9410}, {9437, 9411}, {9438, 9412}, {9439, 9413}, {9440, 9414}, {9441, 9415}, + {9442, 9416}, {9443, 9417}, {9444, 9418}, {9445, 9419}, {9446, 9420}, {9447, 9421}, + {9448, 9422}, {9449, 9423}, {65345, 65313}, {65346, 65314}, {65347, 65315}, {65348, 65316}, + {65349, 65317}, {65350, 65318}, {65351, 65319}, {65352, 65320}, {65353, 65321}, {65354, 65322}, + {65355, 65323}, {65356, 65324}, {65357, 65325}, {65358, 65326}, {65359, 65327}, {65360, 65328}, + {65361, 65329}, {65362, 65330}, {65363, 65331}, {65364, 65332}, {65365, 65333}, {65366, 65334}, + {65367, 65335}, {65368, 65336}, {65369, 65337}, {65370, 65338}, {65535, 0}}; + +static const GUnicodePairType UnicodeToLowerTable[] = { + {65, 97}, {66, 98}, {67, 99}, {68, 100}, {69, 101}, {70, 102}, + {71, 103}, {72, 104}, {73, 105}, {74, 106}, {75, 107}, {76, 108}, + {77, 109}, {78, 110}, {79, 111}, {80, 112}, {81, 113}, {82, 114}, + {83, 115}, {84, 116}, {85, 117}, {86, 118}, {87, 119}, {88, 120}, + {89, 121}, {90, 122}, {192, 224}, {193, 225}, {194, 226}, {195, 227}, + {196, 228}, {197, 229}, {198, 230}, {199, 231}, {200, 232}, {201, 233}, + {202, 234}, {203, 235}, {204, 236}, {205, 237}, {206, 238}, {207, 239}, + {208, 240}, {209, 241}, {210, 242}, {211, 243}, {212, 244}, {213, 245}, + {214, 246}, {216, 248}, {217, 249}, {218, 250}, {219, 251}, {220, 252}, + {221, 253}, {222, 254}, {256, 257}, {258, 259}, {260, 261}, {262, 263}, + {264, 265}, {266, 267}, {268, 269}, {270, 271}, {272, 273}, {274, 275}, + {276, 277}, {278, 279}, {280, 281}, {282, 283}, {284, 285}, {286, 287}, + {288, 289}, {290, 291}, {292, 293}, {294, 295}, {296, 297}, {298, 299}, + {300, 301}, {302, 303}, {304, 105}, {306, 307}, {308, 309}, {310, 311}, + {313, 314}, {315, 316}, {317, 318}, {319, 320}, {321, 322}, {323, 324}, + {325, 326}, {327, 328}, {330, 331}, {332, 333}, {334, 335}, {336, 337}, + {338, 339}, {340, 341}, {342, 343}, {344, 345}, {346, 347}, {348, 349}, + {350, 351}, {352, 353}, {354, 355}, {356, 357}, {358, 359}, {360, 361}, + {362, 363}, {364, 365}, {366, 367}, {368, 369}, {370, 371}, {372, 373}, + {374, 375}, {376, 255}, {377, 378}, {379, 380}, {381, 382}, {385, 595}, + {386, 387}, {388, 389}, {390, 596}, {391, 392}, {393, 598}, {394, 599}, + {395, 396}, {398, 477}, {399, 601}, {400, 603}, {401, 402}, {403, 608}, + {404, 611}, {406, 617}, {407, 616}, {408, 409}, {412, 623}, {413, 626}, + {415, 629}, {416, 417}, {418, 419}, {420, 421}, {423, 424}, {425, 643}, + {428, 429}, {430, 648}, {431, 432}, {433, 650}, {434, 651}, {435, 436}, + {437, 438}, {439, 658}, {440, 441}, {444, 445}, {452, 454}, {455, 457}, + {458, 460}, {461, 462}, {463, 464}, {465, 466}, {467, 468}, {469, 470}, + {471, 472}, {473, 474}, {475, 476}, {478, 479}, {480, 481}, {482, 483}, + {484, 485}, {486, 487}, {488, 489}, {490, 491}, {492, 493}, {494, 495}, + {497, 499}, {500, 501}, {506, 507}, {508, 509}, {510, 511}, {512, 513}, + {514, 515}, {516, 517}, {518, 519}, {520, 521}, {522, 523}, {524, 525}, + {526, 527}, {528, 529}, {530, 531}, {532, 533}, {534, 535}, {902, 940}, + {904, 941}, {905, 942}, {906, 943}, {908, 972}, {910, 973}, {911, 974}, + {913, 945}, {914, 946}, {915, 947}, {916, 948}, {917, 949}, {918, 950}, + {919, 951}, {920, 952}, {921, 953}, {922, 954}, {923, 955}, {924, 956}, + {925, 957}, {926, 958}, {927, 959}, {928, 960}, {929, 961}, {931, 963}, + {932, 964}, {933, 965}, {934, 966}, {935, 967}, {936, 968}, {937, 969}, + {938, 970}, {939, 971}, {994, 995}, {996, 997}, {998, 999}, {1000, 1001}, + {1002, 1003}, {1004, 1005}, {1006, 1007}, {1024, 1104}, {1025, 1105}, {1026, 1106}, + {1027, 1107}, {1028, 1108}, {1029, 1109}, {1030, 1110}, {1031, 1111}, {1032, 1112}, + {1033, 1113}, {1034, 1114}, {1035, 1115}, {1036, 1116}, {1037, 1117}, {1038, 1118}, + {1039, 1119}, {1040, 1072}, {1041, 1073}, {1042, 1074}, {1043, 1075}, {1044, 1076}, + {1045, 1077}, {1046, 1078}, {1047, 1079}, {1048, 1080}, {1049, 1081}, {1050, 1082}, + {1051, 1083}, {1052, 1084}, {1053, 1085}, {1054, 1086}, {1055, 1087}, {1056, 1088}, + {1057, 1089}, {1058, 1090}, {1059, 1091}, {1060, 1092}, {1061, 1093}, {1062, 1094}, + {1063, 1095}, {1064, 1096}, {1065, 1097}, {1066, 1098}, {1067, 1099}, {1068, 1100}, + {1069, 1101}, {1070, 1102}, {1071, 1103}, {1120, 1121}, {1122, 1123}, {1124, 1125}, + {1126, 1127}, {1128, 1129}, {1130, 1131}, {1132, 1133}, {1134, 1135}, {1136, 1137}, + {1138, 1139}, {1140, 1141}, {1142, 1143}, {1144, 1145}, {1146, 1147}, {1148, 1149}, + {1150, 1151}, {1152, 1153}, {1168, 1169}, {1170, 1171}, {1172, 1173}, {1174, 1175}, + {1176, 1177}, {1178, 1179}, {1180, 1181}, {1182, 1183}, {1184, 1185}, {1186, 1187}, + {1188, 1189}, {1190, 1191}, {1192, 1193}, {1194, 1195}, {1196, 1197}, {1198, 1199}, + {1200, 1201}, {1202, 1203}, {1204, 1205}, {1206, 1207}, {1208, 1209}, {1210, 1211}, + {1212, 1213}, {1214, 1215}, {1217, 1218}, {1219, 1220}, {1223, 1224}, {1227, 1228}, + {1232, 1233}, {1234, 1235}, {1236, 1237}, {1238, 1239}, {1240, 1241}, {1242, 1243}, + {1244, 1245}, {1246, 1247}, {1248, 1249}, {1250, 1251}, {1252, 1253}, {1254, 1255}, + {1256, 1257}, {1258, 1259}, {1262, 1263}, {1264, 1265}, {1266, 1267}, {1268, 1269}, + {1272, 1273}, {1329, 1377}, {1330, 1378}, {1331, 1379}, {1332, 1380}, {1333, 1381}, + {1334, 1382}, {1335, 1383}, {1336, 1384}, {1337, 1385}, {1338, 1386}, {1339, 1387}, + {1340, 1388}, {1341, 1389}, {1342, 1390}, {1343, 1391}, {1344, 1392}, {1345, 1393}, + {1346, 1394}, {1347, 1395}, {1348, 1396}, {1349, 1397}, {1350, 1398}, {1351, 1399}, + {1352, 1400}, {1353, 1401}, {1354, 1402}, {1355, 1403}, {1356, 1404}, {1357, 1405}, + {1358, 1406}, {1359, 1407}, {1360, 1408}, {1361, 1409}, {1362, 1410}, {1363, 1411}, + {1364, 1412}, {1365, 1413}, {1366, 1414}, {4256, 4304}, {4257, 4305}, {4258, 4306}, + {4259, 4307}, {4260, 4308}, {4261, 4309}, {4262, 4310}, {4263, 4311}, {4264, 4312}, + {4265, 4313}, {4266, 4314}, {4267, 4315}, {4268, 4316}, {4269, 4317}, {4270, 4318}, + {4271, 4319}, {4272, 4320}, {4273, 4321}, {4274, 4322}, {4275, 4323}, {4276, 4324}, + {4277, 4325}, {4278, 4326}, {4279, 4327}, {4280, 4328}, {4281, 4329}, {4282, 4330}, + {4283, 4331}, {4284, 4332}, {4285, 4333}, {4286, 4334}, {4287, 4335}, {4288, 4336}, + {4289, 4337}, {4290, 4338}, {4291, 4339}, {4292, 4340}, {4293, 4341}, {7680, 7681}, + {7682, 7683}, {7684, 7685}, {7686, 7687}, {7688, 7689}, {7690, 7691}, {7692, 7693}, + {7694, 7695}, {7696, 7697}, {7698, 7699}, {7700, 7701}, {7702, 7703}, {7704, 7705}, + {7706, 7707}, {7708, 7709}, {7710, 7711}, {7712, 7713}, {7714, 7715}, {7716, 7717}, + {7718, 7719}, {7720, 7721}, {7722, 7723}, {7724, 7725}, {7726, 7727}, {7728, 7729}, + {7730, 7731}, {7732, 7733}, {7734, 7735}, {7736, 7737}, {7738, 7739}, {7740, 7741}, + {7742, 7743}, {7744, 7745}, {7746, 7747}, {7748, 7749}, {7750, 7751}, {7752, 7753}, + {7754, 7755}, {7756, 7757}, {7758, 7759}, {7760, 7761}, {7762, 7763}, {7764, 7765}, + {7766, 7767}, {7768, 7769}, {7770, 7771}, {7772, 7773}, {7774, 7775}, {7776, 7777}, + {7778, 7779}, {7780, 7781}, {7782, 7783}, {7784, 7785}, {7786, 7787}, {7788, 7789}, + {7790, 7791}, {7792, 7793}, {7794, 7795}, {7796, 7797}, {7798, 7799}, {7800, 7801}, + {7802, 7803}, {7804, 7805}, {7806, 7807}, {7808, 7809}, {7810, 7811}, {7812, 7813}, + {7814, 7815}, {7816, 7817}, {7818, 7819}, {7820, 7821}, {7822, 7823}, {7824, 7825}, + {7826, 7827}, {7828, 7829}, {7840, 7841}, {7842, 7843}, {7844, 7845}, {7846, 7847}, + {7848, 7849}, {7850, 7851}, {7852, 7853}, {7854, 7855}, {7856, 7857}, {7858, 7859}, + {7860, 7861}, {7862, 7863}, {7864, 7865}, {7866, 7867}, {7868, 7869}, {7870, 7871}, + {7872, 7873}, {7874, 7875}, {7876, 7877}, {7878, 7879}, {7880, 7881}, {7882, 7883}, + {7884, 7885}, {7886, 7887}, {7888, 7889}, {7890, 7891}, {7892, 7893}, {7894, 7895}, + {7896, 7897}, {7898, 7899}, {7900, 7901}, {7902, 7903}, {7904, 7905}, {7906, 7907}, + {7908, 7909}, {7910, 7911}, {7912, 7913}, {7914, 7915}, {7916, 7917}, {7918, 7919}, + {7920, 7921}, {7922, 7923}, {7924, 7925}, {7926, 7927}, {7928, 7929}, {7944, 7936}, + {7945, 7937}, {7946, 7938}, {7947, 7939}, {7948, 7940}, {7949, 7941}, {7950, 7942}, + {7951, 7943}, {7960, 7952}, {7961, 7953}, {7962, 7954}, {7963, 7955}, {7964, 7956}, + {7965, 7957}, {7976, 7968}, {7977, 7969}, {7978, 7970}, {7979, 7971}, {7980, 7972}, + {7981, 7973}, {7982, 7974}, {7983, 7975}, {7992, 7984}, {7993, 7985}, {7994, 7986}, + {7995, 7987}, {7996, 7988}, {7997, 7989}, {7998, 7990}, {7999, 7991}, {8008, 8000}, + {8009, 8001}, {8010, 8002}, {8011, 8003}, {8012, 8004}, {8013, 8005}, {8025, 8017}, + {8027, 8019}, {8029, 8021}, {8031, 8023}, {8040, 8032}, {8041, 8033}, {8042, 8034}, + {8043, 8035}, {8044, 8036}, {8045, 8037}, {8046, 8038}, {8047, 8039}, {8120, 8112}, + {8121, 8113}, {8122, 8048}, {8123, 8049}, {8136, 8050}, {8137, 8051}, {8138, 8052}, + {8139, 8053}, {8152, 8144}, {8153, 8145}, {8154, 8054}, {8155, 8055}, {8168, 8160}, + {8169, 8161}, {8170, 8058}, {8171, 8059}, {8172, 8165}, {8184, 8056}, {8185, 8057}, + {8186, 8060}, {8187, 8061}, {8544, 8560}, {8545, 8561}, {8546, 8562}, {8547, 8563}, + {8548, 8564}, {8549, 8565}, {8550, 8566}, {8551, 8567}, {8552, 8568}, {8553, 8569}, + {8554, 8570}, {8555, 8571}, {8556, 8572}, {8557, 8573}, {8558, 8574}, {8559, 8575}, + {9398, 9424}, {9399, 9425}, {9400, 9426}, {9401, 9427}, {9402, 9428}, {9403, 9429}, + {9404, 9430}, {9405, 9431}, {9406, 9432}, {9407, 9433}, {9408, 9434}, {9409, 9435}, + {9410, 9436}, {9411, 9437}, {9412, 9438}, {9413, 9439}, {9414, 9440}, {9415, 9441}, + {9416, 9442}, {9417, 9443}, {9418, 9444}, {9419, 9445}, {9420, 9446}, {9421, 9447}, + {9422, 9448}, {9423, 9449}, {65313, 65345}, {65314, 65346}, {65315, 65347}, {65316, 65348}, + {65317, 65349}, {65318, 65350}, {65319, 65351}, {65320, 65352}, {65321, 65353}, {65322, 65354}, + {65323, 65355}, {65324, 65356}, {65325, 65357}, {65326, 65358}, {65327, 65359}, {65328, 65360}, + {65329, 65361}, {65330, 65362}, {65331, 65363}, {65332, 65364}, {65333, 65365}, {65334, 65366}, + {65335, 65367}, {65336, 65368}, {65337, 65369}, {65338, 65370}, {65535, 0}}; + +int OVR_CDECL OVR_towupper(wchar_t charCode) { + // Don't use UnicodeUpperBits! It differs from UnicodeToUpperBits. + if (UnicodeCharIs(UnicodeToUpperBits, charCode)) { + // To protect from memory overrun in case the character is not found + // we use one extra fake element in the table {65536, 0}. + size_t idx = Alg::LowerBoundSliced( + UnicodeToUpperTable, + 0, + sizeof(UnicodeToUpperTable) / sizeof(UnicodeToUpperTable[0]) - 1, + (uint16_t)charCode, + CmpUnicodeKey); + return UnicodeToUpperTable[idx].Value; + } + return charCode; +} + +int OVR_CDECL OVR_towlower(wchar_t charCode) { + // Don't use UnicodeLowerBits! It differs from UnicodeToLowerBits. + if (UnicodeCharIs(UnicodeToLowerBits, charCode)) { + // To protect from memory overrun in case the character is not found + // we use one extra fake element in the table {65536, 0}. + size_t idx = Alg::LowerBoundSliced( + UnicodeToLowerTable, + 0, + sizeof(UnicodeToLowerTable) / sizeof(UnicodeToLowerTable[0]) - 1, + (uint16_t)charCode, + CmpUnicodeKey); + return UnicodeToLowerTable[idx].Value; + } + return charCode; +} + +#endif // OVR_NO_WCTYPE + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Std.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Std.h new file mode 100644 index 0000000..9ffc937 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Std.h @@ -0,0 +1,523 @@ +/************************************************************************************ + +Filename : OVR_Std.h +Content : Standard C function interface +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Std_h +#define OVR_Std_h + +#include +#include // for va_list args +#include +#include +#include +#include "OVR_Types.h" + +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) +#define OVR_MSVC_SAFESTRING +#include +#endif + +// Wide-char funcs +#include +#include + +namespace OVR { + +// Has the same behavior as itoa aside from also having a dest size argument. +// Return value: Pointer to the resulting null-terminated string, same as parameter str. +#if defined(OVR_OS_MS) +inline char* OVR_CDECL OVR_itoa(int val, char* dest, size_t destsize, int radix) { +#if defined(OVR_MSVC_SAFESTRING) + _itoa_s(val, dest, destsize, radix); + return dest; +#else + OVR_UNUSED(destsize); + return itoa(val, dest, radix); +#endif +} +#else // OVR_OS_MS +inline char* OVR_itoa(int val, char* dest, size_t len, int radix) { + if (val == 0) { + if (len > 1) { + dest[0] = '0'; + dest[1] = '\0'; + } else if (len > 0) + dest[0] = '\0'; + return dest; + } + + // FIXME: Fix the following code to avoid memory write overruns when len is in sufficient. + int cur = val; + size_t i = 0; + size_t 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 (size_t 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 size_t OVR_CDECL OVR_strlen(const char* str) { + return strlen(str); +} + +inline size_t OVR_CDECL OVR_strlen(const wchar_t* str) { + return wcslen(str); +} + +inline char* OVR_CDECL OVR_strcpy(char* dest, size_t destsize, const char* src) { +#if defined(OVR_MSVC_SAFESTRING) + // Using strncpy_s() instead of strcpy_s() since strcpy_s will invoke the + // invalid parameter exception handler (now in google breakpad) and will + // cause the server to crash, and even if it returns the data may not be + // copied truncated. The intent of all users surveyed has been to truncate + // so we specify strncpy_s with the truncate option instead. + strncpy_s(dest, destsize, src, _TRUNCATE); + return dest; +#else + // FIXME: This should be a safer implementation + OVR_UNUSED(destsize); + return strcpy(dest, src); +#endif +} + +inline wchar_t* OVR_CDECL OVR_strcpy(wchar_t* dest, size_t destsize, const wchar_t* src) { +#if defined(OVR_MSVC_SAFESTRING) + wcscpy_s(dest, destsize, src); + return dest; +#else + // FIXME: This should be a safer implementation + OVR_UNUSED(destsize); + return wcscpy(dest, src); +#endif +} + +// Acts the same as the strlcpy function. +// Copies src to dest, 0-terminating even if it involves truncating the write. +// Returns the required strlen of dest (which is one less than the required size of dest). +// strlcpy is a safer alternative to strcpy and strncpy and provides size information. +// However, it still may result in an incomplete copy. +// +// Example usage: +// char buffer[256]; +// if(OVR_strlcpy(buffer, "hello world", sizeof(buffer)) < sizeof(buffer)) +// { there was enough space } +// else +// { need a larger buffer } +// +size_t OVR_CDECL OVR_strlcpy(char* dest, const char* src, size_t destsize); +size_t OVR_CDECL OVR_strlcpy(wchar_t* dest, const wchar_t* src, size_t destsize); + +// Acts the same as the strlcat function. +// Appends src to dest, 0-terminating even if it involves an incomplete write. +// Doesn't 0-terminate in the case that destsize is 0. +// Returns the required strlen of dest (which is one less than the required size of dest). +// The terminating 0 char of dest is overwritten by the first +// character of src, and a new 0 char is appended to dest. The required capacity +// of the destination is (strlen(src) + strlen(dest) + 1). +// strlcat is a safer alternative to strcat and provides size information. +// However, it still may result in an incomplete copy. +// +// Example usage: +// char buffer[256] = "hello "; +// if(OVR_strlcat(buffer, "world", sizeof(buffer)) < sizeof(buffer)) +// { there was enough space } +// else +// { need a larger buffer } +// +size_t OVR_CDECL OVR_strlcat(char* dest, const char* src, size_t destsize); +size_t OVR_CDECL OVR_strlcat(wchar_t* dest, const wchar_t* src, size_t destsize); + +inline char* OVR_CDECL OVR_strncpy(char* dest, size_t destsize, const char* src, size_t count) { +#if defined(OVR_MSVC_SAFESTRING) + strncpy_s(dest, destsize, src, count); + return dest; +#else + // FIXME: This should be a safer implementation + OVR_UNUSED(destsize); + return strncpy(dest, src, count); +#endif +} + +inline char* OVR_CDECL OVR_strcat(char* dest, size_t destsize, const char* src) { +#if defined(OVR_MSVC_SAFESTRING) + strcat_s(dest, destsize, src); + return dest; +#else + // FIXME: This should be a safer implementation + 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); +} + +const char* OVR_CDECL OVR_strrchr(const char* pString, int c); +inline char* OVR_CDECL OVR_strrchr(char* pString, int c) { + return (char*)OVR_strrchr((const char*)pString, c); +} + +// Supports ASCII strings only, by calling tolower on each element. +char* OVR_CDECL OVR_stristr(const char* s1, const char* s2); + +// Converts each element via towlower. +wchar_t* OVR_CDECL OVR_stristr(const wchar_t* s1, const wchar_t* s2); + +inline const uint8_t* OVR_CDECL OVR_memrchr(const uint8_t* str, size_t size, uint8_t c) { + for (intptr_t i = (intptr_t)size - 1; 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 unsigned 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, size_t size) { + return strncmp(ws1, ws2, size); +} + +inline uint64_t OVR_CDECL OVR_strtouq(const char* nptr, char** endptr, int base) { +#if defined(OVR_CC_MSVC) + return _strtoui64(nptr, endptr, base); +#else + return strtoull(nptr, endptr, base); +#endif +} + +inline int64_t OVR_CDECL OVR_strtoq(const char* nptr, char** endptr, int base) { +#if defined(OVR_CC_MSVC) + return _strtoi64(nptr, endptr, base); +#else + return strtoll(nptr, endptr, base); +#endif +} + +inline int64_t OVR_CDECL OVR_atoq(const char* string) { +#if defined(OVR_CC_MSVC) + return _atoi64(string); +#else + return atoll(string); +#endif +} + +inline uint64_t OVR_CDECL OVR_atouq(const char* string) { + return OVR_strtouq(string, NULL, 10); +} + +// Implemented in OVR_Std.cpp in platform-specific manner. +int OVR_CDECL OVR_stricmp(const char* dest, const char* src); +int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, size_t count); + +// This is like vsprintf but with a destination buffer size argument. However, the behavior is +// different +// from vsnprintf in that the return value semantics are like vsprintf (which returns -1 on capacity +// overflow) and +// not like vsnprintf (which returns intended strlen on capacity overflow). +// Return value: +// On success, the total number of characters written is returned. +// On failure, a negative number is returned. +inline size_t OVR_CDECL +OVR_vsprintf(char* dest, size_t destsize, const char* format, va_list argList) { + size_t ret; +#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 = (size_t)rv; +#else + OVR_UNUSED(destsize); + int rv = _vsnprintf(dest, destsize - 1, format, argList); + OVR_ASSERT(rv != -1); + ret = (size_t)rv; + dest[destsize - 1] = 0; +#endif +#else + // FIXME: This should be a safer implementation + OVR_UNUSED(destsize); + ret = (size_t)vsprintf(dest, format, argList); + OVR_ASSERT(ret < destsize); +#endif + return ret; +} + +// Returns the strlen of the resulting formatted string, or a negative value if the format is +// invalid. +// Note: If you are planning on printing a string then it's more efficient to just use vsnprintf and +// look at the return value and handle the uncommon case that there wasn't enough space. +inline int OVR_CDECL OVR_vscprintf(const char* format, va_list argList) { + int ret; +#if defined(OVR_CC_MSVC) + ret = _vscprintf(format, argList); +#else + ret = vsnprintf(NULL, 0, format, argList); +#endif + return ret; +} + +wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, size_t destsize, const wchar_t* src); +wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, size_t destsize, const wchar_t* src, size_t count); +wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src); +size_t OVR_CDECL OVR_wcslen(const wchar_t* str); +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_MS) +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_wcsicoll(a, b); +#else + return ::wcsicoll(a, b); +#endif +#else + // not supported, use regular wcsicmp + return OVR_wcsicmp(a, b); +#endif +} + +inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b) { +#if defined(OVR_OS_MS) || 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_t* 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_t UnicodeAlnumBits[]; +extern const uint16_t UnicodeAlphaBits[]; +extern const uint16_t UnicodeDigitBits[]; +extern const uint16_t UnicodeSpaceBits[]; +extern const uint16_t UnicodeXDigitBits[]; + +// Uncomment if necessary +// extern const uint16_t UnicodeCntrlBits[]; +// extern const uint16_t UnicodeGraphBits[]; +// extern const uint16_t UnicodeLowerBits[]; +// extern const uint16_t UnicodePrintBits[]; +// extern const uint16_t UnicodePunctBits[]; +// extern const uint16_t 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; + size_t max = OVR_wcslen(string); + if (max > 63) + max = 63; + unsigned char c = 0; + for (size_t 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; + size_t max = OVR_wcslen(string); + if (max > 63) + max = 63; + unsigned char c = 0; + for (size_t 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 +} + +} // namespace OVR + +#endif // OVR_Std_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String.cpp new file mode 100644 index 0000000..c8da444 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String.cpp @@ -0,0 +1,372 @@ +/************************************************************************************ + +Filename : OVR_String.cpp +Content : String UTF8 string implementation with copy-on-write semantics + (thread-safe for assignment but not modification). +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_String.h" + +#include +#include +#include + +namespace OVR { + +// Return the byte size of the UTF-8 string corresponding to pchar (not including null termination) +static size_t GetEncodeStringSize(const wchar_t* pchar, size_t length = StringIsNullTerminated) { + size_t len = 0; + if (length == StringIsNullTerminated) { + for (size_t i = 0; pchar[i] != 0; ++i) { + len += UTF8Util::GetEncodeCharSize(pchar[i]); + } + } else { + for (size_t i = 0; i < length; ++i) { + len += UTF8Util::GetEncodeCharSize(pchar[i]); + } + } + return len; +} + +static size_t StringStrlcpy( + char* pDestUTF8, + size_t destCharCountNotIncludingNull, + const wchar_t* pSrcUCS, + size_t sourceLength = StringIsNullTerminated) { + // String Data[] buffers always have one extra character for null-termination + return UTF8Util::Strlcpy(pDestUTF8, destCharCountNotIncludingNull + 1, pSrcUCS, sourceLength); +} + +static size_t StringStrlcpy( + wchar_t* pDestUCS, + size_t destCharCountNotIncludingNull, + const char* pSrcUTF8, + size_t sourceLength = StringIsNullTerminated) { + // String Data[] buffers always have one extra character for null-termination + return UTF8Util::Strlcpy(pDestUCS, destCharCountNotIncludingNull + 1, pSrcUTF8, sourceLength); +} + +// ***** String Buffer used for Building Strings + +#define OVR_SBUFF_DEFAULT_GROW_SIZE 512 +// Constructors / Destructor. +StringBuffer::StringBuffer() + : pData(NULL), + Size(0), + BufferSize(0), + GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), + LengthIsSize(false) {} + +StringBuffer::StringBuffer(size_t growSize) + : pData(NULL), + Size(0), + BufferSize(0), + GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), + LengthIsSize(false) { + SetGrowSize(growSize); +} + +StringBuffer::StringBuffer(const char* data) + : pData(NULL), + Size(0), + BufferSize(0), + GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), + LengthIsSize(false) { + AppendString(data); +} + +StringBuffer::StringBuffer(const char* data, size_t dataSize) + : pData(NULL), + Size(0), + BufferSize(0), + GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), + LengthIsSize(false) { + AppendString(data, dataSize); +} + +StringBuffer::StringBuffer(const String& src) + : pData(NULL), + Size(0), + BufferSize(0), + GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), + LengthIsSize(false) { + AppendString(src.ToCStr(), src.GetSize()); +} + +StringBuffer::StringBuffer(const StringBuffer& src) + : pData(NULL), + Size(0), + BufferSize(0), + GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), + LengthIsSize(false) { + AppendString(src.ToCStr(), src.GetSize()); +} + +StringBuffer::StringBuffer(const wchar_t* data) + : pData(NULL), + Size(0), + BufferSize(0), + GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), + LengthIsSize(false) { + *this = data; +} + +StringBuffer::~StringBuffer() { + if (pData) + OVR_FREE(pData); +} + +void StringBuffer::SetGrowSize(size_t growSize) { + if (growSize <= 16) + GrowSize = 16; + else { + uint8_t bits = Alg::UpperBit(uint32_t(growSize - 1)); + size_t size = (size_t)1 << bits; + GrowSize = size == growSize ? growSize : size; + } +} + +size_t StringBuffer::GetLength() const { + size_t length, size = GetSize(); + if (LengthIsSize) + return size; + + length = (size_t)UTF8Util::GetLength(pData, (size_t)GetSize()); + + if (length == GetSize()) + LengthIsSize = true; + return length; +} + +void StringBuffer::Reserve(size_t _size) { + // Special-case size 0 to avoid allocations in the default ctor + // which makes e.g. OVRError::Success() cheaper. + // Check for >= BufferSize to reserve space for the trailing null character. + if ((_size > 0) && (_size >= BufferSize)) { + BufferSize = (_size + 1 + GrowSize - 1) & ~(GrowSize - 1); + if (!pData) + pData = (char*)OVR_ALLOC(BufferSize); + else + pData = (char*)OVR_REALLOC(pData, BufferSize); + } +} + +void StringBuffer::Resize(size_t _size) { + Reserve(_size); + LengthIsSize = false; + Size = _size; + if (pData) + pData[Size] = 0; +} + +void StringBuffer::Clear() { + Resize(0); +} + +// Appends a character +void StringBuffer::AppendChar(uint32_t ch) { + char buff[8]; + size_t origSize = GetSize(); + + // Converts ch into UTF8 string and fills it into buff. Also increments index according to the + // number of bytes + // in the UTF8 string. + intptr_t srcSize = 0; + UTF8Util::EncodeChar(buff, &srcSize, ch); + OVR_ASSERT(srcSize >= 0); + + size_t size = origSize + srcSize; + Resize(size); + OVR_ASSERT(pData != NULL); + memcpy(pData + origSize, buff, srcSize); +} + +// Append a string +void StringBuffer::AppendString(const wchar_t* pstr, size_t len) { + if (!pstr || !len) + return; + + size_t srcSize = GetEncodeStringSize(pstr, len); + size_t origSize = GetSize(); + size_t size = srcSize + origSize; + + Resize(size); + OVR_ASSERT(pData != NULL); + StringStrlcpy(pData + origSize, srcSize, pstr, len); +} + +void StringBuffer::AppendString(const char* putf8str, size_t utf8StrSz) { + if (!putf8str || !utf8StrSz) + return; + if (utf8StrSz == StringIsNullTerminated) + utf8StrSz = OVR_strlen(putf8str); + + size_t origSize = GetSize(); + size_t size = utf8StrSz + origSize; + + Resize(size); + OVR_ASSERT(pData != NULL); + memcpy(pData + origSize, putf8str, utf8StrSz); +} + +// If pstr is NULL then the StringBuffer is cleared. +void StringBuffer::operator=(const char* pstr) { + pstr = pstr ? pstr : ""; + size_t size = OVR_strlen(pstr); + Resize(size); + OVR_ASSERT((pData != NULL) || (size == 0)); + memcpy(pData, pstr, size); +} + +// If pstr is NULL then the StringBuffer is cleared. +void StringBuffer::operator=(const wchar_t* pstr) { + pstr = pstr ? pstr : L""; + size_t size = GetEncodeStringSize(pstr); + Resize(size); + OVR_ASSERT((pData != NULL) || (size == 0)); + StringStrlcpy(pData, size, pstr); +} + +void StringBuffer::operator=(const String& src) { + const size_t size = src.GetSize(); + Resize(size); + OVR_ASSERT((pData != NULL) || (size == 0)); + memcpy(pData, src.ToCStr(), size); +} + +void StringBuffer::operator=(const StringBuffer& src) { + Clear(); + AppendString(src.ToCStr(), src.GetSize()); +} + +// Inserts substr at posAt +void StringBuffer::Insert(const char* substr, size_t posAt, size_t len) { + size_t oldSize = Size; + size_t insertSize = (len == StringIsNullTerminated) ? OVR_strlen(substr) : len; + size_t byteIndex = + LengthIsSize ? posAt : (size_t)UTF8Util::GetByteIndex(posAt, pData, (intptr_t)Size); + + OVR_ASSERT(byteIndex <= oldSize); + Reserve(oldSize + insertSize); + + OVR_ASSERT(pData != NULL); // pData is unilaterally written to below. + memmove(pData + byteIndex + insertSize, pData + byteIndex, oldSize - byteIndex + 1); + memcpy(pData + byteIndex, substr, insertSize); + LengthIsSize = false; + Size = oldSize + insertSize; + pData[Size] = 0; +} + +// Inserts character at posAt +size_t StringBuffer::InsertCharAt(uint32_t c, size_t posAt) { + char buf[8]; + intptr_t len = 0; + UTF8Util::EncodeChar(buf, &len, c); + OVR_ASSERT(len >= 0); + buf[(size_t)len] = 0; + + Insert(buf, posAt, len); + return (size_t)len; +} + +std::string StringVsprintf(const char* format, va_list args) { + char buffer[512]; // We first try writing into this buffer. If it's not enough then use a string. + + va_list tmp_args; + va_copy(tmp_args, args); + const int requiredStrlen = vsnprintf(buffer, sizeof(buffer), format, tmp_args); + va_end(tmp_args); + + if (requiredStrlen < + static_cast(sizeof(buffer))) { // If the entire result fits into the buffer. + return std::string(buffer, requiredStrlen); + } + + std::string result(requiredStrlen, '\0'); + std::vsnprintf(&result[0], result.size(), format, args); + + return result; +} + +std::string& AppendSprintf(std::string& s, const char* format, ...) { + va_list args; + va_start(args, format); + s += StringVsprintf(format, args); + va_end(args); + return s; +} + +std::wstring UTF8StringToUCSString(const char* pUTF8, size_t length) { + if (length == StringIsNullTerminated) + length = OVR_strlen(pUTF8); + + std::wstring returnValue(length, wchar_t(0)); // We'll possibly trim this value below. + + // Note that Strlcpy doesn't handle UTF8 encoding errors. + size_t decodedLength = StringStrlcpy(&returnValue[0], length, pUTF8, length); + OVR_ASSERT(decodedLength <= length); + + returnValue.resize(decodedLength); + + return returnValue; +} + +std::wstring UTF8StringToUCSString(const std::string& sUTF8) { + return UTF8StringToUCSString(sUTF8.data(), sUTF8.size()); +} + +std::wstring OVRStringToUCSString(const String& sOVRUTF8) { + return UTF8StringToUCSString(sOVRUTF8.ToCStr(), sOVRUTF8.GetSize()); +} + +std::string UCSStringToUTF8String(const wchar_t* pUCS, size_t length) { + if (length == StringIsNullTerminated) + length = wcslen(pUCS); + + std::string sUTF8; + size_t size = GetEncodeStringSize(pUCS, length); + sUTF8.resize(size); + StringStrlcpy(&sUTF8[0], size, pUCS, length); + return sUTF8; +} + +std::string UCSStringToUTF8String(const std::wstring& sUCS) { + return UCSStringToUTF8String(sUCS.data(), sUCS.size()); +} + +String UCSStringToOVRString(const wchar_t* pUCS, size_t length) { + if (length == StringIsNullTerminated) + length = wcslen(pUCS); + + // We use a std::string intermediate because String doesn't support resize or assignment without + // preallocated data. + const std::string sUTF8 = UCSStringToUTF8String(pUCS, length); + const String sOVRUTF8(sUTF8.data(), sUTF8.size()); + return sOVRUTF8; +} + +String UCSStringToOVRString(const std::wstring& sUCS) { + return UCSStringToOVRString(sUCS.data(), sUCS.length()); +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String.h new file mode 100644 index 0000000..228b020 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String.h @@ -0,0 +1,597 @@ +/************************************************************************************ + +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 (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_String_h +#define OVR_String_h + +#include +#include +#include "OVR_Alg.h" +#include "OVR_Allocator.h" +#include "OVR_Atomic.h" +#include "OVR_Std.h" +#include "OVR_Types.h" +#include "OVR_UTF8Util.h" + +namespace OVR { + +class String; +class StringBuffer; + +// Special/default null-terminated length argument +const size_t StringIsNullTerminated = size_t(-1); + +//----------------------------------------------------------------------------------- +// ***** String Class + +// String is UTF8 based string class with copy-on-write implementation +// for assignment. + +class String : public std::string { + public: + typedef std::string inherited; + + // Constructors / Destructors. + String() {} + + String(const char* data) { + if (data) + inherited::assign(data); + } + + String(const char* data1, const char* pdata2, const char* pdata3 = nullptr) { + if (data1) + inherited::append(data1); + if (pdata2) + inherited::append(pdata2); + if (pdata3) + inherited::append(pdata3); + } + + String(const char* data, size_t buflen) { + if (data) + inherited::assign(data, buflen); + } + + String(const String& src) { + inherited::assign(src.data(), src.length()); + } + + String(const std::string& src) { + inherited::assign(src.data(), src.length()); + } + + explicit String(const wchar_t* data) { + if (data) + String::operator=(data); // Need to do UCS2->UTF8 conversion + } + + void Clear() { + inherited::clear(); + } + + operator const char*() const { + return inherited::c_str(); + } + + const char* ToCStr() const { + return inherited::c_str(); + } + + // Byte length. + size_t GetSize() const { + return inherited::size(); + } + + bool IsEmpty() const { + return inherited::empty(); + } + + // Returns number of Unicode codepoints (not byte length). + size_t GetLength() const { + return (size_t)UTF8Util::GetLength(inherited::data(), inherited::size()); + } + + // Return Unicode codepoint count. + int GetLengthI() const { + return (int)UTF8Util::GetLength(inherited::data(), inherited::size()); + } + + // Return Unicode codepoint at the specified codepoint index. + uint32_t GetCharAt(size_t index) const { + return UTF8Util::GetCharAt(index, inherited::data(), inherited::size()); + } + + // Get first Unicode codepoint. + uint32_t Front() const { + return UTF8Util::GetCharAt(0, inherited::data(), inherited::size()); + } + + // Get last Unicode codepoint. + uint32_t Back() const { + OVR_ASSERT(!inherited::empty()); + return GetCharAt(GetSize() - 1); + } + + // Append a Unicode codepoint. + void AppendChar(uint32_t ch) { + char buff[8]; // Max possible UTF8 sequence is 6 bytes. + intptr_t encodeSize = 0; + UTF8Util::EncodeChar(buff, &encodeSize, ch); + inherited::append(buff, encodeSize); + } + + // Append Unicode codepoints + void AppendString(const wchar_t* pstr, size_t len = StringIsNullTerminated) { + if (pstr) { + if (len == StringIsNullTerminated) + len = wcslen(pstr); + + while (len-- > 0) + AppendChar(*pstr++); + } + } + + // Append UTF8 stirng of a given byte size. + void AppendString(const char* putf8str, size_t utf8StrSz = StringIsNullTerminated) { + if (putf8str) { + if (utf8StrSz == StringIsNullTerminated) + inherited::append(putf8str); + else + inherited::append(putf8str, utf8StrSz); + } + } + + // Assigns string with known byte size. + void AssignString(const char* putf8str, size_t size) { + if (putf8str || (size == 0)) + inherited::assign(putf8str, size); + } + + // Remove 'removeLength' Unicode codepoints starting at the 'posAt' Unicode codepoint. + void Remove(size_t posAt, size_t removeLength = 1) { + size_t length = GetLength(); // Unicode size. + + if (posAt < length) { + size_t oldSize = inherited::size(); // Byte size. + + if ((posAt + removeLength) > length) + removeLength = (length - posAt); + + intptr_t bytePos = UTF8Util::GetByteIndex(posAt, inherited::data(), oldSize); + + intptr_t removeSize = + UTF8Util::GetByteIndex(removeLength, inherited::data() + bytePos, oldSize - bytePos); + + inherited::erase(bytePos, removeSize); + } + } + + // Removes the last Unicode codepoint. + void PopBack() { + if (!inherited::empty()) + Remove(GetLength() - 1, 1); + } + + // Returns a String that's a substring of this. + // start is the index of the first Unicode codepoint you want to include. + // end is the index one past the last Unicode codepoint you want to include. + String Substring(size_t start, size_t end) const { + size_t length = GetLength(); + + if ((start >= length) || (start >= end)) + return String(); + + if (end > length) + end = length; + + // Get position of starting character and size + intptr_t byteStart = UTF8Util::GetByteIndex(start, inherited::data(), inherited::size()); + intptr_t byteSize = UTF8Util::GetByteIndex( + end - start, inherited::data() + byteStart, inherited::size() - byteStart); + + return String(inherited::data() + byteStart, (size_t)byteSize); + } + + // Insert a UTF8 string at the Unicode codepoint posAt. + String& Insert(const char* substr, size_t posAt, size_t strSize = StringIsNullTerminated) { + if (substr) { + if (strSize == StringIsNullTerminated) + strSize = strlen(substr); + + size_t byteIndex = UTF8Util::GetByteIndex(posAt, inherited::c_str(), inherited::size()); + + if (byteIndex > inherited::size()) + byteIndex = inherited::size(); + + inherited::insert(byteIndex, substr, strSize); + } + + return *this; + } + + // UTF8 compare + static int CompareNoCase(const char* a, const char* b) { + return OVR_stricmp(a, b); + } + + // UTF8 compare + static int CompareNoCase(const char* a, const char* b, size_t byteSize) { + return OVR_strnicmp(a, b, byteSize); + } + + // Hash function, case-insensitive + static size_t BernsteinHashFunctionCIS(const void* pdataIn, size_t size, size_t seed = 5381) { + const uint8_t* pdata = (const uint8_t*)pdataIn; + size_t h = seed; + while (size > 0) { + size--; + h = ((h << 5) + h) ^ OVR_tolower(pdata[size]); + } + return h; + } + + // Hash function, case-sensitive + static size_t BernsteinHashFunction(const void* pdataIn, size_t size, size_t seed = 5381) { + const uint8_t* pdata = (const uint8_t*)pdataIn; + size_t h = seed; + while (size > 0) { + size--; + h = ((h << 5) + h) ^ (unsigned)pdata[size]; + } + return h; + } + + // 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(inherited::c_str()); + } + + bool HasExtension() const { + return HasExtension(inherited::c_str()); + } + + bool HasProtocol() const { + return HasProtocol(inherited::c_str()); + } + + 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. + + void operator=(const char* str) { + if (str) + inherited::assign(str); + else + inherited::clear(); + } + + void operator=(const wchar_t* str) { + inherited::clear(); + + while (str && *str) + AppendChar(*str++); + } + + void operator=(const String& src) { + inherited::assign(src.data(), src.size()); + } + + void operator+=(const String& src) { + inherited::append(src.data(), src.size()); + } + + void operator+=(const char* psrc) { + if (psrc) + inherited::append(psrc); + } + + void operator+=(const wchar_t* psrc) { + if (psrc) + AppendString(psrc); + } + + // Append a Unicode codepoint. + // Note that this function seems amiss by taking char as an argument instead of uint32_t or + // wchar_t. + void operator+=(char ch) { + AppendChar(ch); + } + + String operator+(const char* str) const { + String temp(*this); + if (str) + temp += str; + return temp; + } + + String operator+(const String& src) const { + String temp(*this); + temp += src; + return temp; + } + + bool operator==(const String& str) const { + return (OVR_strcmp(inherited::c_str(), str.c_str()) == 0); + } + + bool operator!=(const String& str) const { + return !operator==(str); + } + + bool operator==(const char* str) const { + return OVR_strcmp(inherited::c_str(), (str ? str : "")) == 0; + } + + bool operator!=(const char* str) const { + return !operator==(str); + } + + bool operator<(const char* pstr) const { + return OVR_strcmp(inherited::c_str(), (pstr ? pstr : "")) < 0; + } + + bool operator<(const String& str) const { + return *this < str.c_str(); + } + + bool operator>(const char* pstr) const { + return OVR_strcmp(inherited::c_str(), (pstr ? pstr : "")) > 0; + } + + bool operator>(const String& str) const { + return *this > str.c_str(); + } + + int CompareNoCase(const char* pstr) const { + return CompareNoCase(inherited::c_str(), (pstr ? pstr : "")); + } + + int CompareNoCase(const String& str) const { + return CompareNoCase(inherited::c_str(), str.c_str()); + } + + int CompareNoCaseStartsWith(const String& str) const { + // Problem: the original version of this used GetLength, which seems like a bug because + // CompareNoCase takes a byte length. Need to look back in the OVR_String.h history to see if + // the bug has always been there. + return CompareNoCase(inherited::c_str(), str.c_str(), str.size()); + } + + // Accesses raw bytes + const char& operator[](int index) const { + OVR_ASSERT(index >= 0 && (size_t)index < inherited::size()); + return inherited::operator[](index); + } + + const char& operator[](size_t index) const { + OVR_ASSERT(index < inherited::size()); + return inherited::operator[](index); + } + + 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 { + size_t operator()(const String& str) const { + return String::BernsteinHashFunction(str.data(), str.size()); + } + }; + + // Case-insensitive hash functor used for strings. Supports additional + // lookup based on NoCaseKey. + struct NoCaseHashFunctor { + size_t operator()(const String& str) const { + return String::BernsteinHashFunctionCIS(str.data(), str.size()); + } + size_t operator()(const NoCaseKey& key) const { + return String::BernsteinHashFunctionCIS(key.pStr->c_str(), key.pStr->size()); + } + }; +}; + +//----------------------------------------------------------------------------------- +// ***** String Buffer used for Building Strings + +class StringBuffer { + char* pData; + size_t Size; + size_t BufferSize; + size_t GrowSize; + mutable bool LengthIsSize; + + public: + // Constructors / Destructor. + StringBuffer(); + explicit StringBuffer(size_t growSize); + StringBuffer(const char* data); + StringBuffer(const char* data, size_t 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. + size_t GetGrowSize() const { + return GrowSize; + } + void SetGrowSize(size_t 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. + size_t GetSize() const { + return Size; + } + // Tells whether or not the string is empty. + bool IsEmpty() const { + return GetSize() == 0; + } + + // Returns number of characters + size_t GetLength() const; + + // Returns character at the specified index + uint32_t GetCharAt(size_t index) const; + uint32_t GetFirstCharAt(size_t index, const char** offset) const; + uint32_t GetNextChar(const char** offset) const; + uint32_t Front() const { + return GetCharAt(0); + } + uint32_t Back() const { + return GetCharAt(GetSize() - 1); + } + + // Resize the string to the new size + void Resize(size_t _size); + void Reserve(size_t _size); + + // Appends a character + void AppendChar(uint32_t ch); + + // Append a string + void AppendString(const wchar_t* pstr, size_t len = StringIsNullTerminated); + void AppendString(const char* putf8str, size_t utf8StrSz = StringIsNullTerminated); + void AppendFormatV(const char* format, va_list argList); + void AppendFormat(const char* format, ...); + + // Assigned a string with dynamic data (copied through initializer). + // void AssignString(const InitStruct& src, size_t size); + + // Inserts substr at posAt + void Insert(const char* substr, size_t posAt, size_t len = StringIsNullTerminated); + // Inserts character at posAt + size_t InsertCharAt(uint32_t c, size_t posAt); + + // 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) { + 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[](size_t index) { + OVR_ASSERT(index < GetSize()); + return pData[index]; + } + + const char& operator[](size_t index) const { + OVR_ASSERT(index < GetSize()); + return pData[index]; + } +}; + +// Returns a std::string that was initialized via printf-style formatting. +// The behavior is undefined if the specified format or arguments are invalid. +// Example usage: +// std::string s = StringVsprintf("Hello %s", "world"); +std::string StringVsprintf(const char* format, va_list args); + +// Returns a std::string that was appended to via printf-style formatting. +// The behavior is undefined if the specified format or arguments are invalid. +// Example usage: +// AppendSprintf(s, "appended %s", "hello world"); +std::string& AppendSprintf(std::string& s, const char* format, ...); + +// Convert a UTF8 String object to a wchar_t UCS (Unicode) std::basic_string object. +// The C++11 Standard Library has similar functionality, but it's not supported by earlier +// versions of Visual Studio. To consider: Add support for this when available. +// length is the strlen of pUTF8. If not specified then it is calculated automatically. +// Returns an empty string in the case that the UTF8 is malformed. +std::wstring UTF8StringToUCSString(const char* pUTF8, size_t length = StringIsNullTerminated); +std::wstring UTF8StringToUCSString(const std::string& sUTF8); +std::wstring OVRStringToUCSString(const String& sOVRUTF8); + +// Convert a wchar_t UCS (Unicode) std::basic_string object to a UTF8 std::basic_string object. +// The C++11 Standard Library has similar functionality, but it's not supported by earlier +// versions of Visual Studio. To consider: Add support for this when available. +// length is the strlen of pUCS. If not specified then it is calculated automatically. +// Returns an empty string in the case that the UTF8 is malformed. +std::string UCSStringToUTF8String(const wchar_t* pUCS, size_t length = StringIsNullTerminated); +std::string UCSStringToUTF8String(const std::wstring& sUCS); +String UCSStringToOVRString(const wchar_t* pUCS, size_t length = StringIsNullTerminated); +String UCSStringToOVRString(const std::wstring& sUCS); + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_StringHash.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_StringHash.h new file mode 100644 index 0000000..07f270a --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_StringHash.h @@ -0,0 +1,91 @@ +/************************************************************************************ + +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 (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_StringHash_h +#define OVR_StringHash_h + +#include "OVR_Hash.h" +#include "OVR_String.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 StringHash : public Hash { + public: + typedef U ValueType; + typedef StringHash SelfType; + typedef Hash 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); + } + } +}; + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String_FormatUtil.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String_FormatUtil.cpp new file mode 100644 index 0000000..d9a01c9 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String_FormatUtil.cpp @@ -0,0 +1,77 @@ +/************************************************************************************ + +Filename : OVR_String_FormatUtil.cpp +Content : String format functions. +Created : February 27, 2013 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include +#include "OVR_String.h" + +namespace OVR { + +void StringBuffer::AppendFormatV(const char* format, va_list argList) { + char buffer[512]; + char* bufferUsed = buffer; + char* bufferAllocated = NULL; + + va_list argListSaved; + va_copy(argListSaved, argList); + + int requiredStrlen = vsnprintf( + bufferUsed, + OVR_ARRAY_COUNT(buffer), + format, + argListSaved); // The large majority of the time this will succeed. + + if (requiredStrlen >= (int)sizeof(buffer)) // If the initial capacity wasn't enough... + { + bufferAllocated = (char*)OVR_ALLOC(sizeof(char) * (requiredStrlen + 1)); + bufferUsed = bufferAllocated; + if (bufferAllocated) { + va_end(argListSaved); + va_copy(argListSaved, argList); + requiredStrlen = vsnprintf(bufferAllocated, (requiredStrlen + 1), format, argListSaved); + } + } + + if (requiredStrlen < 0) // If there was a printf format error... + { + bufferUsed = NULL; + } + + va_end(argListSaved); + + if (bufferUsed) + AppendString(bufferUsed); + + if (bufferAllocated) + OVR_FREE(bufferAllocated); +} + +void StringBuffer::AppendFormat(const char* format, ...) { + va_list argList; + va_start(argList, format); + AppendFormatV(format, argList); + va_end(argList); +} +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String_PathUtil.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String_PathUtil.cpp new file mode 100644 index 0000000..ae05cfc --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_String_PathUtil.cpp @@ -0,0 +1,183 @@ +/************************************************************************************ + +Filename : OVR_String_PathUtil.cpp +Content : String filename/url helper function +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_String.h" +#include "OVR_UTF8Util.h" + +namespace OVR { + +//-------------------------------------------------------------------- +// ***** Path-Scanner helper function + +// Scans file path finding filename start and extension start, fills in their addess. +void ScanFilePath(const char* url, const char** pfilename, const char** pext) { + const char* urlStart = url; + const char* filename = 0; + const char* lastDot = 0; + + uint32_t charVal = UTF8Util::DecodeNextChar(&url); + + while (charVal != 0) { + if ((charVal == '/') || (charVal == '\\')) { + filename = url; + lastDot = 0; + } else if (charVal == '.') { + lastDot = url - 1; + } + + charVal = UTF8Util::DecodeNextChar(&url); + } + + if (pfilename) { + if (filename) + *pfilename = filename; + else + *pfilename = urlStart; + } + + if (pext) { + *pext = lastDot; + } +} + +// Scans till the end of protocol. Returns first character past protocol, +// 0 if not found. +// - protocol: 'file://', 'http://' +const char* ScanPathProtocol(const char* url) { + uint32_t charVal = UTF8Util::DecodeNextChar(&url); + uint32_t charVal2; + + while (charVal != 0) { + // Treat a colon followed by a slash as absolute. + if (charVal == ':') { + charVal2 = UTF8Util::DecodeNextChar(&url); + charVal = UTF8Util::DecodeNextChar(&url); + if ((charVal == '/') && (charVal2 == '\\')) + return url; + } + charVal = UTF8Util::DecodeNextChar(&url); + } + return 0; +} + +//-------------------------------------------------------------------- +// ***** String Path API implementation + +bool String::HasAbsolutePath(const char* url) { + // Absolute paths can star with: + // - protocols: 'file://', 'http://' + // - windows drive: 'c:\' + // - UNC share name: '\\share' + // - unix root '/' + + // On the other hand, relative paths are: + // - directory: 'directory/file' + // - this directory: './file' + // - parent directory: '../file' + // + // For now, we don't parse '.' or '..' out, but instead let it be concatenated + // to string and let the OS figure it out. This, however, is not good for file + // name matching in library/etc, so it should be improved. + + if (!url || !*url) + return true; // Treat empty strings as absolute. + + uint32_t charVal = UTF8Util::DecodeNextChar(&url); + + // Fist character of '/' or '\\' means absolute url. + if ((charVal == '/') || (charVal == '\\')) + return true; + + while (charVal != 0) { + // Treat a colon followed by a slash as absolute. + if (charVal == ':') { + charVal = UTF8Util::DecodeNextChar(&url); + // Protocol or windows drive. Absolute. + if ((charVal == '/') || (charVal == '\\')) + return true; + } else if ((charVal == '/') || (charVal == '\\')) { + // Not a first character (else 'if' above the loop would have caught it). + // Must be a relative url. + break; + } + + charVal = UTF8Util::DecodeNextChar(&url); + } + + // We get here for relative paths. + return false; +} + +bool String::HasExtension(const char* path) { + const char* ext = 0; + ScanFilePath(path, 0, &ext); + return ext != 0; +} +bool String::HasProtocol(const char* path) { + return ScanPathProtocol(path) != 0; +} + +String String::GetPath() const { + const char* filename = 0; + ScanFilePath(ToCStr(), &filename, 0); + + // Technically we can have extra logic somewhere for paths, + // such as enforcing protocol and '/' only based on flags, + // but we keep it simple for now. + return String(ToCStr(), filename ? (filename - ToCStr()) : GetSize()); +} + +String String::GetProtocol() const { + const char* protocolEnd = ScanPathProtocol(ToCStr()); + return String(ToCStr(), protocolEnd ? (protocolEnd - ToCStr()) : 0); +} + +String String::GetFilename() const { + const char* filename = 0; + ScanFilePath(ToCStr(), &filename, 0); + return String(filename); +} +String String::GetExtension() const { + const char* ext = 0; + ScanFilePath(ToCStr(), 0, &ext); + return String(ext); +} + +void String::StripExtension() { + const char* ext = 0; + ScanFilePath(ToCStr(), 0, &ext); + if (ext) { + *this = String(ToCStr(), ext - ToCStr()); + } +} + +void String::StripProtocol() { + const char* protocol = ScanPathProtocol(ToCStr()); + if (protocol) + AssignString(protocol, OVR_strlen(protocol)); +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SysFile.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SysFile.cpp new file mode 100644 index 0000000..3fc8913 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SysFile.cpp @@ -0,0 +1,157 @@ +/************************************************************************** + +Filename : OVR_SysFile.cpp +Content : File wrapper class implementation (Win32) + +Created : April 5, 1999 +Authors : Michael Antonov + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +**************************************************************************/ + +#define GFILE_CXX + +// Standard C library (Captain Obvious guarantees!) +#include + +#include "OVR_File.h" +#include "OVR_SysFile.h" + +namespace OVR { + +// This is - a dummy file that fails on all calls. + +class UnopenedFile : public File { + public: + UnopenedFile() {} + ~UnopenedFile() {} + + virtual const char* GetFilePath() { + return 0; + } + + // ** File Information + virtual bool IsValid() { + return 0; + } + virtual bool IsWritable() { + return 0; + } + + // Return position / file size + virtual int Tell() { + return 0; + } + virtual int64_t LTell() { + return 0; + } + virtual int GetLength() { + return 0; + } + virtual int64_t LGetLength() { + return 0; + } + + // virtual bool Stat(FileStats *pfs) { return 0; } + virtual int GetErrorCode() { + return Error_FileNotFound; + } + + // ** Stream implementation & I/O + virtual int Write(const uint8_t* /*pbuffer*/, int /*numBytes*/) { + return -1; + } + virtual int Read(uint8_t* /*pbuffer*/, int /*numBytes*/) { + return -1; + } + virtual int SkipBytes(int /*numBytes*/) { + return 0; + } + virtual int BytesAvailable() { + return 0; + } + virtual bool Flush() { + return 0; + } + virtual int Seek(int /*offset*/, int /*origin*/) { + return -1; + } + virtual int64_t LSeek(int64_t /*offset*/, int /*origin*/) { + return -1; + } + + virtual int CopyFromStream(File* /*pstream*/, int /*byteSize*/) { + return -1; + } + virtual bool Close() { + return 0; + } +}; + +// ***** System File + +// System file is created to access objects on file system directly +// This file can refer directly to path + +// ** Constructor +SysFile::SysFile() : DelegatedFile(0) { + pFile = *new UnopenedFile; +} + +Ptr FileFILEOpen(const String& path, int flags, int mode); + +// Opens a file +SysFile::SysFile(const String& path, int flags, int mode) : DelegatedFile(0) { + Open(path, flags, mode); +} + +// ** Open & management +// Will fail if file's already open +bool SysFile::Open(const String& path, int flags, int mode) { + pFile = FileFILEOpen(path, flags, mode); + if ((!pFile) || (!pFile->IsValid())) { + pFile = *new UnopenedFile; + return 0; + } + // pFile = *OVR_NEW DelegatedFile(pFile); // MA Testing + if (flags & Open_Buffered) + pFile = *new BufferedFile(pFile); + return 1; +} + +// ** Overrides + +int SysFile::GetErrorCode() { + return pFile ? pFile->GetErrorCode() : Error_FileNotFound; +} + +// Overrides to provide re-open support +bool SysFile::IsValid() { + return pFile && pFile->IsValid(); +} +bool SysFile::Close() { + if (IsValid()) { + DelegatedFile::Close(); + pFile = *new UnopenedFile; + return 1; + } + return 0; +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SysFile.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SysFile.h new file mode 100644 index 0000000..7a6f764 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_SysFile.h @@ -0,0 +1,105 @@ +/************************************************************************************ + +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 (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#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 + int64_t ModifyTime; + int64_t AccessTime; + int64_t 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 OVR, 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 diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.cpp new file mode 100644 index 0000000..550d6f4 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.cpp @@ -0,0 +1,214 @@ +/************************************************************************************ + +Filename : OVR_System.cpp +Content : General kernel initialization/cleanup, including that + of the memory allocator. +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_System.h" +#include +#include "Logging/Logging_Library.h" +#include "OVR_DebugHelp.h" +#include "OVR_Threads.h" +#include "OVR_Timer.h" + +#if defined(_MSC_VER) +#include +#else +#include +#endif + +#ifdef OVR_OS_MS +#pragma warning(push, 0) +#include "OVR_Win32_IncludeWindows.h" // GetModuleHandleEx +#pragma warning(pop) +#endif + +static ovrlog::Channel Logger("Kernel:System"); + +namespace OVR { + +//----------------------------------------------------------------------------- +// Initialization/Shutdown state +// If true, then Destroy() was called and is in the process of executing +// Added to fix race condition if thread is started after the call to System::Destroy() +static bool ShuttingDown = false; + +//----------------------------------------------------------------------------- +// Initialization/Shutdown Callbacks + +static SystemSingletonInternal* SystemShutdownListenerList = + nullptr; // Points to the most recent SystemSingletonInternal added to the list. + +static Lock& GetSSILock() { // Put listLock in a function so that it can be constructed on-demand. + static Lock listLock; // Will construct on the first usage. However, the guarding of this + // construction is not thread-safe + return listLock; // under all compilers. However, since we are initially calling this on startup + // before other threads +} // could possibly exist, the first usage of this will be before other threads exist. + +void SystemSingletonInternal::RegisterDestroyCallback() { + GetSSILock().DoLock(); + if (ShuttingDown) { + GetSSILock().Unlock(); + + OnThreadDestroy(); + } else { + GetSSILock().Unlock(); + + // Insert the listener at the front of the list (top of the stack). This is an analogue of a C++ + // forward_list::push_front or stack::push. + NextShutdownSingleton = SystemShutdownListenerList; + SystemShutdownListenerList = this; + } +} + +//----------------------------------------------------------------------------- +// System + +static int System_Init_Count = 0; + +#if defined(_MSC_VER) +// This allows us to throw OVR::bad_alloc instead of std::bad_alloc, which provides less +// information. +int OVRNewFailureHandler(size_t /*size*/) { + throw OVR::bad_alloc(); + + // Disabled because otherwise a compiler warning is generated regarding unreachable code. + // return 0; // A return value of 0 tells the Standard Library to not retry the allocation. +} +#else +// This allows us to throw OVR::bad_alloc instead of std::bad_alloc, which provides less +// information. +void OVRNewFailureHandler() { + throw OVR::bad_alloc(); +} +#endif + +// Initializes System core, installing allocator. +void System::Init() { + // Restart logging if we shut down before + ovrlog::RestartLogging(); + +#if defined(_MSC_VER) + // Make it so that failure of the C malloc family of functions results in the same behavior as C++ + // operator new failure. + // This allows us to throw exceptions for malloc usage the same as for operator new bad_alloc. + _set_new_mode(1); + + // Tells the standard library to direct new (and malloc) failures to us. Normally we wouldn't need + // to do this, as the + // C++ Standard Library already throws std::bad_alloc on operator new failure. The problem is that + // the Standard Library doesn't + // throw std::bad_alloc upon malloc failure, and we can only intercept malloc failure via this + // means. _set_new_handler specifies + // a global handler for the current running Standard Library. If the Standard Library is being + // dynamically linked instead + // of statically linked, then this is a problem because a call to _set_new_handler would override + // anything the application + // has already set. + _set_new_handler(OVRNewFailureHandler); +#else + // This allows us to throw OVR::bad_alloc instead of std::bad_alloc, which provides less + // information. + // Question: Does this set the handler for all threads or just the current thread? The C++ + // Standard doesn't + // explicitly state this, though it may be implied from other parts of the Standard. + std::set_new_handler(OVRNewFailureHandler); +#endif + + if (++System_Init_Count == 1) { + Timer::initializeTimerSystem(); + } else { + Logger.LogError("Init recursively called; depth = ", System_Init_Count); + // XXX Should this just exit? + } +} + +void System::Stop() { + GetSSILock().DoLock(); + ShuttingDown = true; + GetSSILock().Unlock(); + + if (--System_Init_Count == 0) { + Logger.LogInfo("Graceful shutdown: OnThreadDestroy"); + + // Invoke all of the post-finish callbacks (normal case) + for (SystemSingletonInternal* listener = SystemShutdownListenerList; listener; + listener = listener->NextShutdownSingleton) { + listener->OnThreadDestroy(); + } + } else { + Logger.LogError("Stop recursively called; depth = ", System_Init_Count); + } +} + +void System::Destroy() { + if (!ShuttingDown) { + Logger.LogWarning("Destroy called before Stop"); + System::Stop(); + } + + if (System_Init_Count == 0) { + Logger.LogInfo("Graceful shutdown: OnSystemDestroy"); + + // Invoke all of the post-finish callbacks (normal case) + for (SystemSingletonInternal *next, *listener = SystemShutdownListenerList; listener; + listener = next) { + next = listener->NextShutdownSingleton; + listener->OnSystemDestroy(); + } + + SystemShutdownListenerList = nullptr; + + Timer::shutdownTimerSystem(); + } else { + Logger.LogError("Destroy recursively called; depth = ", System_Init_Count); + } + + GetSSILock().DoLock(); + ShuttingDown = false; + GetSSILock().Unlock(); + + Logger.LogInfo("Graceful shutdown: Stopping logger"); + + // Prevent memory leak reports + ovrlog::ShutdownLogging(); +} + +// Returns 'true' if system was properly initialized. +bool System::IsInitialized() { + return System_Init_Count > 0; +} + +// Dump any leaked memory +void System::CheckForAllocatorLeaks() { + if (Allocator::IsTrackingLeaks()) { + int ovrLeakCount = Allocator::DumpMemory(); + (void)ovrLeakCount; + + OVR_ASSERT(ovrLeakCount == 0); + } +} + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.h new file mode 100644 index 0000000..4ed3484 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.h @@ -0,0 +1,181 @@ +/************************************************************************************ + +PublicHeader: OVR +Filename : OVR_System.h +Content : General kernel initialization/cleanup, including that + of the memory allocator. +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_System_h +#define OVR_System_h + +#include "OVR_Allocator.h" +#include "OVR_Atomic.h" + +namespace OVR { + +//----------------------------------------------------------------------------- +// SystemSingleton + +// Subsystems are implemented using the Singleton pattern. +// To avoid code duplication in all the places where Singletons are defined, +// The pattern is defined once here and used everywhere. + +class SystemSingletonInternal { + friend class System; + + // Allows for including this class in the shutdown list. + SystemSingletonInternal* NextShutdownSingleton; + + // No copying allowed + OVR_NON_COPYABLE(SystemSingletonInternal); + + public: + // Call this to register for a call to OnThreadDestroy and OnSystemDestroy before the + // Kernel is shut down. OnThreadDestroy is called before any remaining existing threads + // are exited. Registered callbacks are called in the reverse order they were registered. + // You would typically call this at the end of your SystemSingletonInternal subclass' constructor. + // The registered objects are not deleted on shutdown; they would have to do that themselves + // within + // OnSystemDestroy or via a compiler-generated static destruction. + void RegisterDestroyCallback(); + void PushDestroyCallbacks() { + RegisterDestroyCallback(); + } // For backward compatibility. + + protected: + SystemSingletonInternal() : NextShutdownSingleton(nullptr) {} + + virtual ~SystemSingletonInternal() {} + + // Initializes the SystemSingletonInternal. + // You can register for an automatic call to this function by calling PushInitCallbacks. + // The registration of an automatic call to this is not required, but may be useful if + // you need to postpone your initialization until after Kernel is initialized. + // You cannot call PushInitCallbacks or PushDestroyCallbacks while within this function. + virtual void OnSystemInit() {} + + // Called just before waiting for threads to exit. + // Listeners are called in the opposite order they were registered. + // This function is useful for terminating threads at the right time before the rest of the system + // is shut down. + // Note: The singleton must not delete itself here, as OnSystemDestroy will subsequently be called + // for it. + virtual void OnThreadDestroy() {} + + // Shuts down the SystemSingletonInternal. + // You can register for an automatic call to this function by calling PushDestroyCallbacks. + // The registration of an automatic call to this is not required, but may be useful if + // you need to delay your shutdown until application exit time. + // You cannot call PushInitCallbacks or PushDestroyCallbacks while within this function. + // This function may delete this. + virtual void OnSystemDestroy() {} +}; + +// Singletons derive from this class +template +class SystemSingletonBase : public SystemSingletonInternal { + static std::atomic SingletonInstance; + static T* SlowGetInstance(); + + struct ZeroInitializer { + ZeroInitializer() { + SingletonInstance = nullptr; + } + }; + ZeroInitializer zeroInitializer; + + protected: + ~SystemSingletonBase() { + // Make sure the instance gets set to zero on dtor + if (SingletonInstance.load() == this) + SingletonInstance = nullptr; + } + + public: + static OVR_FORCE_INLINE T* GetInstance() { + // Fast version + // Note: The singleton instance is stored in an std::atomic<> to allow it to be accessed + // atomically from multiple threads without locks. + T* instance = SingletonInstance; + return instance ? instance : SlowGetInstance(); + } +}; + +// For reference, see N3337 14.5.1.3 (Static data members of class templates): +template +std::atomic OVR::SystemSingletonBase::SingletonInstance; + +// Place this in the singleton class in the header file +#define OVR_DECLARE_SINGLETON(T) \ + friend class OVR::SystemSingletonBase; \ + \ + private: \ + T(); \ + virtual ~T(); \ + virtual void OnSystemDestroy() override; + +// Place this in the singleton class source file +#define OVR_DEFINE_SINGLETON(T) \ + namespace OVR { \ + template <> \ + T* SystemSingletonBase::SlowGetInstance() { \ + static OVR::Lock lock; \ + OVR::Lock::Locker locker(&lock); \ + if (!SingletonInstance.load()) \ + SingletonInstance = new T; \ + return SingletonInstance; \ + } \ + } + +// ***** 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. + +class System { + public: + // 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(); + + // Halt all system threads (call before Destroy). + static void OVR_CDECL Stop(); + + // De-initializes System more, finalizing the threading system and destroying + // the global memory allocator. + static void OVR_CDECL Destroy(); + + // Dump any leaked allocations + static void OVR_CDECL CheckForAllocatorLeaks(); +}; + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Threads.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Threads.h new file mode 100644 index 0000000..b0eb971 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Threads.h @@ -0,0 +1,217 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_Threads.h +Content : Contains thread-related (safe) functionality +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ +#ifndef OVR_Threads_h +#define OVR_Threads_h + +#include "OVR_Array.h" +#include "OVR_Atomic.h" +#include "OVR_RefCount.h" +#include "OVR_Types.h" + +#include +#include +#include + +#if !defined(_WIN32) +#include +#endif + +// 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 Event; +// Implementation forward declarations +class MutexImpl; + +//----------------------------------------------------------------------------------- +// ***** 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 MutexImpl; + + std::unique_ptr 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(const std::unique_ptr& pmutex) : Locker(pmutex.get()) {} + ~Locker() { + pMutex->Unlock(); + } + }; +}; + +//----------------------------------------------------------------------------------- +// ***** 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 std::mutex StateMutex; + std::condition_variable 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 + +// ThreadHandle is a handle to a thread, which on some platforms (e.g. Windows) is +// different from ThreadId. On Unix platforms, a ThreadHandle is the same as a +// ThreadId and is pthread_t. +typedef void* ThreadHandle; + +// ThreadId uniquely identifies a thread; returned by Windows GetCurrentThreadId(), +// Unix pthread_self() 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 + +namespace Thread { +// *** Sleep + +// Sleep msecs milliseconds +bool MSleep(unsigned msecs); + +// *** Debugging functionality +void SetCurrentThreadName(const char* name); +void GetCurrentThreadName(char* name, size_t nameCapacity); +}; // namespace Thread + +// Returns the unique Id of a thread it is called on, intended for +// comparison purposes. +ThreadId GetCurrentThreadId(); + +// Returns the unique Id of the current running process. +#if !defined(OVR_OS_MS) +#define GetCurrentProcessId getpid +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_THREAD_LOCAL +// +// Example usage: +// #if defined(OVR_THREAD_LOCAL) +// OVR_THREAD_LOCAL int n = 0; // OK +// extern OVR_THREAD_LOCAL struct Data s; // OK +// static OVR_THREAD_LOCAL char* p; // OK +// OVR_THREAD_LOCAL int i = sizeof(i); // OK. +// OVR_THREAD_LOCAL std::string s("hello"); // Can't be used for initialized +// objects. +// OVR_THREAD_LOCAL int Function(); // Can't be used as return value. +// void Function(){ OVR_THREAD_LOCAL int i = 0; } // Can't be used in function. +// void Function(OVR_THREAD_LOCAL int i){ } // can't be used as argument. +// extern int i; OVR_THREAD_LOCAL int i; // Declarations differ. +// int OVR_THREAD_LOCAL i; // Can't be used as a type modifier. +// OVR_THREAD_LOCAL int i = i; // Can't reference self before +// initialization. +// #endif + +#if !defined(_MSC_VER) || \ + (_MSC_VER >= 1900) // VC++ doesn't support C++11 thread_local storage until VS2015. +#define OVR_THREAD_LOCAL thread_local +#else +#define OVR_THREAD_LOCAL __declspec(thread) +#endif + +} // namespace OVR + +#endif // OVR_ENABLE_THREADS +#endif // OVR_Threads_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ThreadsPthread.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ThreadsPthread.cpp new file mode 100644 index 0000000..56fd27c --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ThreadsPthread.cpp @@ -0,0 +1,234 @@ +/************************************************************************************ + +Filename : OVR_ThreadsPthread.cpp +Content : +Created : +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#if !defined(_WIN32) // Skip the entire file under Windows + +#include "OVR_Threads.h" + +#ifdef OVR_ENABLE_THREADS + +#include +#include +#include +#include +#include +#include +#include "OVR_Timer.h" + +#if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) +#include +#include +#if !defined(OVR_OS_MAC) +#include +#endif +#endif + +namespace OVR { + +// ***** Mutex implementation + +// *** Internal Mutex implementation structure + +class MutexImpl : public NewOverrideBase { + // System mutex or semaphore + pthread_mutex_t SMutex; + bool Recursive; + unsigned LockCount; + pthread_t LockedBy; + + public: + // Constructor/destructor + MutexImpl(Mutex* pmutex, bool recursive = 1); + ~MutexImpl(); + + // Locking functions + void DoLock(); + bool TryLock(); + void Unlock(Mutex* pmutex); + // Returns 1 if the mutes is currently locked + bool IsLockedByAnotherThread(Mutex* pmutex); + bool IsSignaled() const; +}; + +pthread_mutexattr_t Lock::RecursiveAttr; +bool Lock::RecursiveAttrInit = 0; + +// *** Constructor/destructor +MutexImpl::MutexImpl(Mutex* pmutex, bool recursive) { + OVR_UNUSED(pmutex); + Recursive = recursive; + LockCount = 0; + + if (Recursive) { + if (!Lock::RecursiveAttrInit) { + pthread_mutexattr_init(&Lock::RecursiveAttr); + pthread_mutexattr_settype(&Lock::RecursiveAttr, PTHREAD_MUTEX_RECURSIVE); + Lock::RecursiveAttrInit = 1; + } + + pthread_mutex_init(&SMutex, &Lock::RecursiveAttr); + } else + pthread_mutex_init(&SMutex, 0); +} + +MutexImpl::~MutexImpl() { + pthread_mutex_destroy(&SMutex); +} + +// Lock and try lock +void MutexImpl::DoLock() { + while (pthread_mutex_lock(&SMutex)) + ; + LockCount++; + LockedBy = pthread_self(); +} + +bool MutexImpl::TryLock() { + if (!pthread_mutex_trylock(&SMutex)) { + LockCount++; + LockedBy = pthread_self(); + return 1; + } + + return 0; +} + +void MutexImpl::Unlock(Mutex* pmutex) { + OVR_UNUSED(pmutex); + OVR_ASSERT(pthread_self() == LockedBy && LockCount > 0); + + // unsigned lockCount; + LockCount--; + // lockCount = LockCount; + + pthread_mutex_unlock(&SMutex); +} + +bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex) { + OVR_UNUSED(pmutex); + // There could be multiple interpretations of IsLocked with respect to current thread + if (LockCount == 0) + return 0; + if (pthread_self() != LockedBy) + return 1; + return 0; +} + +bool MutexImpl::IsSignaled() const { + // An mutex is signaled if it is not locked ANYWHERE + // Note that this is different from IsLockedByAnotherThread function, + // that takes current thread into account + return LockCount == 0; +} + +// *** Actual Mutex class implementation + +// NOTE: RefCount mode already thread-safe for all waitables. +Mutex::Mutex(bool recursive) : pImpl(new MutexImpl(this, recursive)) {} + +Mutex::~Mutex() {} + +// Lock and try lock +void Mutex::DoLock() { + pImpl->DoLock(); +} +bool Mutex::TryLock() { + return pImpl->TryLock(); +} +void Mutex::Unlock() { + pImpl->Unlock(this); +} +bool Mutex::IsLockedByAnotherThread() { + return pImpl->IsLockedByAnotherThread(this); +} + +//----------------------------------------------------------------------------------- +// ***** Event + +bool Event::Wait(unsigned delay) { + std::unique_lock locker(StateMutex); + + // Do the correct amount of waiting + if (delay == OVR_WAIT_INFINITE) { + while (!State) + StateWaitCondition.wait(locker); + } else if (delay) { + if (!State) + StateWaitCondition.wait_for(locker, std::chrono::milliseconds(delay)); + } + + bool state = State; + // Take care of temporary 'pulsing' of a state + if (Temporary) { + Temporary = false; + State = false; + } + return state; +} + +void Event::updateState(bool newState, bool newTemp, bool mustNotify) { + std::unique_lock lock(StateMutex); + State = newState; + Temporary = newTemp; + if (mustNotify) { + lock.unlock(); + StateWaitCondition.notify_all(); + } +} + +ThreadId GetCurrentThreadId() { + return (void*)pthread_self(); +} + +// *** Sleep functions + +/* static */ +bool Thread::MSleep(unsigned msecs) { + usleep(msecs * 1000); + return 1; +} + +void Thread::SetCurrentThreadName(const char* name) { +#if defined(OVR_OS_APPLE) + pthread_setname_np(name); +#else + pthread_setname_np(pthread_self(), name); +#endif +} + +void Thread::GetCurrentThreadName(char* name, size_t nameCapacity) { + name[0] = 0; +#if !defined(OVR_OS_ANDROID) + // Android does not have pthread_getname_np (or an equivalent) + pthread_getname_np(pthread_self(), name, nameCapacity); +#endif +} + +} // namespace OVR + +#endif // OVR_ENABLE_THREADS + +#endif // _WIN32 diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ThreadsWinAPI.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ThreadsWinAPI.cpp new file mode 100644 index 0000000..3bbe85d --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_ThreadsWinAPI.cpp @@ -0,0 +1,319 @@ +/************************************************************************************ + +Filename : OVR_ThreadsWinAPI.cpp +Platform : WinAPI +Content : Windows specific thread-related (safe) functionality +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_String.h" +#include "OVR_Threads.h" +#include "OVR_Timer.h" + +#ifdef OVR_ENABLE_THREADS + +// For _beginthreadex / _endtheadex +#include + +#ifdef _WIN32 +#include +#include +#include "OVR_DLLHelper.h" + +#if !defined(NTDDI_WIN10_RS1) // RS1 SDK introduced these functions. +WINBASEAPI HRESULT WINAPI SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription); +WINBASEAPI HRESULT WINAPI GetThreadDescription(HANDLE hThread, PWSTR* ppszThreadDescription); +#endif + +// Example usage: +// Kernel32API kernel32API; +// +// if (kernel32API.getThreadDescription) { +// wchar_t* pStr; +// +// if (SUCCEEDED(getThreadDescription(hThread, &pStr)) { +// +// Localfree(pStr); +// } +// } +// +// if (kernel32API.setThreadDescription) { +// HRESULT hr = setThreadDescription(GetCurrentThread(), L"thread name"); +// ... +// } +// +class Kernel32API { + public: + Kernel32API() + : dllHelper{"Kernel32.dll"}, + getThreadDescription(dllHelper.Load("GetThreadDescription")), + setThreadDescription(dllHelper.Load("SetThreadDescription")) {} + + protected: + OVR::DllHelper dllHelper; // Declared first because the members below depend on the ctor order. + + public: + // Recognition of GetThreadDescription requires the Windows 10 SDK v10.14393 (a.k.a build 1607, + // a.k.a. Anniversary Update, a.k.a. RS1, a.k.a. Redstone 1) or later. + // GetThreadDescription requires thread to have at least THREAD_QUERY_LIMITED_INFORMATION access. + decltype(GetThreadDescription)* getThreadDescription; + + // Required THREAD_SET_LIMITED_INFORMATION access. + decltype(SetThreadDescription)* setThreadDescription; +}; + +Kernel32API kernel32API; + +#endif // _WIN32 + +namespace OVR { + +//----------------------------------------------------------------------------------- +// *** Internal Mutex implementation class + +class MutexImpl : public NewOverrideBase { + // System mutex or semaphore + HANDLE hMutexOrSemaphore; + bool Recursive; + volatile unsigned LockCount; + + public: + // Constructor/destructor + MutexImpl(bool recursive = 1); + ~MutexImpl(); + + // Locking functions + void DoLock(); + bool TryLock(); + void Unlock(Mutex* pmutex); + // Returns 1 if the mutes is currently locked + bool IsLockedByAnotherThread(Mutex* pmutex); +}; + +// *** Constructor/destructor +MutexImpl::MutexImpl(bool recursive) { + Recursive = recursive; + LockCount = 0; +#if defined(OVR_OS_WIN32) // Older versions of Windows don't support CreateSemaphoreEx, so stick + // with CreateSemaphore for portability. + hMutexOrSemaphore = Recursive ? CreateMutexW(NULL, 0, NULL) : CreateSemaphoreW(NULL, 1, 1, NULL); +#else + // No CreateSemaphore() call, so emulate it. + hMutexOrSemaphore = Recursive ? CreateMutexW(NULL, 0, NULL) + : CreateSemaphoreExW(NULL, 1, 1, NULL, 0, SEMAPHORE_ALL_ACCESS); +#endif +} +MutexImpl::~MutexImpl() { + CloseHandle(hMutexOrSemaphore); +} + +// Lock and try lock +void MutexImpl::DoLock() { + if (::WaitForSingleObject(hMutexOrSemaphore, INFINITE) != WAIT_OBJECT_0) + return; + LockCount++; +} + +bool MutexImpl::TryLock() { + DWORD ret; + if ((ret = ::WaitForSingleObject(hMutexOrSemaphore, 0)) != WAIT_OBJECT_0) + return 0; + LockCount++; + return 1; +} + +void MutexImpl::Unlock(Mutex* pmutex) { + OVR_UNUSED(pmutex); + + unsigned lockCount; + LockCount--; + lockCount = LockCount; + + // Release mutex + if ((Recursive ? ReleaseMutex(hMutexOrSemaphore) + : ReleaseSemaphore(hMutexOrSemaphore, 1, NULL)) != 0) { + // This used to call Wait handlers if lockCount == 0. + } +} + +bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex) { + // There could be multiple interpretations of IsLocked with respect to current thread + if (LockCount == 0) + return 0; + if (!TryLock()) + return 1; + Unlock(pmutex); + return 0; +} + +/* +bool MutexImpl::IsSignaled() const +{ + // An mutex is signaled if it is not locked ANYWHERE + // Note that this is different from IsLockedByAnotherThread function, + // that takes current thread into account + return LockCount == 0; +} +*/ + +// *** Actual Mutex class implementation + +Mutex::Mutex(bool recursive) : pImpl(new MutexImpl(recursive)) {} + +Mutex::~Mutex() {} + +// Lock and try lock +void Mutex::DoLock() { + pImpl->DoLock(); +} +bool Mutex::TryLock() { + return pImpl->TryLock(); +} +void Mutex::Unlock() { + pImpl->Unlock(this); +} +bool Mutex::IsLockedByAnotherThread() { + return pImpl->IsLockedByAnotherThread(this); +} + +//----------------------------------------------------------------------------------- +// ***** Event + +bool Event::Wait(unsigned delay) { + std::unique_lock locker(StateMutex); + + // Do the correct amount of waiting + if (delay == OVR_WAIT_INFINITE) { + while (!State) + StateWaitCondition.wait(locker); + } else if (delay) { + if (!State) + StateWaitCondition.wait_for(locker, std::chrono::milliseconds(delay)); + } + + bool state = State; + // Take care of temporary 'pulsing' of a state + if (Temporary) { + Temporary = false; + State = false; + } + return state; +} + +void Event::updateState(bool newState, bool newTemp, bool mustNotify) { + { + std::lock_guard lock(StateMutex); + State = newState; + Temporary = newTemp; + } + + // NOTE: The lock does not need to be held when calling notify_all(), + // and holding it is in fact a pessimization. + if (mustNotify) + StateWaitCondition.notify_all(); +} + +//----------------------------------------------------------------------------------- +// ***** Thread Namespace + +// *** Sleep functions + +// static +bool Thread::MSleep(unsigned msecs) { + ::Sleep(msecs); + return 1; +} + +static OVR_THREAD_LOCAL char ThreadLocaThreadlName[32] = {}; + +// Older method of informing the debugger about thread names. +// This needs to be in its own function body due to the use of __try. +static void SetCurrentThreadNameViaException(const char* name) { +#if !defined(OVR_BUILD_SHIPPING) || defined(OVR_BUILD_PROFILING) +// http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx +#pragma pack(push, 8) + struct THREADNAME_INFO { + DWORD dwType; // Must be 0x1000 + LPCSTR szName; // Pointer to name (in user address space) + DWORD dwThreadID; // Thread ID (-1 for caller thread) + DWORD dwFlags; // Reserved for future use; must be zero + }; + union TNIUnion { + THREADNAME_INFO tni; + ULONG_PTR upArray[4]; + }; +#pragma pack(pop) + + TNIUnion tniUnion = {{0x1000, name, ::GetCurrentThreadId(), 0}}; + + __try { + RaiseException(0x406D1388, 0, OVR_ARRAY_COUNT(tniUnion.upArray), tniUnion.upArray); + } __except ( + GetExceptionCode() == 0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER) { + return; + } +#endif // OVR_BUILD_SHIPPING +} + +void Thread::SetCurrentThreadName(const char* name) { + OVR_strlcpy(ThreadLocaThreadlName, name, sizeof(ThreadLocaThreadlName)); + + // https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-setthreaddescription + if (kernel32API.setThreadDescription) { + std::wstring strW = OVR::UTF8StringToUCSString(name); + kernel32API.setThreadDescription(GetCurrentThread(), strW.c_str()); + } else { + SetCurrentThreadNameViaException(name); + } +} + +void Thread::GetCurrentThreadName(char* name, size_t nameCapacity) { + if (kernel32API.getThreadDescription) { + wchar_t* pStrW; + + if (SUCCEEDED(kernel32API.getThreadDescription(GetCurrentThread(), &pStrW))) { + std::string str = OVR::UCSStringToUTF8String(pStrW); + LocalFree(pStrW); + OVR_strlcpy(name, str.c_str(), nameCapacity); + + return; + } + } + + // Fall back to seeing if we set it above in SetCurrentThreadName. + OVR_strlcpy(name, ThreadLocaThreadlName, nameCapacity); +} + +// Returns the unique Id of a thread it is called on, intended for +// comparison purposes. +ThreadId GetCurrentThreadId() { + union { + intptr_t id; + ThreadId threadId; + }; + id = ::GetCurrentThreadId(); + return threadId; +} + +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Timer.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Timer.cpp new file mode 100644 index 0000000..142cdd0 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Timer.cpp @@ -0,0 +1,453 @@ +/************************************************************************************ + +Filename : OVR_Timer.cpp +Content : Provides static functions for precise timing +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Timer.h" + +#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) +#include "OVR_Win32_IncludeWindows.h" + +#include +#pragma comment(lib, "winmm.lib") +#elif defined(OVR_OS_ANDROID) +#include +#include +#else +#include +#endif + +#if defined(OVR_BUILD_DEBUG) && defined(OVR_OS_WIN32) +typedef NTSTATUS( + NTAPI* NtQueryTimerResolutionType)(PULONG MaximumTime, PULONG MinimumTime, PULONG CurrentTime); +static NtQueryTimerResolutionType pNtQueryTimerResolution; +#endif + +#if defined(OVR_OS_MS) && !defined(OVR_OS_WIN32) // Non-desktop Microsoft platforms... + +// Add this alias here because we're not going to include OVR_CAPI.cpp +extern "C" { +double ovr_GetTimeInSeconds() { + return Timer::GetSeconds(); +} +} + +#endif + +namespace OVR { + +// For recorded data playback +bool Timer::useVirtualSeconds = false; +double Timer::VirtualSeconds = 0.0; + +//------------------------------------------------------------------------ +// *** Android Specific Timer + +#if defined( \ + OVR_OS_ANDROID) // To consider: This implementation can also work on most Linux distributions + +//------------------------------------------------------------------------ +// *** Timer - Platform Independent functions + +// Returns global high-resolution application timer in seconds. +double Timer::GetSeconds() { + if (useVirtualSeconds) + return VirtualSeconds; + + // Choreographer vsync timestamp is based on. + struct timespec tp; + const int status = clock_gettime(CLOCK_MONOTONIC, &tp); + +#ifdef OVR_BUILD_DEBUG + if (status != 0) { + OVR_DEBUG_LOG(("clock_gettime status=%i", status)); + } +#else + OVR_UNUSED(status); +#endif + + return (double)tp.tv_sec; +} + +uint64_t Timer::GetTicksNanos() { + if (useVirtualSeconds) + return (uint64_t)(VirtualSeconds * NanosPerSecond); + + // Choreographer vsync timestamp is based on. + struct timespec tp; + const int status = clock_gettime(CLOCK_MONOTONIC, &tp); + +#ifdef OVR_BUILD_DEBUG + if (status != 0) { + OVR_DEBUG_LOG(("clock_gettime status=%i", status)); + } +#else + OVR_UNUSED(status); +#endif + + const uint64_t result = + (uint64_t)tp.tv_sec * (uint64_t)(1000 * 1000 * 1000) + uint64_t(tp.tv_nsec); + return result; +} + +void Timer::initializeTimerSystem() { + // Empty for this platform. +} + +void Timer::shutdownTimerSystem() { + // Empty for this platform. +} + +//------------------------------------------------------------------------ +// *** Win32 Specific Timer + +#elif defined(OVR_OS_MS) + +// This helper class implements high-resolution wrapper that combines timeGetTime() output +// with QueryPerformanceCounter. timeGetTime() is lower precision but drives the high bits, +// as it's tied to the system clock. +struct PerformanceTimer { + PerformanceTimer() + : UsingVistaOrLater(false), + TimeCS(), + OldMMTimeMs(0), + MMTimeWrapCounter(0), + PerfFrequency(0), + PerfFrequencyInverse(0), + PerfFrequencyInverseNanos(0), + PerfMinusTicksDeltaNanos(0), + LastResultNanos(0) {} + + enum { MMTimerResolutionNanos = 1000000 }; + + void Initialize(); + void Shutdown(); + + uint64_t GetTimeSeconds(); + double GetTimeSecondsDouble(); + uint64_t GetTimeNanos(); + + UINT64 getFrequency() { + if (PerfFrequency == 0) { + LARGE_INTEGER freq; + ::QueryPerformanceFrequency(&freq); + PerfFrequency = freq.QuadPart; + PerfFrequencyInverse = 1.0 / (double)PerfFrequency; + PerfFrequencyInverseNanos = 1000000000.0 / (double)PerfFrequency; + } + return PerfFrequency; + } + + double GetFrequencyInverse() { + OVR_ASSERT(PerfFrequencyInverse != 0.0); // Assert that the frequency has been initialized. + return PerfFrequencyInverse; + } + + // In Vista+ we are able to use QPC exclusively. + bool UsingVistaOrLater; + + CRITICAL_SECTION TimeCS; + // timeGetTime() support with wrap. + uint32_t OldMMTimeMs; + uint32_t MMTimeWrapCounter; + // Cached performance frequency result. + uint64_t PerfFrequency; // cycles per second, typically a large value like 3000000, but usually + // not the same as the CPU clock rate. + double PerfFrequencyInverse; // seconds per cycle (will be a small fractional value). + double PerfFrequencyInverseNanos; // nanoseconds per cycle. + + // Computed as (perfCounterNanos - ticksCounterNanos) initially, + // and used to adjust timing. + uint64_t PerfMinusTicksDeltaNanos; + // Last returned value in nanoseconds, to ensure we don't back-step in time. + uint64_t LastResultNanos; +}; + +static PerformanceTimer Win32_PerfTimer; + +void PerformanceTimer::Initialize() { + ::InitializeCriticalSection(&TimeCS); + MMTimeWrapCounter = 0; + getFrequency(); + +#if defined(OVR_OS_WIN32) // Desktop Windows only + // Set Vista flag. On Vista, we can just use QPC() without all the extra work + OSVERSIONINFOEXW ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOEXW)); + ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); + ver.dwMajorVersion = 6; // Vista+ + + DWORDLONG condMask = 0; + VER_SET_CONDITION(condMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + + // VerifyVersionInfo returns true if the OS meets the conditions set above + UsingVistaOrLater = ::VerifyVersionInfoW(&ver, VER_MAJORVERSION, condMask) != 0; +#else + UsingVistaOrLater = true; +#endif + + if (!UsingVistaOrLater) { +#if defined(OVR_OS_WIN32) // Desktop Windows only + // The following has the effect of setting the NT timer resolution (NtSetTimerResolution) to 1 + // millisecond. + MMRESULT mmr = timeBeginPeriod(1); + OVR_ASSERT(TIMERR_NOERROR == mmr); + OVR_UNUSED(mmr); +#endif + +#if defined(OVR_BUILD_DEBUG) && defined(OVR_OS_WIN32) + HMODULE hNtDll = ::LoadLibraryW(L"NtDll.dll"); + if (hNtDll) { + pNtQueryTimerResolution = + (NtQueryTimerResolutionType)::GetProcAddress(hNtDll, "NtQueryTimerResolution"); + // pNtSetTimerResolution = (NtSetTimerResolutionType)::GetProcAddress(hNtDll, + // "NtSetTimerResolution"); + + if (pNtQueryTimerResolution) { + ULONG MinimumResolution; // in 100-ns units + ULONG MaximumResolution; + ULONG ActualResolution; + pNtQueryTimerResolution(&MinimumResolution, &MaximumResolution, &ActualResolution); + } + + ::FreeLibrary(hNtDll); + } +#endif + } +} + +void PerformanceTimer::Shutdown() { + ::DeleteCriticalSection(&TimeCS); + + if (!UsingVistaOrLater) { +#if defined(OVR_OS_WIN32) // Desktop Windows only + MMRESULT mmr = timeEndPeriod(1); + OVR_ASSERT(TIMERR_NOERROR == mmr); + OVR_UNUSED(mmr); +#endif + } +} + +uint64_t PerformanceTimer::GetTimeSeconds() { + if (UsingVistaOrLater) { + LARGE_INTEGER li; + ::QueryPerformanceCounter(&li); + OVR_ASSERT(PerfFrequencyInverse != 0); // Initialize should have been called earlier. + return (uint64_t)(li.QuadPart * PerfFrequencyInverse); + } + + return (uint64_t)(GetTimeNanos() * .0000000001); +} + +double PerformanceTimer::GetTimeSecondsDouble() { + if (UsingVistaOrLater) { + LARGE_INTEGER li; + ::QueryPerformanceCounter(&li); + OVR_ASSERT(PerfFrequencyInverse != 0); + return (li.QuadPart * PerfFrequencyInverse); + } + + return (GetTimeNanos() * .0000000001); +} + +uint64_t PerformanceTimer::GetTimeNanos() { + uint64_t resultNanos; + LARGE_INTEGER li; + + OVR_ASSERT(PerfFrequencyInverseNanos != 0); // Initialize should have been called earlier. + + if (UsingVistaOrLater) // Includes non-desktop platforms + { + // Then we can use QPC() directly without all that extra work + ::QueryPerformanceCounter(&li); + resultNanos = (uint64_t)(li.QuadPart * PerfFrequencyInverseNanos); + return resultNanos; + } + + // Pre-Vista computers: + // Note that the Oculus SDK does not run on PCs before Windows 7 SP1 + // so this code path should never be taken in practice. We keep it here + // since this is a nice reusable timing library that can be useful for + // other projects. + + // On Win32 QueryPerformanceFrequency is unreliable due to SMP and + // performance levels, so use this logic to detect wrapping and track + // high bits. + ::EnterCriticalSection(&TimeCS); + + // Get raw value and perf counter "At the same time". + ::QueryPerformanceCounter(&li); + + DWORD mmTimeMs = timeGetTime(); + if (OldMMTimeMs > mmTimeMs) + MMTimeWrapCounter++; + OldMMTimeMs = mmTimeMs; + + // Normalize to nanoseconds. + uint64_t perfCounterNanos = (uint64_t)(li.QuadPart * PerfFrequencyInverseNanos); + uint64_t mmCounterNanos = ((uint64_t(MMTimeWrapCounter) << 32) | mmTimeMs) * 1000000; + if (PerfMinusTicksDeltaNanos == 0) + PerfMinusTicksDeltaNanos = perfCounterNanos - mmCounterNanos; + + // Compute result before snapping. + // + // On first call, this evaluates to: + // resultNanos = mmCounterNanos. + // Next call, assuming no wrap: + // resultNanos = prev_mmCounterNanos + (perfCounterNanos - prev_perfCounterNanos). + // After wrap, this would be: + // resultNanos = snapped(prev_mmCounterNanos +/- 1ms) + (perfCounterNanos - + // prev_perfCounterNanos). + // + resultNanos = perfCounterNanos - PerfMinusTicksDeltaNanos; + + // Snap the range so that resultNanos never moves further apart then its target resolution. + // It's better to allow more slack on the high side as timeGetTime() may be updated at + // sporadically + // larger then 1 ms intervals even when 1 ms resolution is requested. + if (resultNanos > (mmCounterNanos + MMTimerResolutionNanos * 2)) { + resultNanos = mmCounterNanos + MMTimerResolutionNanos * 2; + if (resultNanos < LastResultNanos) + resultNanos = LastResultNanos; + PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; + } else if (resultNanos < (mmCounterNanos - MMTimerResolutionNanos)) { + resultNanos = mmCounterNanos - MMTimerResolutionNanos; + if (resultNanos < LastResultNanos) + resultNanos = LastResultNanos; + PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; + } + + LastResultNanos = resultNanos; + ::LeaveCriticalSection(&TimeCS); + + return resultNanos; +} + +//------------------------------------------------------------------------ +// *** Timer - Platform Independent functions + +// Returns global high-resolution application timer in seconds. +double Timer::GetSeconds() { + return Win32_PerfTimer.GetTimeSecondsDouble(); +} + +double Timer::GetVirtualSeconds() { + if (useVirtualSeconds) + return VirtualSeconds; + + return Win32_PerfTimer.GetTimeSecondsDouble(); +} + +// Delegate to PerformanceTimer. +uint64_t Timer::GetVirtualTicksNanos() { + if (useVirtualSeconds) + return (uint64_t)(VirtualSeconds * NanosPerSecond); + + return Win32_PerfTimer.GetTimeNanos(); +} + +uint64_t Timer::GetTicksNanos() { + return Win32_PerfTimer.GetTimeNanos(); +} + +// Windows version also provides the performance frequency inverse. +double Timer::GetPerfFrequencyInverse() { + return Win32_PerfTimer.GetFrequencyInverse(); +} + +double Timer::GetPerfFrequency() { + return double(Win32_PerfTimer.getFrequency()); +} + +void Timer::initializeTimerSystem() { + Win32_PerfTimer.Initialize(); +} +void Timer::shutdownTimerSystem() { + Win32_PerfTimer.Shutdown(); +} + +#else // C++11 standard compliant platforms + +double Timer::GetSeconds() { + if (useVirtualSeconds) + return VirtualSeconds; + + using FpSeconds = std::chrono::duration; + + auto now = std::chrono::high_resolution_clock::now(); + return FpSeconds(now.time_since_epoch()).count(); +} + +double Timer::GetVirtualSeconds() { + if (useVirtualSeconds) + return VirtualSeconds; + + using FpSeconds = std::chrono::duration; + + auto now = std::chrono::high_resolution_clock::now(); + return FpSeconds(now.time_since_epoch()).count(); +} + +uint64_t Timer::GetTicksNanos() { + if (useVirtualSeconds) + return (uint64_t)(VirtualSeconds * NanosPerSecond); + + using Uint64Nanoseconds = std::chrono::duration; + + auto now = std::chrono::high_resolution_clock::now(); + return Uint64Nanoseconds(now.time_since_epoch()).count(); +} + +void Timer::initializeTimerSystem() {} + +void Timer::shutdownTimerSystem() {} + +#endif // OS-specific + +CountdownTimer::CountdownTimer(size_t countdownTimeMs, bool start) + : CountdownTime(std::chrono::duration_cast( + std::chrono::milliseconds(countdownTimeMs))) { + if (start) + Restart(); +} + +std::chrono::steady_clock::time_point CountdownTimer::CurrentTime() const { + return std::chrono::steady_clock::now(); +} + +bool CountdownTimer::IsTimeUp() const { + return (CurrentTime() > DoneTime); +} + +void CountdownTimer::Restart() { + DoneTime = (CurrentTime() + CountdownTime); +} + +void CountdownTimer::Restart(size_t countdownTimeMs) { + CountdownTime = std::chrono::duration_cast( + std::chrono::milliseconds(countdownTimeMs)); + Restart(); +}; + +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Timer.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Timer.h new file mode 100644 index 0000000..ecec87a --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Timer.h @@ -0,0 +1,143 @@ +/************************************************************************************ + +PublicHeader: OVR +Filename : OVR_Timer.h +Content : Provides static functions for precise timing +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Timer_h +#define OVR_Timer_h + +#include +#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. + MksPerSecond = 1000 * 1000, // Microseconds in one second. + NanosPerSecond = 1000 * 1000 * 1000, // Nanoseconds in one second. + }; + + // ***** Timing APIs for Application + + // These APIs should be used to guide animation and other program functions + // that require precision. + + // Returns global high-resolution application timer in seconds. + static double OVR_STDCALL GetSeconds(); + + // This may return a recorded time if Replaying a recording + static double OVR_STDCALL GetVirtualSeconds(); + + // Returns time in Nanoseconds, using highest possible system resolution. + static uint64_t OVR_STDCALL GetTicksNanos(); + + // This may return a recorded time if Replaying a recording + static uint64_t OVR_STDCALL GetVirtualTicksNanos(); + +#ifdef OVR_OS_MS + static double OVR_STDCALL GetPerfFrequencyInverse(); + + static double OVR_STDCALL GetPerfFrequency(); +#endif + + // Kept for compatibility. + // 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. + static uint32_t OVR_STDCALL GetTicksMs() { + return uint32_t(GetTicksNanos() / 1000000); + } + + // This may return a recorded time if Replaying a recording + static uint32_t OVR_STDCALL GetVirtualTicksMs() { + return uint32_t(GetVirtualTicksNanos() / 1000000); + } + + // for recorded data playback + static void SetVirtualSeconds(double virtualSeconds, bool enable = true) { + VirtualSeconds = virtualSeconds; + useVirtualSeconds = enable; + } + + private: + friend class System; + // System called during program startup/shutdown. + static void initializeTimerSystem(); + static void shutdownTimerSystem(); + + // for recorded data playback. + static double VirtualSeconds; + static bool useVirtualSeconds; + +#if defined(OVR_OS_ANDROID) +// Android-specific data +#elif defined(OVR_OS_MS) +// Microsoft-specific data +#endif +}; // class Timer + +//----------------------------------------------------------------------------- +// CountdownTimer +// +// Acts like a kitchen timer. Implemented using std::chrono::steady_clock. +// Input resolution is in milliseconds. +// Under the hood, it uses the native resolution of a std::chrono::steady_clock. +// +// Exmample usage: +// CountdownTimer timer(5000, true); +// +// if(timer.IsTimeUp()) +// { +// DoSomething(); +// timer.Restart(); +// } +// +struct CountdownTimer { + std::chrono::steady_clock::time_point DoneTime; + std::chrono::steady_clock::duration CountdownTime; + CountdownTimer(size_t countdownTimeMs = 0, bool start = false); + + std::chrono::steady_clock::time_point CurrentTime() const; + bool IsTimeUp() const; + void Restart(); + void Restart(size_t countdownTimeMs); +}; + +} // namespace OVR + +// This version of ovr_GetTimeInSeconds should be called internally with Oculus service, +// as public APIs are not available. +inline double ovr_GetTimeInSeconds_Internal() { + return OVR::Timer::GetSeconds(); +} + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Types.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Types.h new file mode 100644 index 0000000..0126e84 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Types.h @@ -0,0 +1,1167 @@ +/************************************************************************************ + +Filename : OVR_Types.h +Content : Standard library defines and simple types +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Types_h +#define OVR_Types_h + +#include +#include "OVR_Compiler.h" + +#if defined(_WIN32) && defined(OVR_KILL_WINDOWS_A_FUNCTIONS) +#include +#include "OVR_Win32_IncludeWindows.h" +#pragma warning(push) +#pragma warning(disable : 4091) +#include +#pragma warning(pop) +#include +#include +#include +#include +#include +#include +#include +#include "WindowsAFunctions.h" +#endif + +// Unsupported compiler configurations +#if defined(_MSC_VER) && _MSC_VER == 0x1600 +#if _MSC_FULL_VER < 160040219 +#error "Oculus does not support VS2010 without SP1 installed: It will crash in Release mode" +#endif +#endif + +//----------------------------------------------------------------------------------- +// ****** Operating system identification +// +// Try to use the most generic version of these defines as possible in order to achieve +// the simplest portable code. For example, instead of using #if (defined(OVR_OS_IPHONE) || +// defined(OVR_OS_MAC)), +// consider using #if defined(OVR_OS_APPLE). +// +// Type definitions exist for the following operating systems: (OVR_OS_x) +// +// WIN32 - Win32 and Win64 (Windows XP and later) Does not include Microsoft phone and +// console platforms, despite that Microsoft's _WIN32 may be defined by the compiler for them. +// WIN64 - Win64 (Windows XP and later) +// MAC - Mac OS X (may be defined in addition to BSD) +// LINUX - Linux +// BSD - BSD Unix +// ANDROID - Android (may be defined in addition to LINUX) +// IPHONE - iPhone +// MS_MOBILE - Microsoft mobile OS. +// +// Meta platforms +// MS - Any OS by Microsoft (e.g. Win32, Win64, phone, console) +// APPLE - Any OS by Apple (e.g. iOS, OS X) +// UNIX - Linux, BSD, Mac OS X. +// MOBILE - iOS, Android, Microsoft phone +// CONSOLE - Console platforms. +// + +#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)) +#if !defined(OVR_OS_IPHONE) +#define OVR_OS_IPHONE +#endif +#else +#if !defined(OVR_OS_MAC) +#define OVR_OS_MAC +#endif +#if !defined(OVR_OS_DARWIN) +#define OVR_OS_DARWIN +#endif +#if !defined(OVR_OS_BSD) +#define OVR_OS_BSD +#endif +#endif +#elif (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) +#if !defined(OVR_OS_WIN64) +#define OVR_OS_WIN64 +#endif +#if !defined(OVR_OS_WIN32) +#define OVR_OS_WIN32 // Can be a 32 bit Windows build or a WOW64 support for Win32. In this case +// WOW64 support for Win32. +#endif +#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) +#if !defined(OVR_OS_WIN32) +#define OVR_OS_WIN32 // Can be a 32 bit Windows build or a WOW64 support for Win32. In this case +// WOW64 support for Win32. +#endif +#elif defined(ANDROID) || defined(__ANDROID__) +#if !defined(OVR_OS_ANDROID) +#define OVR_OS_ANDROID +#endif +#if !defined(OVR_OS_LINUX) +#define OVR_OS_LINUX +#endif +#elif defined(__linux__) || defined(__linux) +#if !defined(OVR_OS_LINUX) +#define OVR_OS_LINUX +#endif +#elif defined(_BSD_) || defined(__FreeBSD__) +#if !defined(OVR_OS_BSD) +#define OVR_OS_BSD +#endif +#else +#if !defined(OVR_OS_OTHER) +#define OVR_OS_OTHER +#endif +#endif + +#if !defined(OVR_OS_MS_MOBILE) +#if (defined(_M_ARM) || defined(_M_IX86) || defined(_M_AMD64)) && !defined(OVR_OS_WIN32) && \ + !defined(OVR_OS_CONSOLE) +#define OVR_OS_MS_MOBILE +#endif +#endif + +#if !defined(OVR_OS_MS) +#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) || defined(OVR_OS_MS_MOBILE) +#define OVR_OS_MS +#endif +#endif + +#if !defined(OVR_OS_APPLE) +#if defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) +#define OVR_OS_APPLE +#endif +#endif + +#if !defined(OVR_OS_UNIX) +#if defined(OVR_OS_ANDROID) || defined(OVR_OS_BSD) || defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) +#define OVR_OS_UNIX +#endif +#endif + +#if !defined(OVR_OS_MOBILE) +#if defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE) || defined(OVR_OS_MS_MOBILE) +#define OVR_OS_MOBILE +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** CPU Architecture +// +// 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__) || \ + defined(_M_AMD64) +#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(_M_IX86) || \ + defined(_M_AMD64) // _M_IX86 and _M_AMD64 are Microsoft identifiers for Intel-based platforms. +#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 Warnings + +// Disable MSVC warnings +#if defined(OVR_CC_MSVC) +#pragma warning(disable : 4127) // Conditional expression is constant +#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) +#if (OVR_CC_MSVC > 1800) +#pragma warning(disable : 4265) // Class has virtual functions, but destructor is not virtual +#pragma warning(disable : 4312) // Conversion from 'type1' to 'type2' of greater size +#pragma warning(disable : 4311) // Pointer truncation from 'type' to 'type' +#pragma warning(disable : 4302) // Truncation from 'type 1' to 'type 2' +#endif // OVR_CC_MSVC>1800 +#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 +#include +#include + +// MSVC Based Memory Leak checking - for now +#if defined(OVR_CC_MSVC) && defined(OVR_BUILD_DEBUG) +#define _CRTDBG_MAP_ALLOC +#include +#include +#endif + +//----------------------------------------------------------------------------------- +// ***** int8_t, int16_t, etc. + +#if defined(OVR_CC_MSVC) && (OVR_CC_VERSION <= 1500) // VS2008 and earlier +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +#include +#endif + +//----------------------------------------------------------------------------------- +// ***** Type definitions for Common Systems + +namespace OVR { + +typedef char Char; + +// Pointer-sized integer +typedef size_t UPInt; +typedef std::ptrdiff_t SPInt; + +#if defined(OVR_OS_MS) + +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 +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 + +// osx PID is a signed int32 (already defined to pid_t in OSX framework) +// linux PID is a signed int32 (already defined) +// win32 PID is an unsigned int32 +#ifdef OVR_OS_WIN32 +// process ID representation +typedef unsigned long pid_t; +#endif + +// OVR_INVALID_PID defines an invalid process id in a portable way. +#if !defined(OVR_INVALID_PID) +#define OVR_INVALID_PID 0 +#endif + +struct OVR_GUID { + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +}; + +} // namespace OVR + +//----------------------------------------------------------------------------------- +// ****** Standard C/C++ Library +// +// Identifies which standard library is currently being used. +// +// LIBSTDCPP - GNU libstdc++, used by GCC. +// LIBCPP - LLVM libc++, typically used by clang and GCC. +// DINKUMWARE - Used by Microsoft and various non-Microsoft compilers (e.g. Sony clang). + +#if !defined(OVR_STDLIB_LIBSTDCPP) +#if defined(__GLIBCXX__) +#define OVR_STDLIB_LIBSTDCPP 1 +#endif +#endif + +#if !defined(OVR_STDLIB_LIBCPP) +#if defined(__clang__) +#if defined(__cplusplus) && __has_include(<__config>) +#define OVR_STDLIB_LIBCPP 1 +#endif +#endif +#endif + +#if !defined(OVR_STDLIB_DINKUMWARE) +#if defined(_YVALS) // Dinkumware globally #defines _YVALS from the #includes above. +#define OVR_STDLIB_DINKUMWARE 1 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** 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 + +#if defined(OVR_OS_MS) + +// ***** Windows and non-desktop platforms + +// 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_PTR_SIZE +// +// Specifies the byte size of pointers (same as sizeof void*). + +#if !defined(OVR_PTR_SIZE) +#if defined(__WORDSIZE) +#define OVR_PTR_SIZE ((__WORDSIZE) / 8) +#elif defined(_WIN64) || defined(__LP64__) || defined(_LP64) || defined(_M_IA64) || \ + defined(__ia64__) || defined(__arch64__) || defined(__64BIT__) || defined(__Ptr_Is_64) +#define OVR_PTR_SIZE 8 +#elif defined(__CC_ARM) && (__sizeof_ptr == 8) +#define OVR_PTR_SIZE 8 +#else +#define OVR_PTR_SIZE 4 +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_WORD_SIZE +// +// Specifies the byte size of a machine word/register. Not necessarily the same as +// the size of pointers, but usually >= the size of pointers. + +#if !defined(OVR_WORD_SIZE) +#define OVR_WORD_SIZE OVR_PTR_SIZE // For our currently supported platforms these are equal. +#endif + +// ------------------------------------------------------------------------ +// ***** OVR_CONST_FLOAT / OVR_CONST_DOUBLE +// +// Used for defining a const float, typically in a header file. The resulting +// variable has external linkage and thus any other declarations of variables +// with the same name must be of an identical value. +// +// Example usage: +// OVR_CONST_FLOAT kPi = 3.14159265f; +// OVR_CONST_DOUBLE kOne = 1.0; + +#if defined(_MSC_VER) +#define OVR_CONST_FLOAT extern const __declspec(selectany) float +#define OVR_CONST_DOUBLE extern const __declspec(selectany) double +#else +#define OVR_CONST_FLOAT __attribute__((weak)) extern const float +#define OVR_CONST_DOUBLE __attribute__((weak)) extern const double +#endif + +// ------------------------------------------------------------------------ +// ***** OVR_FORCE_INLINE +// +// Force inline substitute - goes before function declaration +// Example usage: +// OVR_FORCE_INLINE void Test(); + +#if !defined(OVR_FORCE_INLINE) +#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 +#endif + +// ------------------------------------------------------------------------ +// ***** OVR_NO_INLINE +// +// Cannot be used with inline or OVR_FORCE_INLINE. +// Example usage: +// OVR_NO_INLINE void Test(); + +#if !defined(OVR_NO_INLINE) +#if defined(OVR_CC_MSVC) && (_MSC_VER >= 1500) // VS2008+ +#define OVR_NO_INLINE __declspec(noinline) +#elif !defined(OVR_CC_MSVC) +#define OVR_NO_INLINE __attribute__((noinline)) +#endif +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_STRINGIZE +// +// Converts a preprocessor symbol to a string. +// +// Example usage: +// printf("Line: %s", OVR_STRINGIZE(__LINE__)); +// +#if !defined(OVR_STRINGIZE) +#define OVR_STRINGIZEIMPL(x) #x +#define OVR_STRINGIZE(x) OVR_STRINGIZEIMPL(x) +#endif + +// ----------------------------------------------------------------------------------- +// ***** OVR_JOIN +// +// Joins two preprocessing symbols together. Supports the case when either or the +// the symbols are macros themselves. +// +// Example usage: +// char OVR_JOIN(unique_, __LINE__); // Results in (e.g.) char unique_123; +// +#if !defined(OVR_JOIN) +#define OVR_JOIN(a, b) OVR_JOIN1(a, b) +#define OVR_JOIN1(a, b) OVR_JOIN2(a, b) +#define OVR_JOIN2(a, b) a##b +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_OFFSETOF +// +// Portable implementation of offsetof for structs and classes. offsetof and GCC's +// __builtin_offsetof work only with POD types (standard-layout types under C++11), +// despite that it can safely work with a number of types that aren't POD. This +// version works with more types without generating compiler warnings or errors. +// Returns the offset as a size_t, as per offsetof. +// +// Example usage: +// struct Test{ int i; float f; }; +// size_t fPos = OVR_OFFSETOF(Test, f); + +#if defined(OVR_CC_GNU) +#define OVR_OFFSETOF(class_, member_) \ + ((size_t)( \ + ((uintptr_t) & reinterpret_cast((((class_*)65536)->member_))) - \ + 65536)) +#else +#define OVR_OFFSETOF(class_, member_) offsetof(class_, member_) +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_SIZEOF_MEMBER +// +// Implements a portable way to determine the size of struct or class data member. +// C++11 allows this directly via sizeof (see OVR_CPP_NO_EXTENDED_SIZEOF), and this +// macro exists to handle pre-C++11 compilers. +// Returns the offset as a size_t, as per sizeof. +// +// Example usage: +// struct Test{ int i; float f; }; +// size_t fSize = OVR_SIZEOF_MEMBER(Test, f); +// +#if defined(OVR_CPP_NO_EXTENDED_SIZEOF) +#define OVR_SIZEOF_MEMBER(class_, member_) (sizeof(((class_*)0)->member_)) +#else +#define OVR_SIZEOF_MEMBER(class_, member_) (sizeof(class_::member_)) +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_DEBUG_BREAK, +// OVR_ASSERT, OVR_ASSERT_M, OVR_ASSERT_AND_UNUSED +// +// Macros have effect only in debug builds. +// +// Example OVR_DEBUG_BREAK usage (note the lack of parentheses): +// #define MY_ASSERT(expression) do { if (!(expression)) { OVR_DEBUG_BREAK; } } while(0) +// +// +// Example OVR_ASSERT usage: +// OVR_ASSERT(count < 100); +// OVR_ASSERT_M(count < 100, "count is too high"); +// +#if defined(OVR_BUILD_DEBUG) +// Causes a debugger breakpoint in debug builds. Has no effect in release builds. +// Microsoft Win32 specific debugging support +#if defined(OVR_CC_MSVC) +// The __debugbreak() intrinsic works for the MSVC debugger, but when the debugger +// is not attached we want our VectoredExceptionHandler to catch assertions, and +// VEH does not trap "int 3" breakpoints. +#define OVR_DEBUG_BREAK __debugbreak() +#elif defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) +#if 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 __builtin_trap() +#endif +#else +#define OVR_DEBUG_BREAK \ + do { \ + *((int*)0) = 1; \ + } while (0) +#endif + +// In debug builds this tests the given expression; if false then executes OVR_DEBUG_BREAK, +// if true then no action. Has no effect in release builds. +#if defined(__clang_analyzer__) // During static analysis, make it so the analyzer thinks that +// failed asserts result in program exit. Reduced false positives. +#include +#ifndef OVR_FAIL_M +#define OVR_FAIL_M(message) \ + do { \ + OVR_DEBUG_BREAK; \ + exit(0); \ + } while (0) +#endif +#ifndef OVR_FAIL +#define OVR_FAIL() \ + do { \ + OVR_DEBUG_BREAK; \ + exit(0); \ + } while (0) +#endif +#ifndef OVR_ASSERT_M +#define OVR_ASSERT_M(p, message) \ + do { \ + if (!(p)) { \ + OVR_DEBUG_BREAK; \ + exit(0); \ + } \ + } while (0) +#endif +#ifndef OVR_ASSERT +#define OVR_ASSERT(p) \ + do { \ + if (!(p)) { \ + OVR_DEBUG_BREAK; \ + exit(0); \ + } \ + } while (0) +#endif +#else +#include + +// OVR::IsAutomationRunning() is a flag that indicates the current process is running automated +// tests. +// Tests are usually running using GoogleTest or some other test harness +// +// Using OVR_DEBUG_BREAK will cause the test to bail out and kill the current process. +// abort() will fail the test and let subsequent tests run. +#ifndef OVR_FAIL_M +#define OVR_FAIL_M_ENABLED // Indicates that OVR_FAIL_M is enabled. +#define OVR_FAIL_M(message) \ + { \ + intptr_t ovrAssertUserParam; \ + OVR::OVRAssertionHandler ovrAssertUserHandler = OVR::GetAssertionHandler(&ovrAssertUserParam); \ + \ + if (OVR::IsAutomationRunning() && !OVR::OVRIsDebuggerPresent()) { \ + /* Do nothing to allow error code examination */ \ + } else if (ovrAssertUserHandler && !OVR::OVRIsDebuggerPresent()) { \ + ovrAssertUserHandler(ovrAssertUserParam, "Assertion failure", message); \ + } else { \ + OVR_DEBUG_BREAK; \ + } \ + } +#endif + +#ifndef OVR_FAIL +#define OVR_FAIL_ENABLED // Indicates that OVR_FAIL is enabled. +#define OVR_FAIL() OVR_FAIL_M("Assertion failure") +#endif + +// void OVR_ASSERT_M(bool expression, const char* message); +// Note: The expression below is expanded into all usage of this assertion macro. +// We should try to minimize the size of the expanded code to the extent possible. +#ifndef OVR_ASSERT_M +#define OVR_ASSERT_M_ENABLED // Indicates that OVR_ASSERT_M is enabled. +#define OVR_ASSERT_M(p, message) \ + do { \ + if (!(p)) \ + OVR_FAIL_M(message) \ + } while (0) +#endif + +// void OVR_ASSERT(bool expression); +#ifndef OVR_ASSERT +#define OVR_ASSERT_ENABLED // Indicates that OVR_ASSERT is enabled. +#define OVR_ASSERT(p) OVR_ASSERT_M((p), (#p)) +#endif +#endif + +// Acts the same as OVR_ASSERT in debug builds. Acts the same as OVR_UNUSED in release builds. +// Example usage: OVR_ASSERT_AND_UNUSED(x < 30, x); +#ifndef OVR_ASSERT_AND_UNUSED +#define OVR_ASSERT_AND_UNUSED(expression, value) \ + OVR_ASSERT(expression); \ + OVR_UNUSED(value) +#endif + +#else // non-debug builds + +// Causes a debugger breakpoint in debug builds. Has no effect in release builds. +#ifndef OVR_DEBUG_BREAK +#define OVR_DEBUG_BREAK ((void)0) +#endif + +// In debug builds this tests the given expression; if false then executes OVR_DEBUG_BREAK, +// if true then no action. Has no effect in release builds. +#ifndef OVR_FAIL_M +#define OVR_FAIL_M(message) ((void)0) +#endif +#ifndef OVR_FAIL +#define OVR_FAIL() ((void)0) +#endif +#ifndef OVR_ASSERT_M +#define OVR_ASSERT_M(p, m) ((void)0) +#endif +#ifndef OVR_ASSERT +#define OVR_ASSERT(p) ((void)0) +#endif + +// Acts the same as OVR_ASSERT in debug builds. Acts the same as OVR_UNUSED in release builds. +// Example usage: OVR_ASSERT_AND_UNUSED(x < 30, x); +#ifndef OVR_ASSERT_AND_UNUSED +#define OVR_ASSERT_AND_UNUSED(expression, value) OVR_UNUSED(value) +#endif +#endif // OVR_BUILD_DEBUG + +// Assert handler +// The user of this library can override the default assertion handler and provide their own. +namespace OVR { +// The return value meaning is reserved for future definition and currently has no effect. +typedef intptr_t (*OVRAssertionHandler)(intptr_t userParam, const char* title, const char* msg); + +// Returns the current assertion handler. +OVRAssertionHandler GetAssertionHandler(intptr_t* userParameter = NULL); + +// Sets the current assertion handler. +// The default assertion handler if none is set simply issues a debug break. +// Example usage: +// intptr_t CustomAssertionHandler(intptr_t /*userParameter*/, const char* title, const char* +// message)) { +// MessageBox(title, message); +// OVR_DEBUG_BREAK; +// return 0; +// } +void SetAssertionHandler(OVRAssertionHandler assertionHandler, intptr_t userParameter = 0); + +// Implements the default assertion handler. +intptr_t DefaultAssertionHandler(intptr_t userParameter, const char* title, const char* message); + +// Checks if the current application is an automated test +bool IsAutomationRunning(); + +// Currently defined in OVR_DebugHelp.cpp +bool OVRIsDebuggerPresent(); +} // namespace OVR + +// ------------------------------------------------------------------------ +// ***** OVR_COMPILER_ASSERT +// +// Compile-time assert; produces compiler error if condition is false. +// The expression must be a compile-time constant expression. +// This macro is deprecated in favor of static_assert, which provides better +// compiler output and works in a broader range of contexts. +// +// Example usage: +// OVR_COMPILER_ASSERT(sizeof(int32_t == 4)); + +#if !defined(OVR_COMPILER_ASSERT) +#define OVR_COMPILER_ASSERT(expression) static_assert(expression, #expression) +#define OVR_COMPILER_ASSERT_M(expression, msg) static_assert(expression, msg) +#endif + +// ***** OVR_PROCESSOR_PAUSE +// +// Yields the processor for other hyperthreads, usually for the purpose of implementing spins and +// spin locks. +// +// Example usage: +// while(!finished()) +// OVR_PROCESSOR_PAUSE(); + +#if !defined(OVR_PROCESSOR_PAUSE) +#if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) +#if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) +#define OVR_PROCESSOR_PAUSE() \ + asm volatile("pause" ::: "memory") // Consumes 38-40 clocks on current Intel x86 and x64 hardware. +#elif defined(OVR_CC_MSVC) +#include +#pragma intrinsic(_mm_pause) // Maps to asm pause. +#define OVR_PROCESSOR_PAUSE _mm_pause +#else +#define OVR_PROCESSOR_PAUSE() +#endif +#else +#define OVR_PROCESSOR_PAUSE() +#endif +#endif + +// ------------------------------------------------------------------------ +// ***** OVR_union_cast +// +// Implements a reinterpret cast which is strict-aliasing safe. Recall that +// it's not sufficient to do a C++ reinterpret_cast or C-style cast in order +// to avoid strict-aliasing violation. The downside to this utility is that +// it works by copying the variable through a union, and this can be have +// a performance hit if the type is not small. +// +// Requires both types to be POD (plain old data), such as built-in types +// or C style structs. +// +// Example usage: +// double d = 1.0; +// int64_t i = union_cast(d); +// +// Note that you cannot safetly use union_cast to alias the contents of two +// unrelated pointers. It can be used to alias values, not pointers to values. + +namespace OVR { +template +DestType union_cast(SourceType sourceValue) { + static_assert(sizeof(DestType) == sizeof(SourceType), "union_cast size mismatch"); + static_assert(OVR_ALIGNOF(DestType) == OVR_ALIGNOF(SourceType), "union_cast alignment mismatch"); + + union SourceDest { + SourceType sourceValue; + DestType destValue; + }; + + SourceDest sd = {sourceValue}; + return sd.destValue; +} +} // namespace OVR + +// ------------------------------------------------------------------------ +// ***** OVR_VA_COPY +// +// Implements a version of C++11's va_copy that works with pre-C++11 compilers. +// +// Example usage: +// void Printf(char* pFormat, ...) +// { +// va_list argList; +// va_list argListCopy; +// +// va_start(argList, pFormat); +// OVR_VA_COPY(argListCopy, argList); +// +// +// va_end(argList); +// va_end(argListCopy); +// } +// +#if !defined(OVR_VA_COPY) +#if defined(__GNUC__) || defined(__clang__) // GCC / clang +#define OVR_VA_COPY(dest, src) va_copy((dest), (src)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1800) // VS2013+ +#define OVR_VA_COPY(dest, src) va_copy((dest), (src)) +#else +// This may not work for some platforms, depending on their ABI. +// It works for many Microsoft platforms. +#define OVR_VA_COPY(dest, src) memcpy(&(dest), &(src), sizeof(va_list)) +#endif +#endif + +// ------------------------------------------------------------------------ +// ***** OVR_ARRAY_COUNT +// +// Returns the element count of a C array. +// +// Example usage: +// float itemArray[16]; +// for(size_t i = 0; i < OVR_ARRAY_COUNT(itemArray); i++) { ... } + +#if defined(OVR_CPP_NO_CONSTEXPR) +#ifndef OVR_ARRAY_COUNT +#define OVR_ARRAY_COUNT(x) (sizeof(x) / sizeof(x[0])) +#endif +#else +// Smarter C++11 version which knows the difference between arrays and pointers. ; +template +struct OVRArrayCountOf_helper; + +template +struct OVRArrayCountOf_helper { + enum : std::size_t { size = N }; +}; + +template +struct OVRArrayCountOf_helper { + enum : std::size_t { size = N }; +}; + +template +constexpr std::size_t OVRArrayCountOf() { + return OVRArrayCountOf_helper::size; +} + +#define OVR_ARRAY_COUNT(x) OVRArrayCountOf() +#endif + +// ------------------------------------------------------------------------ +// ***** OVR_CURRENT_FUNCTION +// +// Portable wrapper for __PRETTY_FUNCTION__, C99 __func__, __FUNCTION__. +// This represents the most expressive version available. +// Acts as if the following were declared: +// static const char OVR_CURRENT_FUNCTION[] = "function-name"; +// +// Example usage: +// void Test() { printf("%s", OVR_CURRENT_FUNCTION); } + +#if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) || \ + (defined(__ICC) && (__ICC >= 600)) // GCC, clang, Intel +#define OVR_CURRENT_FUNCTION __PRETTY_FUNCTION__ +#elif defined(__FUNCSIG__) // VC++ +#define OVR_CURRENT_FUNCTION __FUNCSIG__ +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) // C99 compilers +#define OVR_CURRENT_FUNCTION __func__ +#else +#define OVR_CURRENT_FUNCTION __FUNCTION__ +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_DEPRECATED / OVR_DEPRECATED_MSG +// +// Portably annotates a function or struct as deprecated. +// Note that clang supports __deprecated_enum_msg, which may be useful to support. +// +// Example usage: +// OVR_DEPRECATED void Test(); // Use on the function declaration, as opposed to +// definition. +// +// struct OVR_DEPRECATED Test{ ... }; +// +// OVR_DEPRECATED_MSG("Test is deprecated") +// void Test(); + +#if !defined(OVR_DEPRECATED) +#if defined(OVR_CC_MSVC) && (OVR_CC_VERSION > 1400) // VS2005+ +#define OVR_DEPRECATED __declspec(deprecated) +#define OVR_DEPRECATED_MSG(msg) __declspec(deprecated(msg)) +#elif defined(OVR_CC_CLANG) && OVR_CC_HAS_FEATURE(attribute_deprecated_with_message) +#define OVR_DEPRECATED __declspec(deprecated) +#define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) +#elif defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 405) +#define OVR_DEPRECATED __declspec(deprecated) +#define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) +#elif !defined(OVR_CC_MSVC) +#define OVR_DEPRECATED __attribute__((deprecated)) +#define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated)) +#else +#define OVR_DEPRECATED +#define OVR_DEPRECATED_MSG(msg) +#endif +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_SELECTANY +// +// Implements a wrapper for Microsoft's __declspec(selectany) +// +// Example usage: +// SomeFile.h: +// extern const OVR_SELECTANY float OVR_Pi = 3.14f; // Allows you to declare floating point +// constants in header files. +// +// Example usage: +// SomeStruct.h: +// struct Some { +// static const x = 37; // See below for definition, which is required by C++11: 9.4.2p3. +// }; +// +// SomeStruct.cpp: +// OVR_SELECTANY const int Some::x; // You need to use selectany here for static const +// member definitions because the VC++ linker requires it. Other linkers do not. +// + +#if !defined(OVR_SELECTANY) +#if defined(_MSC_VER) +#define OVR_SELECTANY __declspec(selectany) +#else +#define OVR_SELECTANY // selectany is similar to weak linking but not enough to attempt to use +// __attribute__((weak)) here. +#endif +#endif + +// OVR_RUN_ONCE +// +// Executes a block of code only the first time it is encountered. +// +// This macro is not thread-safe. If two threads execute this simultaneously then it's +// possible that execution will occur twice. +// +// This macro will generate some code (to read a static bool) even if the block is empty, +// such as if the block goes away in a release build. +// +// C++11 has the std::call_once facility, which is similar to this but is restricted to a +// calling an individual function. It is thread-safe, however. +// +// Example usage: +// OVR_RUN_ONCE { +// printf("Hello world"); +// } +// +#ifndef OVR_RUN_ONCE +#define OVR_RUN_ONCE for (static bool executed = false; !executed; executed = true) +#endif + +// OVR_RUN_ONCE_CONDITION +// +// This is the same as OVR_RUN_ONCE except that it evaluates a condition before considering +// whether to execute the code block. The block is executed at most once, the first time the +// condition evaluates to true. +// +// Example usage: +// OVR_RUN_ONCE_CONDITION(time > 1000) { +// printf("Hello world"); +// } +// +#ifndef OVR_RUN_ONCE_CONDITION +#define OVR_RUN_ONCE_CONDITION(condition) \ + for (static bool executed = false; !executed && (condition); executed = true) +#endif + +//----------------------------------------------------------------------------------- +// ***** OVR_UNUSED - Unused Argument handling +// Macro to quiet compiler warnings about unused parameters/variables. +// +// Example usage: +// void Test() { +// int x = SomeFunction(); +// OVR_UNUSED(x); +// } +// + +#ifndef OVR_UNUSED +#if defined(OVR_CC_GNU) +#define OVR_UNUSED(a) \ + do { \ + __typeof__(&a) __attribute__((unused)) __tmp = &a; \ + } while (0) +#else +#define OVR_UNUSED(a) ((void)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) +#endif + +//----------------------------------------------------------------------------------- +// ***** Configuration Macros +// +// Expands to the current build type as a const char string literal. +// Acts as the following declaration: const char OVR_BUILD_STRING[]; + +#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 +// + +//----------------------------------------------------------------------------------- +// ***** Find normal allocations +// +// Our allocations are all supposed to go through the OVR System Allocator, so that +// they can be run through a game's own preferred allocator. Occasionally we will +// accidentally introduce new code that doesn't adhere to this contract. And it +// then becomes difficult to track down these normal allocations. This piece of +// code makes it easy to check for normal allocations by asserting whenever they +// happen in our code. + +//#define OVR_FIND_NORMAL_ALLOCATIONS +#ifdef OVR_FIND_NORMAL_ALLOCATIONS + +inline void* operator new(size_t size, const char* filename, int line) { + void* ptr = new char[size]; + OVR_ASSERT(false); + return ptr; +} + +#define new new (__FILE__, __LINE__) + +#endif // OVR_FIND_NORMAL_ALLOCATIONS + +#include "OVR_Nullptr.h" + +#endif // OVR_Types_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_UTF8Util.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_UTF8Util.cpp new file mode 100644 index 0000000..4f0311f --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_UTF8Util.cpp @@ -0,0 +1,390 @@ +/************************************************************************** + +Filename : OVR_UTF8Util.cpp +Content : UTF8 Unicode character encoding/decoding support +Created : September 19, 2012 +Notes : +Notes : Much useful info at "UTF-8 and Unicode FAQ" + http://www.cl.cam.ac.uk/~mgk25/unicode.html + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_UTF8Util.h" +#include +#include + +// sizeof(wchar_t) in preprocessor-accessible form. +#ifndef OVR_WCHAR_SIZE +#if defined(__WCHAR_MAX__) +#if (__WCHAR_MAX__ == 127) || (__WCHAR_MAX__ == 255) +#define OVR_WCHAR_SIZE 1 +#elif (__WCHAR_MAX__ == 32767) || (__WCHAR_MAX__ == 65535) +#define OVR_WCHAR_SIZE 2 +#else +#define OVR_WCHAR_SIZE 4 +#endif +#elif defined(OVR_OS_UNIX) +#define OVR_WCHAR_SIZE 4 +#else +#define OVR_WCHAR_SIZE 2 +#endif +#endif + +namespace OVR { +namespace UTF8Util { + +size_t Strlcpy(char* pDestUTF8, size_t destCharCount, const wchar_t* pSrcUCS, size_t sourceLength) { + if (sourceLength == (size_t)-1) + sourceLength = wcslen(pSrcUCS); + + size_t destLength = 0; + + size_t i; + for (i = 0; i < sourceLength; ++i) { + char buff[6]; // longest utf8 encoding just to be safe + intptr_t count = 0; + + EncodeChar(buff, &count, pSrcUCS[i]); + + // If this character occupies more than the remaining space (leaving room for the trailing + // '\0'), truncate here + if ((destLength + count) >= destCharCount) + break; + + memcpy(pDestUTF8 + destLength, buff, count); + destLength += (size_t)count; + } + + // Should be true for all cases other than destCharCount == 0. + if (destLength < destCharCount) + pDestUTF8[destLength] = '\0'; + + // Compute the required destination size for any remaining source characters + // Note a very long wchar string with lots of multibyte encodings can overflow destLength + // This should be okay since we'll just treat those cases (likely to be originating + // from an attacker) as shorter strings + while (i < sourceLength) + destLength += GetEncodeCharSize(pSrcUCS[i++]); + + // Return the intended strlen of pDestUTF8. + return destLength; +} + +size_t Strlcpy(wchar_t* pDestUCS, size_t destCharCount, const char* pSrcUTF8, size_t sourceLength) { + if (sourceLength == (size_t)-1) + sourceLength = strlen(pSrcUTF8); + + size_t destLength = 0, requiredLength = 0; + + for (const char* pSrcUTF8End = (pSrcUTF8 + sourceLength); pSrcUTF8 < pSrcUTF8End;) { + uint32_t c = DecodeNextChar_Advance0(&pSrcUTF8); + OVR_ASSERT_M( + pSrcUTF8 <= (pSrcUTF8 + sourceLength), "Strlcpy sourceLength was not on a UTF8 boundary."); + +#if (OVR_WCHAR_SIZE == 2) + if (c >= 0x0000FFFF) + c = 0x0000FFFD; +#endif + + if ((destLength + 1) < destCharCount) // If there is enough space to append a wchar_t (leaving + // room for a trailing '\0')... + { + pDestUCS[destLength] = wchar_t(c); + destLength++; + } + + requiredLength++; + } + + if (destLength < destCharCount) + pDestUCS[destLength] = L'\0'; + + return requiredLength; // Return the intended wcslen of pDestUCS. +} + +intptr_t GetLength(const char* buf, intptr_t buflen) { + const char* p = buf; + intptr_t length = 0; + + if (buflen != -1) { + while (p - buf < buflen) { + // We should be able to have ASStrings with 0 in the middle. + UTF8Util::DecodeNextChar_Advance0(&p); + length++; + } + } else { + while (UTF8Util::DecodeNextChar_Advance0(&p)) + length++; + } + + return length; +} + +uint32_t GetCharAt(intptr_t index, const char* putf8str, intptr_t length) { + const char* buf = putf8str; + uint32_t c = 0; + + if (length != -1) { + while (buf - putf8str < length) { + c = UTF8Util::DecodeNextChar_Advance0(&buf); + if (index == 0) + return c; + index--; + } + + return c; + } + + do { + c = UTF8Util::DecodeNextChar_Advance0(&buf); + index--; + + if (c == 0) { + // We've hit the end of the string; don't go further. + OVR_ASSERT(index == 0); + return c; + } + } while (index >= 0); + + return c; +} + +intptr_t GetByteIndex(intptr_t index, const char* putf8str, intptr_t byteLength) { + const char* buf = putf8str; + + if (byteLength >= 0) { + const char* lastValid = putf8str; + while ((buf - putf8str) < byteLength && index > 0) { + lastValid = buf; + // XXX this may read up to 5 bytes past byteLength + UTF8Util::DecodeNextChar_Advance0(&buf); + index--; + } + + // check for UTF8 characters which ran past the end of the buffer + if (buf - putf8str > byteLength) + return lastValid - putf8str; + + return buf - putf8str; + } + + while (index > 0) { + uint32_t c = UTF8Util::DecodeNextChar(&buf); + index--; + + // okay to index past null-terminator, DecodeNextChar will not advance past it + if (c == 0) + break; + } + + return buf - putf8str; +} + +intptr_t GetByteIndexChecked(intptr_t index, const char* putf8str, intptr_t byteLength) { + const char* buf = putf8str; + + // before start of string? + if (index < 0) + return -1; + + if (byteLength >= 0) { + while ((buf - putf8str) < byteLength && index > 0) { + // XXX this may read up to 5 bytes past byteLength + UTF8Util::DecodeNextChar_Advance0(&buf); + index--; + } + + // check for UTF8 characters which ran past the end of the buffer + if ((buf - putf8str) > byteLength) + return -1; + } else { + while (index > 0) { + uint32_t c = UTF8Util::DecodeNextChar_Advance0(&buf); + index--; + + // ran past null terminator + if (c == 0) + return -1; + } + } + + // ran off end of string + if (index != 0) + return -1; + + // at the valid index'th character-boundary offset in the string + return buf - putf8str; +} + +int GetEncodeCharSize(uint32_t ucs_character) { + if (ucs_character <= 0x7F) + return 1; + else if (ucs_character <= 0x7FF) + return 2; + else if (ucs_character <= 0xFFFF) + return 3; + else if (ucs_character <= 0x1FFFFF) + return 4; + else if (ucs_character <= 0x3FFFFFF) + return 5; + else if (ucs_character <= 0x7FFFFFFF) + return 6; + else + return 0; +} + +uint32_t DecodeNextChar_Advance0(const char** putf8Buffer) { + uint32_t uc; + char c; + +// Security considerations: +// +// Changed, this is now only the case for DecodeNextChar: +// - If we hit a zero byte, we want to return 0 without stepping +// the buffer pointer past the 0. th +// +// If we hit an "overlong sequence"; i.e. a character encoded +// in a longer multibyte string than is necessary, then we +// need to discard the character. This is so attackers can't +// disguise dangerous characters or character sequences -- +// there is only one valid encoding for each character. +// +// If we decode characters { 0xD800 .. 0xDFFF } or { 0xFFFE, +// 0xFFFF } then we ignore them; they are not valid in UTF-8. + +// This isn't actually an invalid character; it's a valid char that +// looks like an inverted question mark. +#define INVALID_CHAR 0x0FFFD + +#define FIRST_BYTE(mask, shift) uc = (c & (mask)) << (shift); + +#define NEXT_BYTE(shift) \ + c = **putf8Buffer; \ + if (c == 0) \ + return 0; /* end of buffer, do not advance */ \ + if ((c & 0xC0) != 0x80) \ + return INVALID_CHAR; /* standard check */ \ + (*putf8Buffer)++; \ + uc |= (c & 0x3F) << shift; + + c = **putf8Buffer; + (*putf8Buffer)++; + if (c == 0) + return 0; // End of buffer. + + if ((c & 0x80) == 0) + return (uint32_t)c; // Conventional 7-bit ASCII. + + // Multi-byte sequences. + if ((c & 0xE0) == 0xC0) { + // Two-byte sequence. + FIRST_BYTE(0x1F, 6); + NEXT_BYTE(0); + if (uc < 0x80) + return INVALID_CHAR; // overlong + return uc; + } else if ((c & 0xF0) == 0xE0) { + // Three-byte sequence. + FIRST_BYTE(0x0F, 12); + NEXT_BYTE(6); + NEXT_BYTE(0); + if (uc < 0x800) + return INVALID_CHAR; // overlong + // Not valid ISO 10646, but Flash requires these to work + // see AS3 test e15_5_3_2_3 for String.fromCharCode().charCodeAt(0) + // if (uc >= 0x0D800 && uc <= 0x0DFFF) return INVALID_CHAR; + // if (uc == 0x0FFFE || uc == 0x0FFFF) return INVALID_CHAR; // not valid ISO 10646 + return uc; + } else if ((c & 0xF8) == 0xF0) { + // Four-byte sequence. + FIRST_BYTE(0x07, 18); + NEXT_BYTE(12); + NEXT_BYTE(6); + NEXT_BYTE(0); + if (uc < 0x010000) + return INVALID_CHAR; // overlong + return uc; + } else if ((c & 0xFC) == 0xF8) { + // Five-byte sequence. + FIRST_BYTE(0x03, 24); + NEXT_BYTE(18); + NEXT_BYTE(12); + NEXT_BYTE(6); + NEXT_BYTE(0); + if (uc < 0x0200000) + return INVALID_CHAR; // overlong + return uc; + } else if ((c & 0xFE) == 0xFC) { + // Six-byte sequence. + FIRST_BYTE(0x01, 30); + NEXT_BYTE(24); + NEXT_BYTE(18); + NEXT_BYTE(12); + NEXT_BYTE(6); + NEXT_BYTE(0); + if (uc < 0x04000000) + return INVALID_CHAR; // overlong + return uc; + } else { + // Invalid. + return INVALID_CHAR; + } +} + +void EncodeChar(char* pbuffer, intptr_t* pindex, uint32_t ucs_character) { + if (ucs_character <= 0x7F) { + // Plain single-byte ASCII. + pbuffer[(*pindex)++] = (char)ucs_character; + } else if (ucs_character <= 0x7FF) { + // Two bytes. + pbuffer[(*pindex)++] = 0xC0 | (char)(ucs_character >> 6); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); + } else if (ucs_character <= 0xFFFF) { + // Three bytes. + pbuffer[(*pindex)++] = 0xE0 | (char)(ucs_character >> 12); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); + } else if (ucs_character <= 0x1FFFFF) { + // Four bytes. + pbuffer[(*pindex)++] = 0xF0 | (char)(ucs_character >> 18); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); + } else if (ucs_character <= 0x3FFFFFF) { + // Five bytes. + pbuffer[(*pindex)++] = 0xF8 | (char)(ucs_character >> 24); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); + } else if (ucs_character <= 0x7FFFFFFF) { + // Six bytes. + pbuffer[(*pindex)++] = 0xFC | (char)(ucs_character >> 30); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 24) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); + } else { + // Invalid char; don't encode anything. + } +} +} // namespace UTF8Util +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_UTF8Util.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_UTF8Util.h new file mode 100644 index 0000000..61630be --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_UTF8Util.h @@ -0,0 +1,130 @@ +/************************************************************************************ + +Filename : OVR_UTF8Util.h +Content : UTF8 Unicode character encoding/decoding support +Created : September 19, 2012 +Notes : + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_UTF8Util_h +#define OVR_UTF8Util_h + +#include "OVR_Types.h" + +namespace OVR { +namespace UTF8Util { + +// *** wchar_t / UTF8 Unicode string conversion + +// Same behavior as strlcpy except it does an encoding conversion while doing the copy. +// length refers to wcslen(pSrcUCS). +// Returns the intended strlen of the destination. +// +// Example usage: +// wchar_t* strW = L"abcdefgh"; +// char buffer[4]; +// size_t requiredStrlen = Strlcpy(buffer, OVR_ARRAY_COUNT(buffer), strW); +// +// if(requiredStrlen >= OVR_ARRAY_COUNT(buffer)) // If not enough space... +// { +// char* pBuffer = new char[requiredStrlen + 1]; +// Strlcpy(pBuffer, OVR_ARRAY_COUNT(requiredStrlen + 1), strW); +// ... +// } +// +size_t Strlcpy( + char* pDestUTF8, + size_t destCharCount, + const wchar_t* pSrcUCS, + size_t sourceLength = (size_t)-1); + +// Same behavior as strlcpy except it does an encoding conversion while doing the copy. +// length refers to strlen(pSrcUTF8). +// Returns the intended wcslen of the destination. +// +// Example usage: +// char* str8 = "abcdefgh"; +// wchar_t buffer[4]; +// size_t requiredStrlen = Strlcpy(buffer, OVR_ARRAY_COUNT(buffer), str8); +// +// if(requiredStrlen >= OVR_ARRAY_COUNT(buffer)) // If not enough space... +// { +// wchar_t* pBuffer = new wchar_t[requiredStrlen + 1]; +// Strlcpy(pBuffer, OVR_ARRAY_COUNT(requiredStrlen + 1), str8); +// ... +// } +// +size_t Strlcpy( + wchar_t* pDestUCS, + size_t destCharCount, + const char* pSrcUTF8, + size_t sourceLength = (size_t)-1); + +// *** 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. +intptr_t GetLength(const char* putf8str, intptr_t 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_t GetCharAt(intptr_t index, const char* putf8str, intptr_t length = -1); + +// Converts UTF8 character index into byte offset. +// A valid offset is always returned, either to the start of the string if index < 0, +// or to the terminating null character/end of string if the index'th character is past byteLength. +// Characters which straddle byteLength are truncated. +intptr_t GetByteIndex(intptr_t index, const char* putf8str, intptr_t byteLength = -1); + +// Converts UTF8 character index into byte offset. +// -1 is returned if index was out of bounds or if the final character straddles byteLength. +intptr_t GetByteIndexChecked(intptr_t index, const char* putf8str, intptr_t byteLength = -1); + +// *** Individual character Encoding/Decoding. + +// Determined the number of bytes necessary to encode a UCS character. +int GetEncodeCharSize(uint32_t 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 EncodeChar(char* pbuffer, intptr_t* poffset, uint32_t 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_t DecodeNextChar_Advance0(const char** putf8Buffer); + +// Safer version of DecodeNextChar, which doesn't advance pointer if +// null character is hit. +inline uint32_t DecodeNextChar(const char** putf8Buffer) { + uint32_t ch = DecodeNextChar_Advance0(putf8Buffer); + if (ch == 0) + (*putf8Buffer)--; + return ch; +} +} // namespace UTF8Util +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Win32_IncludeWindows.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Win32_IncludeWindows.h new file mode 100644 index 0000000..f1159aa --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_Win32_IncludeWindows.h @@ -0,0 +1,209 @@ +/************************************************************************************ + +Filename : OVR_Win32_IncludeWindows.h +Content : Small helper header to include Windows.h properly +Created : Oct 16, 2014 +Authors : Chris Taylor, Scott Bassett + +Copyright : Copyright 2014 Oculus, Inc. All Rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Win32_IncludeWindows_h +#define OVR_Win32_IncludeWindows_h + +#include "OVR_Types.h" + +// Automatically avoid including the Windows header on non-Windows platforms. +#ifdef OVR_OS_MS + +// It is common practice to define WIN32_LEAN_AND_MEAN to reduce compile times. +// However this then requires us to define our own NTSTATUS data type and other +// irritations throughout our code-base. +#ifdef WIN32_LEAN_AND_MEAN +#undef WIN32_LEAN_AND_MEAN +#endif + +// Prevents from #including , as we use instead. +#ifndef _WINSOCKAPI_ +#define DID_DEFINE_WINSOCKAPI +#define _WINSOCKAPI_ +#endif + +// Prevents from defining min() and max() macro symbols. +#ifndef NOMINMAX +#define NOMINMAX +#endif + +OVR_DISABLE_ALL_MSVC_WARNINGS() +// d3dkmthk.h requires an NTSTATUS type, but WIN32_LEAN_AND_MEAN will prevent. +#define WIN32_NO_STATUS +#include +#undef WIN32_NO_STATUS +#include +OVR_RESTORE_ALL_MSVC_WARNINGS() + +#ifdef DID_DEFINE_WINSOCKAPI +#undef _WINSOCKAPI_ +#undef DID_DEFINE_WINSOCKAPI +#endif + +namespace OVR { + +//----------------------------------------------------------------------------- +// ScopedHANDLE +// +// MSVC 2010, and MSVC 2012 do not support the utility header. +// So we provide our own version of HandleRAII, which is an incredibly +// useful pattern for working with Windows HANDLE values. +// +// HANDLEs have two invalid values in Windows, either nullptr or +// INVALID_HANDLE_VALUE. The invalid value that is correct for the usage must +// be provided as the template argument. + +struct ScopedHANDLE_NullTraits { + // We cannot make this a static member variable as it is not an integral type. + inline static HANDLE InvalidValue() { + return nullptr; + } +}; +struct ScopedHANDLE_InvalidTraits { + inline static HANDLE InvalidValue() { + return INVALID_HANDLE_VALUE; + } +}; + +template +class ScopedHANDLE { + HANDLE hAttachedHandle; + + public: + ScopedHANDLE(HANDLE handle) : hAttachedHandle(handle) {} + ScopedHANDLE() { + hAttachedHandle = Traits::InvalidValue(); + } + ScopedHANDLE& operator=(HANDLE handle) { + Close(); + hAttachedHandle = handle; + return *this; + } + ~ScopedHANDLE() { + Close(); + } + + bool IsValid() const { + return hAttachedHandle != Traits::InvalidValue(); + } + +#if !(defined(OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS) && OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS) + operator bool() const { + return IsValid(); + } + + operator HANDLE() const { + return hAttachedHandle; + } +#endif + + HANDLE Get() const { + return hAttachedHandle; + } + HANDLE& GetRawRef() { + return hAttachedHandle; + } + void Attach(HANDLE handle) { + Close(); + hAttachedHandle = handle; + } + void Detach() { + // Do not close handle + hAttachedHandle = Traits::InvalidValue(); + } + bool Close() { + bool success = true; + if (hAttachedHandle != Traits::InvalidValue()) { + if (::CloseHandle(hAttachedHandle) != TRUE) { + success = false; + } + hAttachedHandle = Traits::InvalidValue(); + } + return success; + } +}; + +// Different Windows API functions have different invalid values. +// These types are provided to improve readability. +typedef ScopedHANDLE ScopedMutexHANDLE; +typedef ScopedHANDLE ScopedEventHANDLE; +typedef ScopedHANDLE ScopedFileHANDLE; +typedef ScopedHANDLE ScopedProcessHANDLE; +typedef ScopedHANDLE ScopedThreadHANDLE; +typedef ScopedHANDLE ScopedSemaphoreHANDLE; + +// Scoped registry keys +class ScopedHKEY { + HKEY hAttachedHandle; + + public: + ScopedHKEY(HKEY handle) : hAttachedHandle(handle) {} + ScopedHKEY() { + hAttachedHandle = nullptr; + } + ScopedHKEY& operator=(HKEY handle) { + Close(); + hAttachedHandle = handle; + return *this; + } + ~ScopedHKEY() { + Close(); + } + + bool IsValid() { + return hAttachedHandle != nullptr; + } + HKEY Get() { + return hAttachedHandle; + } + HKEY& GetRawRef() { + return hAttachedHandle; + } + void Attach(HKEY handle) { + Close(); + hAttachedHandle = handle; + } + void Detach() { + // Do not close handle + hAttachedHandle = nullptr; + } + bool Close() { + bool success = true; + if (hAttachedHandle != nullptr) { + if (::RegCloseKey(hAttachedHandle) == ERROR_SUCCESS) { + success = false; + } + hAttachedHandle = nullptr; + } + return success; + } +}; + +} // namespace OVR + +#endif // OVR_OS_MS + +#endif // OVR_Win32_IncludeWindows_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/WindowsAFunctions.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/WindowsAFunctions.h new file mode 100644 index 0000000..80fa9ee --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/WindowsAFunctions.h @@ -0,0 +1,4887 @@ +// This header file's purpose is to kill Windows A functions, for the purpose of preventing +// localization +// mistakes in application code. Windows A functions are not UTF-8-aware and cannot be used in any +// practical +// way in properly engineered localization-compatible code. What you want to do with this header is +// set your +// build to either auto-include this for builds (VC++ supports this) or otherwise make sure it is +// #included +// in every compilation unit. If code attempts to use an unsafe function then an error will be +// generated. + +#define RtlIpv4AddressToStringExA OVR_UNDEFINED +#define RtlIpv6AddressToStringExA OVR_UNDEFINED +#define ConvertInterfaceNameToLuidA OVR_UNDEFINED +#define ConvertInterfaceLuidToNameA OVR_UNDEFINED +#define StrToIntExA OVR_UNDEFINED +#define PathCompactPathExA OVR_UNDEFINED +#define PathCanonicalizeA OVR_UNDEFINED +#define ConvertSidToStringSidA OVR_UNDEFINED +#define ConvertStringSidToSidA OVR_UNDEFINED +#define ConvertStringSecurityDescriptorToSecurityDescriptorA OVR_UNDEFINED +#define ConvertSecurityDescriptorToStringSecurityDescriptorA OVR_UNDEFINED +#define GetUserNameExA OVR_UNDEFINED +#define GetComputerObjectNameA OVR_UNDEFINED +#define TranslateNameA OVR_UNDEFINED +#define StrToIntExA OVR_UNDEFINED +#define PathCompactPathExA OVR_UNDEFINED +#define AcquireCredentialsHandleA OVR_UNDEFINED +#define AddCredentialsA OVR_UNDEFINED +#define SspiAcquireCredentialsHandleAsyncA OVR_UNDEFINED +#define SspiInitializeSecurityContextAsyncA OVR_UNDEFINED +#define ChangeAccountPasswordA OVR_UNDEFINED +#define InitializeSecurityContextA OVR_UNDEFINED +#define QueryContextAttributesA OVR_UNDEFINED +#define QueryContextAttributesExA OVR_UNDEFINED +#define SetContextAttributesA OVR_UNDEFINED +#define QueryCredentialsAttributesA OVR_UNDEFINED +#define QueryCredentialsAttributesExA OVR_UNDEFINED +#define SetCredentialsAttributesA OVR_UNDEFINED +#define EnumerateSecurityPackagesA OVR_UNDEFINED +#define QuerySecurityPackageInfoA OVR_UNDEFINED +#define ImportSecurityContextA OVR_UNDEFINED +#define InitSecurityInterfaceA OVR_UNDEFINED +#define SaslEnumerateProfilesA OVR_UNDEFINED +#define SaslGetProfilePackageA OVR_UNDEFINED +#define SaslIdentifyPackageA OVR_UNDEFINED +#define SaslInitializeSecurityContextA OVR_UNDEFINED +#define SspiPromptForCredentialsA OVR_UNDEFINED +#define AddSecurityPackageA OVR_UNDEFINED +#define DeleteSecurityPackageA OVR_UNDEFINED +#define StringLengthWorkerA OVR_UNDEFINED +#define StringExValidateSrcA OVR_UNDEFINED +#define StringValidateDestA OVR_UNDEFINED +#define StringValidateDestAndLengthA OVR_UNDEFINED +#define StringExValidateDestA OVR_UNDEFINED +#define StringExValidateDestAndLengthA OVR_UNDEFINED +#define StringCopyWorkerA OVR_UNDEFINED +#define StringVPrintfWorkerA OVR_UNDEFINED +#define StringVPrintf_lWorkerA OVR_UNDEFINED +#define StringGetsWorkerA OVR_UNDEFINED +#define StringExHandleFillBehindNullA OVR_UNDEFINED +#define StringExHandleOtherFlagsA OVR_UNDEFINED +#define StringCchCopyA OVR_UNDEFINED +#define StringCbCopyA OVR_UNDEFINED +#define StringCchCopyExA OVR_UNDEFINED +#define AddCredentialsA OVR_UNDEFINED +#define SspiAcquireCredentialsHandleAsyncA OVR_UNDEFINED +#define SspiInitializeSecurityContextAsyncA OVR_UNDEFINED +#define ChangeAccountPasswordA OVR_UNDEFINED +#define RtlStringLengthWorkerA OVR_UNDEFINED +#define RtlStringExValidateSrcA OVR_UNDEFINED +#define RtlStringValidateDestA OVR_UNDEFINED +#define RtlStringValidateDestAndLengthA OVR_UNDEFINED +#define RtlStringExValidateDestA OVR_UNDEFINED +#define RtlStringExValidateDestAndLengthA OVR_UNDEFINED +#define RtlStringCopyWorkerA OVR_UNDEFINED +#define RtlStringVPrintfWorkerA OVR_UNDEFINED +#define RtlStringExHandleFillBehindNullA OVR_UNDEFINED +#define RtlStringExHandleOtherFlagsA OVR_UNDEFINED +#define RtlStringCchCopyA OVR_UNDEFINED +#define RtlStringCbCopyA OVR_UNDEFINED +#define RtlStringCchCopyExA OVR_UNDEFINED +#define RtlStringCbCopyExA OVR_UNDEFINED +#define RtlStringCchCopyNA OVR_UNDEFINED +#define RtlStringCbCopyNA OVR_UNDEFINED +#define RtlStringCchCopyNExA OVR_UNDEFINED +#define RtlStringCbCopyNExA OVR_UNDEFINED +#define RtlStringCchCatA OVR_UNDEFINED +#define RtlStringCbCatA OVR_UNDEFINED +#define RtlStringCchCatExA OVR_UNDEFINED +#define RtlStringCbCatExA OVR_UNDEFINED +#define RtlStringCchCatNA OVR_UNDEFINED +#define RtlStringCbCatNA OVR_UNDEFINED +#define RtlStringCchCatNExA OVR_UNDEFINED +#define RtlStringCbCatNExA OVR_UNDEFINED +#define RtlStringCchVPrintfA OVR_UNDEFINED +#define RtlStringCbVPrintfA OVR_UNDEFINED +#define RtlStringCchPrintfA OVR_UNDEFINED +#define RtlStringCbPrintfA OVR_UNDEFINED +#define RtlStringCchPrintfExA OVR_UNDEFINED +#define RtlStringCbPrintfExA OVR_UNDEFINED +#define RtlStringCchVPrintfExA OVR_UNDEFINED +#define RtlStringCbVPrintfExA OVR_UNDEFINED +#define RtlStringCchLengthA OVR_UNDEFINED +#define RtlStringCbLengthA OVR_UNDEFINED +#define RtlStringLengthWorkerA OVR_UNDEFINED +#define RtlStringExValidateSrcA OVR_UNDEFINED +#define RtlStringValidateDestA OVR_UNDEFINED +#define RtlStringValidateDestAndLengthA OVR_UNDEFINED +#define RtlStringExValidateDestA OVR_UNDEFINED +#define RtlStringExValidateDestAndLengthA OVR_UNDEFINED +#define RtlStringCopyWorkerA OVR_UNDEFINED +#define RtlStringVPrintfWorkerA OVR_UNDEFINED +#define RtlStringExHandleFillBehindNullA OVR_UNDEFINED +#define RtlStringExHandleOtherFlagsA OVR_UNDEFINED +#define RtlIpv4AddressToStringExA OVR_UNDEFINED +#define RtlIpv6AddressToStringExA OVR_UNDEFINED +#define ConvertInterfaceNameToLuidA OVR_UNDEFINED +#define ConvertInterfaceLuidToNameA OVR_UNDEFINED +#define PathCanonicalizeA OVR_UNDEFINED +#define PathCompactPathExA OVR_UNDEFINED +#define PathCanonicalizeA OVR_UNDEFINED +#define ConvertSidToStringSidA OVR_UNDEFINED +#define ConvertStringSidToSidA OVR_UNDEFINED +#define ConvertStringSecurityDescriptorToSecurityDescriptorA OVR_UNDEFINED +#define ConvertSecurityDescriptorToStringSecurityDescriptorA OVR_UNDEFINED +#define GetUserNameExA OVR_UNDEFINED +#define GetComputerObjectNameA OVR_UNDEFINED +#define TranslateNameA OVR_UNDEFINED +#define StrToIntExA OVR_UNDEFINED +#define PathCompactPathExA OVR_UNDEFINED +#define PathCanonicalizeA OVR_UNDEFINED +#define AcquireCredentialsHandleA OVR_UNDEFINED +#define AddCredentialsA OVR_UNDEFINED +#define SspiAcquireCredentialsHandleAsyncA OVR_UNDEFINED +#define SspiInitializeSecurityContextAsyncA OVR_UNDEFINED +#define ChangeAccountPasswordA OVR_UNDEFINED +#define InitializeSecurityContextA OVR_UNDEFINED +#define QueryContextAttributesA OVR_UNDEFINED +#define QueryContextAttributesExA OVR_UNDEFINED +#define SetContextAttributesA OVR_UNDEFINED +#define QueryCredentialsAttributesA OVR_UNDEFINED +#define QueryCredentialsAttributesExA OVR_UNDEFINED +#define SetCredentialsAttributesA OVR_UNDEFINED +#define EnumerateSecurityPackagesA OVR_UNDEFINED +#define QuerySecurityPackageInfoA OVR_UNDEFINED +#define ImportSecurityContextA OVR_UNDEFINED +#define InitSecurityInterfaceA OVR_UNDEFINED +#define SaslEnumerateProfilesA OVR_UNDEFINED +#define SaslGetProfilePackageA OVR_UNDEFINED +#define SaslIdentifyPackageA OVR_UNDEFINED +#define SaslInitializeSecurityContextA OVR_UNDEFINED +#define SspiPromptForCredentialsA OVR_UNDEFINED +#define AddSecurityPackageA OVR_UNDEFINED +#define DeleteSecurityPackageA OVR_UNDEFINED +#define StringLengthWorkerA OVR_UNDEFINED +#define StringExValidateSrcA OVR_UNDEFINED +#define StringValidateDestA OVR_UNDEFINED +#define StringValidateDestAndLengthA OVR_UNDEFINED +#define StringExValidateDestA OVR_UNDEFINED +#define StringExValidateDestAndLengthA OVR_UNDEFINED +#define StringCopyWorkerA OVR_UNDEFINED +#define StringVPrintfWorkerA OVR_UNDEFINED +#define StringVPrintf_lWorkerA OVR_UNDEFINED +#define StringGetsWorkerA OVR_UNDEFINED +#define StringExHandleFillBehindNullA OVR_UNDEFINED +#define StringExHandleOtherFlagsA OVR_UNDEFINED +#define StringCchCopyA OVR_UNDEFINED +#define TcOpenInterfaceA OVR_UNDEFINED +#define TcQueryFlowA OVR_UNDEFINED +#define TcSetFlowA OVR_UNDEFINED +#define TcGetFlowNameA OVR_UNDEFINED +#define _VCrtDbgReportA OVR_UNDEFINED +#define SetEntriesInAclA OVR_UNDEFINED +#define GetExplicitEntriesFromAclA OVR_UNDEFINED +#define GetEffectiveRightsFromAclA OVR_UNDEFINED +#define GetAuditedPermissionsFromAclA OVR_UNDEFINED +#define GetNamedSecurityInfoA OVR_UNDEFINED +#define SetNamedSecurityInfoA OVR_UNDEFINED +#define GetInheritanceSourceA OVR_UNDEFINED +#define TreeResetNamedSecurityInfoA OVR_UNDEFINED +#define TreeSetNamedSecurityInfoA OVR_UNDEFINED +#define BuildSecurityDescriptorA OVR_UNDEFINED +#define LookupSecurityDescriptorPartsA OVR_UNDEFINED +#define BuildExplicitAccessWithNameA OVR_UNDEFINED +#define BuildImpersonateExplicitAccessWithNameA OVR_UNDEFINED +#define BuildTrusteeWithNameA OVR_UNDEFINED +#define BuildImpersonateTrusteeA OVR_UNDEFINED +#define BuildTrusteeWithSidA OVR_UNDEFINED +#define BuildTrusteeWithObjectsAndSidA OVR_UNDEFINED +#define BuildTrusteeWithObjectsAndNameA OVR_UNDEFINED +#define GetTrusteeNameA OVR_UNDEFINED +#define GetTrusteeTypeA OVR_UNDEFINED +#define GetTrusteeFormA OVR_UNDEFINED +#define GetMultipleTrusteeOperationA OVR_UNDEFINED +#define GetMultipleTrusteeA OVR_UNDEFINED +#define RunSetupCommandA OVR_UNDEFINED +#define RebootCheckOnInstallA OVR_UNDEFINED +#define TranslateInfStringA OVR_UNDEFINED +#define RegInstallA OVR_UNDEFINED +#define LaunchINFSectionExA OVR_UNDEFINED +#define ExecuteCabA OVR_UNDEFINED +#define AdvInstallFileA OVR_UNDEFINED +#define RegSaveRestoreA OVR_UNDEFINED +#define RegSaveRestoreOnINFA OVR_UNDEFINED +#define RegRestoreAllA OVR_UNDEFINED +#define FileSaveRestoreA OVR_UNDEFINED +#define FileSaveRestoreOnINFA OVR_UNDEFINED +#define AddDelBackupEntryA OVR_UNDEFINED +#define FileSaveMarkNotExistA OVR_UNDEFINED +#define GetVersionFromFileA OVR_UNDEFINED +#define GetVersionFromFileExA OVR_UNDEFINED +#define DelNodeA OVR_UNDEFINED +#define DelNodeRunDLL32A OVR_UNDEFINED +#define OpenINFEngineA OVR_UNDEFINED +#define TranslateInfStringExA OVR_UNDEFINED +#define ExtractFilesA OVR_UNDEFINED +#define LaunchINFSectionA OVR_UNDEFINED +#define UserInstStubWrapperA OVR_UNDEFINED +#define UserUnInstStubWrapperA OVR_UNDEFINED +#define SetPerUserSecValuesA OVR_UNDEFINED +#define ceGetOIDNameA OVR_UNDEFINED +#define ceVerifyObjIdA OVR_UNDEFINED +#define CAEnumFirstCA OVR_UNDEFINED +#define CAEnumNextCA OVR_UNDEFINED +#define CACreateNewCA OVR_UNDEFINED +#define CAUpdateCA OVR_UNDEFINED +#define CADeleteCA OVR_UNDEFINED +#define CACloseCA OVR_UNDEFINED +#define CAEnumCertTypesForCA OVR_UNDEFINED +#define CM_Add_IDA OVR_UNDEFINED +#define CM_Add_ID_ExA OVR_UNDEFINED +#define CM_Connect_MachineA OVR_UNDEFINED +#define CM_Create_DevNodeA OVR_UNDEFINED +#define CM_Create_DevNode_ExA OVR_UNDEFINED +#define CM_Enumerate_EnumeratorsA OVR_UNDEFINED +#define CM_Enumerate_Enumerators_ExA OVR_UNDEFINED +#define CM_Get_Class_NameA OVR_UNDEFINED +#define CM_Get_Class_Name_ExA OVR_UNDEFINED +#define CM_Get_Class_Key_NameA OVR_UNDEFINED +#define CM_Get_Class_Key_Name_ExA OVR_UNDEFINED +#define CM_Get_Device_IDA OVR_UNDEFINED +#define CM_Get_Device_ID_ExA OVR_UNDEFINED +#define CM_Get_Device_ID_ListA OVR_UNDEFINED +#define CM_Get_Device_ID_List_ExA OVR_UNDEFINED +#define CM_Get_Device_ID_List_SizeA OVR_UNDEFINED +#define CM_Get_Device_ID_List_Size_ExA OVR_UNDEFINED +#define CM_Get_DevNode_Registry_PropertyA OVR_UNDEFINED +#define CM_Get_DevNode_Registry_Property_ExA OVR_UNDEFINED +#define CM_Get_DevNode_Custom_PropertyA OVR_UNDEFINED +#define CM_Get_DevNode_Custom_Property_ExA OVR_UNDEFINED +#define CM_Get_Hardware_Profile_InfoA OVR_UNDEFINED +#define CM_Get_Hardware_Profile_Info_ExA OVR_UNDEFINED +#define CM_Get_HW_Prof_FlagsA OVR_UNDEFINED +#define CM_Get_HW_Prof_Flags_ExA OVR_UNDEFINED +#define CM_Get_Device_Interface_AliasA OVR_UNDEFINED +#define CM_Get_Device_Interface_Alias_ExA OVR_UNDEFINED +#define CM_Get_Device_Interface_ListA OVR_UNDEFINED +#define CM_Get_Device_Interface_List_ExA OVR_UNDEFINED +#define CM_Get_Device_Interface_List_SizeA OVR_UNDEFINED +#define CM_Get_Device_Interface_List_Size_ExA OVR_UNDEFINED +#define CM_Locate_DevNodeA OVR_UNDEFINED +#define CM_Locate_DevNode_ExA OVR_UNDEFINED +#define CM_Open_Class_KeyA OVR_UNDEFINED +#define CM_Open_Class_Key_ExA OVR_UNDEFINED +#define CM_Open_Device_Interface_KeyA OVR_UNDEFINED +#define CM_Open_Device_Interface_Key_ExA OVR_UNDEFINED +#define CM_Delete_Device_Interface_KeyA OVR_UNDEFINED +#define CM_Delete_Device_Interface_Key_ExA OVR_UNDEFINED +#define CM_Query_And_Remove_SubTreeA OVR_UNDEFINED +#define CM_Query_And_Remove_SubTree_ExA OVR_UNDEFINED +#define CM_Request_Device_EjectA OVR_UNDEFINED +#define CM_Request_Device_Eject_ExA OVR_UNDEFINED +#define CM_Register_Device_InterfaceA OVR_UNDEFINED +#define CM_Register_Device_Interface_ExA OVR_UNDEFINED +#define CM_Unregister_Device_InterfaceA OVR_UNDEFINED +#define CM_Unregister_Device_Interface_ExA OVR_UNDEFINED +#define CM_Set_DevNode_Registry_PropertyA OVR_UNDEFINED +#define CM_Set_DevNode_Registry_Property_ExA OVR_UNDEFINED +#define CM_Set_HW_Prof_FlagsA OVR_UNDEFINED +#define CM_Set_HW_Prof_Flags_ExA OVR_UNDEFINED +#define CM_Get_Resource_Conflict_DetailsA OVR_UNDEFINED +#define CM_Get_Class_Registry_PropertyA OVR_UNDEFINED +#define CM_Set_Class_Registry_PropertyA OVR_UNDEFINED +#define CmWwanPlusAuthAKA OVR_UNDEFINED +#define ImageList_LoadImageA OVR_UNDEFINED +#define DrawStatusTextA OVR_UNDEFINED +#define CreateStatusWindowA OVR_UNDEFINED +#define GetOpenFileNameA OVR_UNDEFINED +#define GetSaveFileNameA OVR_UNDEFINED +#define GetFileTitleA OVR_UNDEFINED +#define ChooseColorA OVR_UNDEFINED +#define FindTextA OVR_UNDEFINED +#define ReplaceTextA OVR_UNDEFINED +#define AfxReplaceTextA OVR_UNDEFINED +#define ChooseFontA OVR_UNDEFINED +#define PrintDlgExA OVR_UNDEFINED +#define PageSetupDlgA OVR_UNDEFINED +#define CommonPropertySheetUIA OVR_UNDEFINED +#define CommonPropertySheetUIA OVR_UNDEFINED +#define PeekConsoleInputA OVR_UNDEFINED +#define ReadConsoleA OVR_UNDEFINED +#define ReadConsoleInputA OVR_UNDEFINED +#define WriteConsoleA OVR_UNDEFINED +#define CertSelectCertificateA OVR_UNDEFINED +#define CertViewPropertiesA OVR_UNDEFINED +#define GetFriendlyNameOfCertA OVR_UNDEFINED +#define CertConfigureTrustA OVR_UNDEFINED +#define CryptUIDlgViewCertificateA OVR_UNDEFINED +#define CustomControlInfoA OVR_UNDEFINED +#define D3DX10CompileFromFileA OVR_UNDEFINED +#define D3DX10CompileFromResourceA OVR_UNDEFINED +#define D3DX10CreateEffectFromFileA OVR_UNDEFINED +#define D3DX10CreateEffectFromResourceA OVR_UNDEFINED +#define D3DX10CreateEffectPoolFromFileA OVR_UNDEFINED +#define D3DX10CreateEffectPoolFromResourceA OVR_UNDEFINED +#define D3DX10PreprocessShaderFromFileA OVR_UNDEFINED +#define D3DX10PreprocessShaderFromResourceA OVR_UNDEFINED +#define D3DX10CreateAsyncFileLoaderA OVR_UNDEFINED +#define D3DX10CreateAsyncResourceLoaderA OVR_UNDEFINED +#define D3DX10CreateFontA OVR_UNDEFINED +#define D3DX10CreateFontIndirectA OVR_UNDEFINED +#define D3DX10GetImageInfoFromFileA OVR_UNDEFINED +#define D3DX10GetImageInfoFromResourceA OVR_UNDEFINED +#define D3DX10CreateShaderResourceViewFromFileA OVR_UNDEFINED +#define D3DX10CreateTextureFromFileA OVR_UNDEFINED +#define D3DX10CreateShaderResourceViewFromResourceA OVR_UNDEFINED +#define D3DX10CreateTextureFromResourceA OVR_UNDEFINED +#define D3DX10SaveTextureToFileA OVR_UNDEFINED +#define D3DXCreateFontA OVR_UNDEFINED +#define D3DXCreateFontIndirectA OVR_UNDEFINED +#define D3DXCreateEffectFromFileA OVR_UNDEFINED +#define D3DXCreateEffectFromResourceA OVR_UNDEFINED +#define D3DXCreateEffectFromFileExA OVR_UNDEFINED +#define D3DXCreateEffectFromResourceExA OVR_UNDEFINED +#define D3DXCreateEffectCompilerFromFileA OVR_UNDEFINED +#define D3DXCreateEffectCompilerFromResourceA OVR_UNDEFINED +#define D3DXLoadMeshFromXA OVR_UNDEFINED +#define D3DXSaveMeshToXA OVR_UNDEFINED +#define D3DXLoadPRTBufferFromFileA OVR_UNDEFINED +#define D3DXSavePRTBufferToFileA OVR_UNDEFINED +#define D3DXLoadPRTCompBufferFromFileA OVR_UNDEFINED +#define D3DXSavePRTCompBufferToFileA OVR_UNDEFINED +#define D3DXAssembleShaderFromFileA OVR_UNDEFINED +#define D3DXAssembleShaderFromResourceA OVR_UNDEFINED +#define D3DXCompileShaderFromFileA OVR_UNDEFINED +#define D3DXCompileShaderFromResourceA OVR_UNDEFINED +#define D3DXPreprocessShaderFromFileA OVR_UNDEFINED +#define D3DXPreprocessShaderFromResourceA OVR_UNDEFINED +#define D3DXCreateTextA OVR_UNDEFINED +#define D3DXGetImageInfoFromFileA OVR_UNDEFINED +#define D3DXGetImageInfoFromResourceA OVR_UNDEFINED +#define D3DXLoadSurfaceFromFileA OVR_UNDEFINED +#define D3DXLoadSurfaceFromResourceA OVR_UNDEFINED +#define D3DXSaveSurfaceToFileA OVR_UNDEFINED +#define D3DXLoadVolumeFromFileA OVR_UNDEFINED +#define D3DXLoadVolumeFromResourceA OVR_UNDEFINED +#define D3DXSaveVolumeToFileA OVR_UNDEFINED +#define D3DXCreateTextureFromFileA OVR_UNDEFINED +#define D3DXCreateCubeTextureFromFileA OVR_UNDEFINED +#define D3DXCreateVolumeTextureFromFileA OVR_UNDEFINED +#define D3DXCreateTextureFromResourceA OVR_UNDEFINED +#define D3DXCreateCubeTextureFromResourceA OVR_UNDEFINED +#define D3DXCreateVolumeTextureFromResourceA OVR_UNDEFINED +#define D3DXCreateTextureFromFileExA OVR_UNDEFINED +#define D3DXCreateCubeTextureFromFileExA OVR_UNDEFINED +#define D3DXCreateVolumeTextureFromFileExA OVR_UNDEFINED +#define D3DXCreateTextureFromResourceExA OVR_UNDEFINED +#define D3DXCreateCubeTextureFromResourceExA OVR_UNDEFINED +#define D3DXCreateVolumeTextureFromResourceExA OVR_UNDEFINED +#define D3DXSaveTextureToFileA OVR_UNDEFINED +#define GetDateFormatA OVR_UNDEFINED +#define GetTimeFormatA OVR_UNDEFINED +#define SymMatchStringA OVR_UNDEFINED +#define SymAddSourceStreamA OVR_UNDEFINED +#define DdeInitializeA OVR_UNDEFINED +#define DdeCreateStringHandleA OVR_UNDEFINED +#define DdeQueryStringA OVR_UNDEFINED +#define DirectDrawEnumerateA OVR_UNDEFINED +#define DirectDrawEnumerateExA OVR_UNDEFINED +//#define OutputDebugStringA OVR_UNDEFINED +#define DriverPackagePreinstallA OVR_UNDEFINED +#define DriverPackageInstallA OVR_UNDEFINED +#define DriverPackageUninstallA OVR_UNDEFINED +#define DriverPackageGetPathA OVR_UNDEFINED +#define SetDifxLogCallbackA OVR_UNDEFINED +#define DIFXAPISetLogCallbackA OVR_UNDEFINED +#define ConfigureIMEA OVR_UNDEFINED +#define EnumRegisterWordA OVR_UNDEFINED +#define EscapeA OVR_UNDEFINED +#define GetCandidateListA OVR_UNDEFINED +#define GetCandidateListCountA OVR_UNDEFINED +#define GetCompositionFontA OVR_UNDEFINED +#define GetCompositionStringA OVR_UNDEFINED +#define GetConversionListA OVR_UNDEFINED +#define GetDescriptionA OVR_UNDEFINED +#define GetGuideLineA OVR_UNDEFINED +#define GetIMEFileNameA OVR_UNDEFINED +#define GetRegisterWordStyleA OVR_UNDEFINED +#define InstallIMEA OVR_UNDEFINED +#define IsUIMessageA OVR_UNDEFINED +#define RegisterWordA OVR_UNDEFINED +#define SetCompositionFontA OVR_UNDEFINED +#define SetCompositionStringA OVR_UNDEFINED +#define UnregisterWordA OVR_UNDEFINED +#define GetCodePageA OVR_UNDEFINED +#define GetImeMenuItemsA OVR_UNDEFINED +#define ConfigureIMEA OVR_UNDEFINED +#define EnumRegisterWordA OVR_UNDEFINED +#define EscapeA OVR_UNDEFINED +#define GetCandidateListA OVR_UNDEFINED +#define GetCandidateListCountA OVR_UNDEFINED +#define GetCompositionFontA OVR_UNDEFINED +#define GetCompositionStringA OVR_UNDEFINED +#define GetConversionListA OVR_UNDEFINED +#define GetDescriptionA OVR_UNDEFINED +#define GetGuideLineA OVR_UNDEFINED +#define GetIMEFileNameA OVR_UNDEFINED +#define GetRegisterWordStyleA OVR_UNDEFINED +#define InstallIMEA OVR_UNDEFINED +#define IsUIMessageA OVR_UNDEFINED +#define RegisterWordA OVR_UNDEFINED +#define SetCompositionFontA OVR_UNDEFINED +#define SetCompositionStringA OVR_UNDEFINED +#define UnregisterWordA OVR_UNDEFINED +#define GetCodePageA OVR_UNDEFINED +#define GetImeMenuItemsA OVR_UNDEFINED +#define RequestMessageA OVR_UNDEFINED +#define SendIMCA OVR_UNDEFINED +#define DsBrowseForContainerA OVR_UNDEFINED +#define DsGetDcNameA OVR_UNDEFINED +#define DsGetSiteNameA OVR_UNDEFINED +#define DsValidateSubnetNameA OVR_UNDEFINED +#define DsAddressToSiteNamesA OVR_UNDEFINED +#define DsAddressToSiteNamesExA OVR_UNDEFINED +#define DsGetDcSiteCoverageA OVR_UNDEFINED +#define DsGetDcOpenA OVR_UNDEFINED +#define DsGetDcNextA OVR_UNDEFINED +#define DirectSoundEnumerateA OVR_UNDEFINED +#define DirectSoundCaptureEnumerateA OVR_UNDEFINED +#define DsMakeSpnA OVR_UNDEFINED +#define DsCrackSpnA OVR_UNDEFINED +#define DsQuoteRdnValueA OVR_UNDEFINED +#define DsUnquoteRdnValueA OVR_UNDEFINED +#define DsCrackUnquotedMangledRdnA OVR_UNDEFINED +#define DsIsMangledRdnValueA OVR_UNDEFINED +#define DsIsMangledDnA OVR_UNDEFINED +#define DsCrackSpn2A OVR_UNDEFINED +#define FatalAppExitA OVR_UNDEFINED +#define AddERExcludedApplicationA OVR_UNDEFINED +#define AMGetErrorTextA OVR_UNDEFINED +#define JetInit3A OVR_UNDEFINED +#define JetCreateInstanceA OVR_UNDEFINED +#define JetCreateInstance2A OVR_UNDEFINED +#define JetSetSystemParameterA OVR_UNDEFINED +#define JetGetSystemParameterA OVR_UNDEFINED +#define JetEnableMultiInstanceA OVR_UNDEFINED +#define JetBeginSessionA OVR_UNDEFINED +#define JetCreateDatabaseA OVR_UNDEFINED +#define JetCreateDatabase2A OVR_UNDEFINED +#define JetAttachDatabaseA OVR_UNDEFINED +#define JetAttachDatabase2A OVR_UNDEFINED +#define JetDetachDatabaseA OVR_UNDEFINED +#define JetDetachDatabase2A OVR_UNDEFINED +#define JetGetObjectInfoA OVR_UNDEFINED +#define JetGetTableInfoA OVR_UNDEFINED +#define JetCreateTableA OVR_UNDEFINED +#define JetCreateTableColumnIndexA OVR_UNDEFINED +#define JetCreateTableColumnIndex2A OVR_UNDEFINED +#define JetCreateTableColumnIndex3A OVR_UNDEFINED +#define JetCreateTableColumnIndex4A OVR_UNDEFINED +#define JetDeleteTableA OVR_UNDEFINED +#define JetRenameTableA OVR_UNDEFINED +#define JetGetTableColumnInfoA OVR_UNDEFINED +#define JetGetColumnInfoA OVR_UNDEFINED +#define JetAddColumnA OVR_UNDEFINED +#define JetDeleteColumnA OVR_UNDEFINED +#define JetDeleteColumn2A OVR_UNDEFINED +#define JetRenameColumnA OVR_UNDEFINED +#define JetSetColumnDefaultValueA OVR_UNDEFINED +#define JetGetTableIndexInfoA OVR_UNDEFINED +#define JetGetIndexInfoA OVR_UNDEFINED +#define JetCreateIndexA OVR_UNDEFINED +#define JetCreateIndex2A OVR_UNDEFINED +#define JetCreateIndex3A OVR_UNDEFINED +#define JetCreateIndex4A OVR_UNDEFINED +#define JetDeleteIndexA OVR_UNDEFINED +#define JetGetDatabaseInfoA OVR_UNDEFINED +#define JetGetDatabaseFileInfoA OVR_UNDEFINED +#define JetOpenDatabaseA OVR_UNDEFINED +#define JetOpenTableA OVR_UNDEFINED +#define JetGetCurrentIndexA OVR_UNDEFINED +#define JetSetCurrentIndexA OVR_UNDEFINED +#define JetSetCurrentIndex2A OVR_UNDEFINED +#define JetSetCurrentIndex3A OVR_UNDEFINED +#define JetSetCurrentIndex4A OVR_UNDEFINED +#define JetCompactA OVR_UNDEFINED +#define JetDefragmentA OVR_UNDEFINED +#define JetDefragment2A OVR_UNDEFINED +#define JetDefragment3A OVR_UNDEFINED +#define JetSetDatabaseSizeA OVR_UNDEFINED +#define JetBackupA OVR_UNDEFINED +#define JetBackupInstanceA OVR_UNDEFINED +#define JetRestoreA OVR_UNDEFINED +#define JetRestore2A OVR_UNDEFINED +#define JetRestoreInstanceA OVR_UNDEFINED +#define JetGetAttachInfoA OVR_UNDEFINED +#define JetGetAttachInfoInstanceA OVR_UNDEFINED +#define JetOpenFileA OVR_UNDEFINED +#define JetOpenFileInstanceA OVR_UNDEFINED +#define JetGetLogInfoA OVR_UNDEFINED +#define JetGetLogInfoInstanceA OVR_UNDEFINED +#define JetGetLogInfoInstance2A OVR_UNDEFINED +#define JetGetTruncateLogInfoInstanceA OVR_UNDEFINED +#define JetExternalRestoreA OVR_UNDEFINED +#define JetExternalRestore2A OVR_UNDEFINED +#define JetGetInstanceInfoA OVR_UNDEFINED +#define JetOSSnapshotFreezeA OVR_UNDEFINED +#define JetOSSnapshotGetFreezeInfoA OVR_UNDEFINED +#define JetInit3A OVR_UNDEFINED +#define JetInit4A OVR_UNDEFINED +#define JetCreateInstanceA OVR_UNDEFINED +#define JetCreateInstance2A OVR_UNDEFINED +#define JetSetSystemParameterA OVR_UNDEFINED +#define JetGetSystemParameterA OVR_UNDEFINED +#define JetEnableMultiInstanceA OVR_UNDEFINED +#define JetBeginSessionA OVR_UNDEFINED +#define JetCreateDatabaseA OVR_UNDEFINED +#define JetCreateDatabase2A OVR_UNDEFINED +#define JetAttachDatabaseA OVR_UNDEFINED +#define JetAttachDatabase2A OVR_UNDEFINED +#define JetDetachDatabaseA OVR_UNDEFINED +#define JetDetachDatabase2A OVR_UNDEFINED +#define JetGetObjectInfoA OVR_UNDEFINED +#define JetGetTableInfoA OVR_UNDEFINED +#define JetSetTableInfoA OVR_UNDEFINED +#define JetCreateTableA OVR_UNDEFINED +#define JetCreateTableColumnIndexA OVR_UNDEFINED +#define JetCreateTableColumnIndex2A OVR_UNDEFINED +#define JetCreateTableColumnIndex3A OVR_UNDEFINED +#define JetCreateTableColumnIndex4A OVR_UNDEFINED +#define JetCreateTableColumnIndex5A OVR_UNDEFINED +#define JetDeleteTableA OVR_UNDEFINED +#define JetRenameTableA OVR_UNDEFINED +#define JetGetTableColumnInfoA OVR_UNDEFINED +#define JetGetColumnInfoA OVR_UNDEFINED +#define JetAddColumnA OVR_UNDEFINED +#define JetDeleteColumnA OVR_UNDEFINED +#define JetDeleteColumn2A OVR_UNDEFINED +#define JetRenameColumnA OVR_UNDEFINED +#define JetSetColumnDefaultValueA OVR_UNDEFINED +#define JetGetTableIndexInfoA OVR_UNDEFINED +#define JetGetIndexInfoA OVR_UNDEFINED +#define JetCreateIndexA OVR_UNDEFINED +#define JetCreateIndex2A OVR_UNDEFINED +#define JetCreateIndex3A OVR_UNDEFINED +#define JetCreateIndex4A OVR_UNDEFINED +#define JetDeleteIndexA OVR_UNDEFINED +#define JetGetDatabaseInfoA OVR_UNDEFINED +#define JetGetDatabaseFileInfoA OVR_UNDEFINED +#define JetGetLogFileInfoA OVR_UNDEFINED +#define JetOpenDatabaseA OVR_UNDEFINED +#define JetOpenTableA OVR_UNDEFINED +#define JetGetCurrentIndexA OVR_UNDEFINED +#define JetSetCurrentIndexA OVR_UNDEFINED +#define JetSetCurrentIndex2A OVR_UNDEFINED +#define JetSetCurrentIndex3A OVR_UNDEFINED +#define JetSetCurrentIndex4A OVR_UNDEFINED +#define JetCompactA OVR_UNDEFINED +#define JetDefragmentA OVR_UNDEFINED +#define JetDefragment2A OVR_UNDEFINED +#define JetDefragment3A OVR_UNDEFINED +#define JetConvertDDLA OVR_UNDEFINED +#define JetUpgradeDatabaseA OVR_UNDEFINED +#define JetSetDatabaseSizeA OVR_UNDEFINED +#define JetDBUtilitiesA OVR_UNDEFINED +#define JetBackupA OVR_UNDEFINED +#define JetBackupInstanceA OVR_UNDEFINED +#define JetRestoreA OVR_UNDEFINED +#define JetRestore2A OVR_UNDEFINED +#define JetRestoreInstanceA OVR_UNDEFINED +#define JetGetAttachInfoA OVR_UNDEFINED +#define JetGetAttachInfoInstanceA OVR_UNDEFINED +#define JetOpenFileA OVR_UNDEFINED +#define JetOpenFileInstanceA OVR_UNDEFINED +#define JetOpenFileSectionInstanceA OVR_UNDEFINED +#define JetGetLogInfoA OVR_UNDEFINED +#define JetGetLogInfoInstanceA OVR_UNDEFINED +#define JetGetLogInfoInstance2A OVR_UNDEFINED +#define JetGetTruncateLogInfoInstanceA OVR_UNDEFINED +#define JetExternalRestoreA OVR_UNDEFINED +#define JetExternalRestore2A OVR_UNDEFINED +#define JetSnapshotStartA OVR_UNDEFINED +#define JetGetInstanceInfoA OVR_UNDEFINED +#define JetOSSnapshotFreezeA OVR_UNDEFINED +#define JetOSSnapshotGetFreezeInfoA OVR_UNDEFINED +#define JetRemoveLogfileA OVR_UNDEFINED +#define JetBeginDatabaseIncrementalReseedA OVR_UNDEFINED +#define JetEndDatabaseIncrementalReseedA OVR_UNDEFINED +#define JetPatchDatabasePagesA OVR_UNDEFINED +#define CreateDirectoryA OVR_UNDEFINED +#define CreateFileA OVR_UNDEFINED +#define DeleteFileA OVR_UNDEFINED +#define FindFirstChangeNotificationA OVR_UNDEFINED +#define FindFirstFileA OVR_UNDEFINED +#define FindFirstFileExA OVR_UNDEFINED +#define FindNextFileA OVR_UNDEFINED +#define GetDiskFreeSpaceA OVR_UNDEFINED +#define GetDiskFreeSpaceExA OVR_UNDEFINED +#define GetDriveTypeA OVR_UNDEFINED +#define GetFileAttributesA OVR_UNDEFINED +#define GetFileAttributesExA OVR_UNDEFINED +#define GetFinalPathNameByHandleA OVR_UNDEFINED +#define GetFullPathNameA OVR_UNDEFINED +#define GetLongPathNameA OVR_UNDEFINED +#define RemoveDirectoryA OVR_UNDEFINED +#define SetFileAttributesA OVR_UNDEFINED +#define GetCompressedFileSizeA OVR_UNDEFINED +#define GetTempPathA OVR_UNDEFINED +#define GetVolumeInformationA OVR_UNDEFINED +#define GetTempFileNameA OVR_UNDEFINED +#define GdipCreateTextureIA OVR_UNDEFINED +#define GdipCreateFontFromLogfontA OVR_UNDEFINED +#define GdipGetLogFontA OVR_UNDEFINED +#define GetLogFontA OVR_UNDEFINED +#define GetLogFontA OVR_UNDEFINED +#define HtmlHelpA OVR_UNDEFINED +#define OpenColorProfileA OVR_UNDEFINED +#define CreateProfileFromLogColorSpaceA OVR_UNDEFINED +#define CreateColorTransformA OVR_UNDEFINED +#define RegisterCMMA OVR_UNDEFINED +#define UnregisterCMMA OVR_UNDEFINED +#define GetColorDirectoryA OVR_UNDEFINED +#define InstallColorProfileA OVR_UNDEFINED +#define UninstallColorProfileA OVR_UNDEFINED +#define EnumColorProfilesA OVR_UNDEFINED +#define SetStandardColorSpaceProfileA OVR_UNDEFINED +#define GetStandardColorSpaceProfileA OVR_UNDEFINED +#define AssociateColorProfileWithDeviceA OVR_UNDEFINED +#define DisassociateColorProfileFromDeviceA OVR_UNDEFINED +#define SetupColorMatchingA OVR_UNDEFINED +#define WcsOpenColorProfileA OVR_UNDEFINED +#define SymMatchStringA OVR_UNDEFINED +#define SymAddSourceStreamA OVR_UNDEFINED +#define SendIMEMessageExA OVR_UNDEFINED +#define ImmInstallIMEA OVR_UNDEFINED +#define UImmGetDescriptionA OVR_UNDEFINED +#define UImmGetIMEFileNameA OVR_UNDEFINED +#define ImmGetCompositionStringA OVR_UNDEFINED +#define ImmSetCompositionStringA OVR_UNDEFINED +#define ImmGetCandidateListCountA OVR_UNDEFINED +#define ImmGetCandidateListA OVR_UNDEFINED +#define ImmGetGuideLineA OVR_UNDEFINED +#define ImmGetCompositionFontA OVR_UNDEFINED +#define ImmSetCompositionFontA OVR_UNDEFINED +#define ImmConfigureIMEA OVR_UNDEFINED +#define ImmEscapeA OVR_UNDEFINED +#define ImmGetConversionListA OVR_UNDEFINED +#define ImmIsUIMessageA OVR_UNDEFINED +#define ImmRegisterWordA OVR_UNDEFINED +#define ImmUnregisterWordA OVR_UNDEFINED +#define UImmGetRegisterWordStyleA OVR_UNDEFINED +#define UImmEnumRegisterWordA OVR_UNDEFINED +#define ImmGetImeMenuItemsA OVR_UNDEFINED +#define ImmInstallIMEA OVR_UNDEFINED +#define UImmGetDescriptionA OVR_UNDEFINED +#define UImmGetIMEFileNameA OVR_UNDEFINED +#define ImmGetCompositionStringA OVR_UNDEFINED +#define ImmSetCompositionStringA OVR_UNDEFINED +#define ImmGetCandidateListCountA OVR_UNDEFINED +#define ImmGetCandidateListA OVR_UNDEFINED +#define ImmGetGuideLineA OVR_UNDEFINED +#define ImmGetCompositionFontA OVR_UNDEFINED +#define ImmSetCompositionFontA OVR_UNDEFINED +#define ImmConfigureIMEA OVR_UNDEFINED +#define ImmEscapeA OVR_UNDEFINED +#define ImmGetConversionListA OVR_UNDEFINED +#define ImmIsUIMessageA OVR_UNDEFINED +#define ImmRegisterWordA OVR_UNDEFINED +#define ImmUnregisterWordA OVR_UNDEFINED +#define UImmGetRegisterWordStyleA OVR_UNDEFINED +#define UImmEnumRegisterWordA OVR_UNDEFINED +#define ImmGetImeMenuItemsA OVR_UNDEFINED +#define ImmRequestMessageA OVR_UNDEFINED +#define INTSHCUTAPITranslateURLA OVR_UNDEFINED +#define INTSHCUTAPIURLAssociationDialogA OVR_UNDEFINED +#define INTSHCUTAPIMIMEAssociationDialogA OVR_UNDEFINED +#define GetIScsiTargetInformationA OVR_UNDEFINED +#define AddIScsiConnectionA OVR_UNDEFINED +#define ReportIScsiTargetsA OVR_UNDEFINED +#define AddIScsiStaticTargetA OVR_UNDEFINED +#define RemoveIScsiStaticTargetA OVR_UNDEFINED +#define AddIScsiSendTargetPortalA OVR_UNDEFINED +#define RemoveIScsiSendTargetPortalA OVR_UNDEFINED +#define RefreshIScsiSendTargetPortalA OVR_UNDEFINED +#define ReportIScsiSendTargetPortalsA OVR_UNDEFINED +#define ReportIScsiSendTargetPortalsExA OVR_UNDEFINED +#define LoginIScsiTargetA OVR_UNDEFINED +#define ReportIScsiPersistentLoginsA OVR_UNDEFINED +#define RemoveIScsiPersistentTargetA OVR_UNDEFINED +#define ReportIScsiInitiatorListA OVR_UNDEFINED +#define ReportActiveIScsiTargetMappingsA OVR_UNDEFINED +#define SetIScsiTunnelModeOuterAddressA OVR_UNDEFINED +#define SetIScsiIKEInfoA OVR_UNDEFINED +#define GetIScsiIKEInfoA OVR_UNDEFINED +#define SetIScsiInitiatorNodeNameA OVR_UNDEFINED +#define GetIScsiInitiatorNodeNameA OVR_UNDEFINED +#define AddISNSServerA OVR_UNDEFINED +#define RemoveISNSServerA OVR_UNDEFINED +#define RefreshISNSServerA OVR_UNDEFINED +#define ReportISNSServerListA OVR_UNDEFINED +#define GetIScsiSessionListA OVR_UNDEFINED +#define GetDevicesForIScsiSessionA OVR_UNDEFINED +#define AddPersistentIScsiDeviceA OVR_UNDEFINED +#define RemovePersistentIScsiDeviceA OVR_UNDEFINED +#define ReportPersistentIScsiDevicesA OVR_UNDEFINED +#define ReportIScsiTargetPortalsA OVR_UNDEFINED +#define AddRadiusServerA OVR_UNDEFINED +#define RemoveRadiusServerA OVR_UNDEFINED +#define ReportRadiusServerListA OVR_UNDEFINED +#define joyGetDevCapsA OVR_UNDEFINED +#define GetModuleFileNameA OVR_UNDEFINED +#define GetModuleHandleA OVR_UNDEFINED +#define GetModuleHandleExA OVR_UNDEFINED +#define LoadLibraryExA OVR_UNDEFINED +#define LoadStringA OVR_UNDEFINED +#define EnumResourceLanguagesExA OVR_UNDEFINED +#define EnumResourceNamesExA OVR_UNDEFINED +#define EnumResourceTypesExA OVR_UNDEFINED +#define LoadLibraryA OVR_UNDEFINED +#define InstallPerfDllA OVR_UNDEFINED +#define LoadPerfCounterTextStringsA OVR_UNDEFINED +#define UnloadPerfCounterTextStringsA OVR_UNDEFINED +#define UpdatePerfNameFilesA OVR_UNDEFINED +#define SetServiceAsTrustedA OVR_UNDEFINED +#define GetExpandedNameA OVR_UNDEFINED +#define LZOpenFileA OVR_UNDEFINED +#define mciSendCommandA OVR_UNDEFINED +#define mciSendStringA OVR_UNDEFINED +#define mciGetDeviceIDA OVR_UNDEFINED +#define mciGetDeviceIDFromElementIDA OVR_UNDEFINED +#define mciGetErrorStringA OVR_UNDEFINED +#define MFConvertColorInfoToDXVA OVR_UNDEFINED +#define MFConvertColorInfoFromDXVA OVR_UNDEFINED +#define MI_Instance_IsA OVR_UNDEFINED +#define SetStrBufA OVR_UNDEFINED +#define GetStrBufA OVR_UNDEFINED +#define LcidToRfc1766A OVR_UNDEFINED +#define Rfc1766ToLcidA OVR_UNDEFINED +#define waveOutGetDevCapsA OVR_UNDEFINED +#define waveOutGetErrorTextA OVR_UNDEFINED +#define waveInGetDevCapsA OVR_UNDEFINED +#define waveInGetErrorTextA OVR_UNDEFINED +#define midiOutGetDevCapsA OVR_UNDEFINED +#define midiOutGetErrorTextA OVR_UNDEFINED +#define midiInGetDevCapsA OVR_UNDEFINED +#define midiInGetErrorTextA OVR_UNDEFINED +#define auxGetDevCapsA OVR_UNDEFINED +#define mixerGetDevCapsA OVR_UNDEFINED +#define mixerGetLineInfoA OVR_UNDEFINED +#define mixerGetLineControlsA OVR_UNDEFINED +#define mixerGetControlDetailsA OVR_UNDEFINED +#define mmioStringToFOURCCA OVR_UNDEFINED +#define mmioInstallIOProcA OVR_UNDEFINED +#define mmioOpenA OVR_UNDEFINED +#define mmioRenameA OVR_UNDEFINED +#define PeekMessageA OVR_UNDEFINED +#define GetMessageA OVR_UNDEFINED +#define GetDeltaInfoA OVR_UNDEFINED +#define ApplyDeltaA OVR_UNDEFINED +#define CreateDeltaA OVR_UNDEFINED +#define GetDeltaSignatureA OVR_UNDEFINED +#define ConfigureIMEA OVR_UNDEFINED +#define EnumRegisterWordA OVR_UNDEFINED +#define EscapeA OVR_UNDEFINED +#define GetCandidateListA OVR_UNDEFINED +#define GetCandidateListCountA OVR_UNDEFINED +#define GetCompositionFontA OVR_UNDEFINED +#define GetCompositionStringA OVR_UNDEFINED +#define GetConversionListA OVR_UNDEFINED +#define GetDescriptionA OVR_UNDEFINED +#define GetGuideLineA OVR_UNDEFINED +#define GetIMEFileNameA OVR_UNDEFINED +#define GetRegisterWordStyleA OVR_UNDEFINED +#define InstallIMEA OVR_UNDEFINED +#define IsUIMessageA OVR_UNDEFINED +#define RegisterWordA OVR_UNDEFINED +#define SetCompositionFontA OVR_UNDEFINED +#define SetCompositionStringA OVR_UNDEFINED +#define UnregisterWordA OVR_UNDEFINED +#define GetCodePageA OVR_UNDEFINED +#define GetImeMenuItemsA OVR_UNDEFINED +#define ConfigureIMEA OVR_UNDEFINED +#define EnumRegisterWordA OVR_UNDEFINED +#define EscapeA OVR_UNDEFINED +#define GetCandidateListA OVR_UNDEFINED +#define GetCandidateListCountA OVR_UNDEFINED +#define GetCompositionFontA OVR_UNDEFINED +#define GetCompositionStringA OVR_UNDEFINED +#define GetConversionListA OVR_UNDEFINED +#define GetDescriptionA OVR_UNDEFINED +#define GetGuideLineA OVR_UNDEFINED +#define GetIMEFileNameA OVR_UNDEFINED +#define GetRegisterWordStyleA OVR_UNDEFINED +#define InstallIMEA OVR_UNDEFINED +#define IsUIMessageA OVR_UNDEFINED +#define RegisterWordA OVR_UNDEFINED +#define SetCompositionFontA OVR_UNDEFINED +#define SetCompositionStringA OVR_UNDEFINED +#define UnregisterWordA OVR_UNDEFINED +#define GetCodePageA OVR_UNDEFINED +#define GetImeMenuItemsA OVR_UNDEFINED +#define MsiSetExternalUIA OVR_UNDEFINED +#define UMsiEnableLogA OVR_UNDEFINED +#define MsiQueryProductStateA OVR_UNDEFINED +#define UMsiGetProductInfoA OVR_UNDEFINED +#define UMsiGetProductInfoExA OVR_UNDEFINED +#define UMsiInstallProductA OVR_UNDEFINED +#define UMsiConfigureProductA OVR_UNDEFINED +#define UMsiConfigureProductExA OVR_UNDEFINED +#define UMsiReinstallProductA OVR_UNDEFINED +#define UMsiAdvertiseProductExA OVR_UNDEFINED +#define UMsiAdvertiseProductA OVR_UNDEFINED +#define UMsiProcessAdvertiseScriptA OVR_UNDEFINED +#define UMsiAdvertiseScriptA OVR_UNDEFINED +#define UMsiGetProductInfoFromScriptA OVR_UNDEFINED +#define UMsiGetProductCodeA OVR_UNDEFINED +#define USERINFOSTATEMsiGetUserInfoA OVR_UNDEFINED +#define UMsiCollectUserInfoA OVR_UNDEFINED +#define UMsiApplyPatchA OVR_UNDEFINED +#define UMsiGetPatchInfoA OVR_UNDEFINED +#define UMsiEnumPatchesA OVR_UNDEFINED +#define UMsiRemovePatchesA OVR_UNDEFINED +#define UMsiExtractPatchXMLDataA OVR_UNDEFINED +#define UMsiGetPatchInfoExA OVR_UNDEFINED +#define UMsiApplyMultiplePatchesA OVR_UNDEFINED +#define UMsiDeterminePatchSequenceA OVR_UNDEFINED +#define UMsiDetermineApplicablePatchesA OVR_UNDEFINED +#define UMsiEnumPatchesExA OVR_UNDEFINED +#define MsiQueryFeatureStateA OVR_UNDEFINED +#define UMsiQueryFeatureStateExA OVR_UNDEFINED +#define MsiUseFeatureA OVR_UNDEFINED +#define MsiUseFeatureExA OVR_UNDEFINED +#define UMsiGetFeatureUsageA OVR_UNDEFINED +#define UMsiConfigureFeatureA OVR_UNDEFINED +#define UMsiReinstallFeatureA OVR_UNDEFINED +#define UMsiProvideComponentA OVR_UNDEFINED +#define UMsiProvideQualifiedComponentA OVR_UNDEFINED +#define UMsiProvideQualifiedComponentExA OVR_UNDEFINED +#define MsiGetComponentPathA OVR_UNDEFINED +#define MsiGetComponentPathExA OVR_UNDEFINED #define #define +#define UMsiProvideAssemblyA OVR_UNDEFINED +#define UMsiQueryComponentStateA OVR_UNDEFINED +#define UMsiEnumProductsA OVR_UNDEFINED +#define UMsiEnumProductsExA OVR_UNDEFINED +#define UMsiEnumRelatedProductsA OVR_UNDEFINED +#define UMsiEnumFeaturesA OVR_UNDEFINED +#define UMsiEnumComponentsA OVR_UNDEFINED +#define UMsiEnumComponentsExA OVR_UNDEFINED #define +#define UMsiEnumClientsA OVR_UNDEFINED +#define UMsiEnumComponentQualifiersA OVR_UNDEFINED +#define UMsiOpenProductA OVR_UNDEFINED +#define UMsiOpenPackageA OVR_UNDEFINED +#define UMsiOpenPackageExA OVR_UNDEFINED +#define UMsiGetPatchFileListA OVR_UNDEFINED +#define UMsiGetProductPropertyA OVR_UNDEFINED +#define UMsiVerifyPackageA OVR_UNDEFINED +#define UMsiGetFeatureInfoA OVR_UNDEFINED +#define UMsiInstallMissingComponentA OVR_UNDEFINED +#define UMsiInstallMissingFileA OVR_UNDEFINED +#define MsiLocateComponentA OVR_UNDEFINED +#define UMsiSourceListClearAllA OVR_UNDEFINED +#define UMsiSourceListAddSourceA OVR_UNDEFINED +#define UMsiSourceListForceResolutionA OVR_UNDEFINED +#define UMsiSourceListAddSourceExA OVR_UNDEFINED +#define UMsiSourceListAddMediaDiskA OVR_UNDEFINED +#define UMsiSourceListClearSourceA OVR_UNDEFINED +#define UMsiSourceListClearMediaDiskA OVR_UNDEFINED +#define UMsiSourceListClearAllExA OVR_UNDEFINED +#define UMsiSourceListForceResolutionExA OVR_UNDEFINED +#define UMsiSourceListSetInfoA OVR_UNDEFINED +#define UMsiSourceListGetInfoA OVR_UNDEFINED +#define UMsiSourceListEnumSourcesA OVR_UNDEFINED +#define UMsiSourceListEnumMediaDisksA OVR_UNDEFINED +#define UMsiGetFileVersionA OVR_UNDEFINED +#define UMsiGetFileHashA OVR_UNDEFINED +#define MsiGetFileSignatureInformationA OVR_UNDEFINED +#define UMsiGetShortcutTargetA OVR_UNDEFINED +#define UMsiIsProductElevatedA OVR_UNDEFINED +#define UMsiNotifySidChangeA OVR_UNDEFINED +#define UMsiBeginTransactionA OVR_UNDEFINED +#define UMsiDatabaseOpenViewA OVR_UNDEFINED +#define MSIDBERRORMsiViewGetErrorA OVR_UNDEFINED +#define UMsiDatabaseGetPrimaryKeysA OVR_UNDEFINED +#define MSICONDITIONMsiDatabaseIsTablePersistentA OVR_UNDEFINED +#define UMsiGetSummaryInformationA OVR_UNDEFINED +#define UMsiSummaryInfoSetPropertyA OVR_UNDEFINED +#define UMsiSummaryInfoGetPropertyA OVR_UNDEFINED +#define UMsiOpenDatabaseA OVR_UNDEFINED +#define UMsiDatabaseImportA OVR_UNDEFINED +#define UMsiDatabaseExportA OVR_UNDEFINED +#define UMsiDatabaseMergeA OVR_UNDEFINED +#define UMsiDatabaseGenerateTransformA OVR_UNDEFINED +#define UMsiDatabaseApplyTransformA OVR_UNDEFINED +#define UMsiCreateTransformSummaryInfoA OVR_UNDEFINED +#define UMsiRecordSetStringA OVR_UNDEFINED +#define UMsiRecordGetStringA OVR_UNDEFINED +#define UMsiRecordSetStreamA OVR_UNDEFINED +#define UMsiSetPropertyA OVR_UNDEFINED +#define UMsiGetPropertyA OVR_UNDEFINED +#define UMsiFormatRecordA OVR_UNDEFINED +#define UMsiDoActionA OVR_UNDEFINED +#define UMsiSequenceA OVR_UNDEFINED +#define MsiEvaluateConditionA OVR_UNDEFINED +#define UMsiGetFeatureStateA OVR_UNDEFINED +#define UMsiSetFeatureStateA OVR_UNDEFINED +#define UMsiSetFeatureAttributesA OVR_UNDEFINED +#define UMsiGetComponentStateA OVR_UNDEFINED +#define UMsiSetComponentStateA OVR_UNDEFINED +#define UMsiGetFeatureCostA OVR_UNDEFINED +#define UMsiEnumComponentCostsA OVR_UNDEFINED +#define UMsiGetFeatureValidStatesA OVR_UNDEFINED +#define UMsiGetSourcePathA OVR_UNDEFINED +#define UMsiGetTargetPathA OVR_UNDEFINED +#define UMsiSetTargetPathA OVR_UNDEFINED +#define UMsiPreviewDialogA OVR_UNDEFINED +#define UMsiPreviewBillboardA OVR_UNDEFINED +#define LoadMUILibraryA OVR_UNDEFINED +#define NMRtlIpv6AddressToStringA OVR_UNDEFINED +#define NMRtlIpv6StringToAddressA OVR_UNDEFINED +#define UpdateDriverForPlugAndPlayDevicesA OVR_UNDEFINED +#define DiInstallDriverA OVR_UNDEFINED +#define WNetSetLastErrorA OVR_UNDEFINED +#define DsBindA OVR_UNDEFINED +#define DsBindWithCredA OVR_UNDEFINED +#define DsBindWithSpnA OVR_UNDEFINED +#define DsBindWithSpnExA OVR_UNDEFINED +#define DsBindByInstanceA OVR_UNDEFINED +#define DsBindToISTGA OVR_UNDEFINED +#define DsUnBindA OVR_UNDEFINED +#define DsMakePasswordCredentialsA OVR_UNDEFINED +#define DsCrackNamesA OVR_UNDEFINED +#define DsFreeNameResultA OVR_UNDEFINED +#define DsGetSpnA OVR_UNDEFINED +#define DsFreeSpnArrayA OVR_UNDEFINED +#define DsWriteAccountSpnA OVR_UNDEFINED +#define DsClientMakeSpnForTargetServerA OVR_UNDEFINED +#define DsServerRegisterSpnA OVR_UNDEFINED +#define DsReplicaSyncA OVR_UNDEFINED +#define DsReplicaAddA OVR_UNDEFINED +#define DsReplicaDelA OVR_UNDEFINED +#define DsReplicaModifyA OVR_UNDEFINED +#define DsReplicaUpdateRefsA OVR_UNDEFINED +#define DsRemoveDsServerA OVR_UNDEFINED +#define DsRemoveDsDomainA OVR_UNDEFINED +#define DsListSitesA OVR_UNDEFINED +#define DsListServersInSiteA OVR_UNDEFINED +#define DsListDomainsInSiteA OVR_UNDEFINED +#define DsListServersForDomainInSiteA OVR_UNDEFINED +#define DsListInfoForServerA OVR_UNDEFINED +#define DsListRolesA OVR_UNDEFINED +#define DsQuerySitesByCostA OVR_UNDEFINED +#define DsMapSchemaGuidsA OVR_UNDEFINED +#define DsFreeSchemaGuidMapA OVR_UNDEFINED +#define DsGetDomainControllerInfoA OVR_UNDEFINED +#define DsFreeDomainControllerInfoA OVR_UNDEFINED +#define DsReplicaVerifyObjectsA OVR_UNDEFINED +#define DsAddSidHistoryA OVR_UNDEFINED +#define DsInheritSecurityIdentityA OVR_UNDEFINED +#define HANDLEOpenNtmsSessionA OVR_UNDEFINED +#define CreateNtmsMediaPoolA OVR_UNDEFINED +#define GetNtmsMediaPoolNameA OVR_UNDEFINED +#define GetNtmsObjectInformationA OVR_UNDEFINED +#define SetNtmsObjectInformationA OVR_UNDEFINED +#define CreateNtmsMediaA OVR_UNDEFINED +#define GetNtmsObjectAttributeA OVR_UNDEFINED +#define SetNtmsObjectAttributeA OVR_UNDEFINED +#define GetNtmsUIOptionsA OVR_UNDEFINED +#define SetNtmsUIOptionsA OVR_UNDEFINED +#define SubmitNtmsOperatorRequestA OVR_UNDEFINED +#define EjectDiskFromSADriveA OVR_UNDEFINED +#define GetVolumesFromDriveA OVR_UNDEFINED +#define LocateCatalogsA OVR_UNDEFINED_In_PCSTRpwszScope +#define AuditLookupCategoryNameA OVR_UNDEFINED +#define AuditLookupSubCategoryNameA OVR_UNDEFINED +#define AuditSetGlobalSaclA OVR_UNDEFINED +#define AuditQueryGlobalSaclA OVR_UNDEFINED +#define GetRoleTextA OVR_UNDEFINED +#define GetStateTextA OVR_UNDEFINED +#define CreateStdAccessibleProxyA OVR_UNDEFINED +#define LHashValOfNameSysA OVR_UNDEFINED +#define OleUIAddVerbMenuA OVR_UNDEFINED +#define OleUIInsertObjectA OVR_UNDEFINED +#define OleUIPasteSpecialA OVR_UNDEFINED +#define OleUIEditLinksA OVR_UNDEFINED +#define OleUIChangeIconA OVR_UNDEFINED +#define OleUIConvertA OVR_UNDEFINED +#define OleUIBusyA OVR_UNDEFINED +#define OleUIChangeSourceA OVR_UNDEFINED +#define OleUIObjectPropertiesA OVR_UNDEFINED +#define OleUIPromptUserA OVR_UNDEFINED +#define OleUIUpdateLinksA OVR_UNDEFINED +#define ConfigureIMEA OVR_UNDEFINED +#define EnumRegisterWordA OVR_UNDEFINED +#define EscapeA OVR_UNDEFINED +#define GetCandidateListA OVR_UNDEFINED +#define GetCandidateListCountA OVR_UNDEFINED +#define GetCompositionFontA OVR_UNDEFINED +#define GetCompositionStringA OVR_UNDEFINED +#define GetConversionListA OVR_UNDEFINED +#define GetDescriptionA OVR_UNDEFINED +#define GetGuideLineA OVR_UNDEFINED +#define GetIMEFileNameA OVR_UNDEFINED +#define GetRegisterWordStyleA OVR_UNDEFINED +#define InstallIMEA OVR_UNDEFINED +#define IsUIMessageA OVR_UNDEFINED +#define RegisterWordA OVR_UNDEFINED +#define SetCompositionFontA OVR_UNDEFINED +#define SetCompositionStringA OVR_UNDEFINED +#define UnregisterWordA OVR_UNDEFINED +#define GetCodePageA OVR_UNDEFINED +#define GetImeMenuItemsA OVR_UNDEFINED +#define CreatePatchFileA OVR_UNDEFINED +#define CreatePatchFileExA OVR_UNDEFINED +#define ExtractPatchHeaderToFileA OVR_UNDEFINED +#define TestApplyPatchToFileA OVR_UNDEFINED +#define ApplyPatchToFileA OVR_UNDEFINED +#define ApplyPatchToFileExA OVR_UNDEFINED +#define GetFilePatchSignatureA OVR_UNDEFINED +#define UUiCreatePatchPackageA OVR_UNDEFINED +#define UUiCreatePatchPackageExA OVR_UNDEFINED +#define PdhOpenQueryA OVR_UNDEFINED +#define PdhAddCounterA OVR_UNDEFINED +#define PdhAddEnglishCounterA OVR_UNDEFINED +#define PdhValidatePathExA OVR_UNDEFINED +#define PdhGetFormattedCounterArrayA OVR_UNDEFINED +#define PdhGetRawCounterArrayA OVR_UNDEFINED +#define PdhGetCounterInfoA OVR_UNDEFINED +#define PdhConnectMachineA OVR_UNDEFINED +#define PdhEnumMachinesA OVR_UNDEFINED +#define PdhEnumObjectsA OVR_UNDEFINED +#define PdhEnumObjectItemsA OVR_UNDEFINED +#define PdhMakeCounterPathA OVR_UNDEFINED +#define PdhParseCounterPathA OVR_UNDEFINED +#define PdhParseInstanceNameA OVR_UNDEFINED +#define PdhValidatePathA OVR_UNDEFINED +#define PdhGetDefaultPerfObjectA OVR_UNDEFINED +#define PdhGetDefaultPerfCounterA OVR_UNDEFINED +#define PdhBrowseCountersA OVR_UNDEFINED +#define PdhExpandCounterPathA OVR_UNDEFINED +#define PdhLookupPerfNameByIndexA OVR_UNDEFINED +#define PdhLookupPerfIndexByNameA OVR_UNDEFINED +#define PdhExpandWildCardPathA OVR_UNDEFINED +#define PdhOpenLogA OVR_UNDEFINED +#define PdhUpdateLogA OVR_UNDEFINED +#define PdhSelectDataSourceA OVR_UNDEFINED +#define PdhGetDataSourceTimeRangeA OVR_UNDEFINED +#define PdhBindInputDataSourceA OVR_UNDEFINED +#define PdhEnumMachinesHA OVR_UNDEFINED +#define PdhEnumObjectsHA OVR_UNDEFINED +#define PdhEnumObjectItemsHA OVR_UNDEFINED +#define PdhExpandWildCardPathHA OVR_UNDEFINED +#define PdhGetDefaultPerfObjectHA OVR_UNDEFINED +#define PdhGetDefaultPerfCounterHA OVR_UNDEFINED +#define PdhBrowseCountersHA OVR_UNDEFINED +#define PdhVerifySQLDBA OVR_UNDEFINED +#define PdhCreateSQLTablesA OVR_UNDEFINED +#define PdhEnumLogSetNamesA OVR_UNDEFINED +#define sndPlaySoundA OVR_UNDEFINED +#define PlaySoundA OVR_UNDEFINED +#define FreeEnvironmentStringsA OVR_UNDEFINED +#define GetCommandLineA OVR_UNDEFINED +#define GetEnvironmentVariableA OVR_UNDEFINED +#define SetEnvironmentVariableA OVR_UNDEFINED +#define ExpandEnvironmentStringsA OVR_UNDEFINED +#define SetCurrentDirectoryA OVR_UNDEFINED +#define GetCurrentDirectoryA OVR_UNDEFINED +#define SearchPathA OVR_UNDEFINED +#define NeedCurrentDirectoryForExePathA OVR_UNDEFINED +#define CreateProcessA OVR_UNDEFINED +#define CreateProcessAsUserA OVR_UNDEFINED +#define CreatePropertySheetPageA OVR_UNDEFINED +#define PropertySheetA OVR_UNDEFINED +#define GetModuleBaseNameA OVR_UNDEFINED +#define GetModuleFileNameExA OVR_UNDEFINED +#define RasDialA OVR_UNDEFINED +#define RasEnumConnectionsA OVR_UNDEFINED +#define RasEnumEntriesA OVR_UNDEFINED +#define RasGetConnectStatusA OVR_UNDEFINED +#define RasGetErrorStringA OVR_UNDEFINED +#define RasHangUpA OVR_UNDEFINED_In_HRASCONN +#define RasGetProjectionInfoA OVR_UNDEFINED +#define RasCreatePhonebookEntryA OVR_UNDEFINED +#define RasEditPhonebookEntryA OVR_UNDEFINED +#define RasSetEntryDialParamsA OVR_UNDEFINED +#define RasGetEntryDialParamsA OVR_UNDEFINED +#define RasEnumDevicesA OVR_UNDEFINED +#define RasGetCountryInfoA OVR_UNDEFINED +#define RasGetEntryPropertiesA OVR_UNDEFINED +#define RasSetEntryPropertiesA OVR_UNDEFINED +#define RasRenameEntryA OVR_UNDEFINED +#define RasDeleteEntryA OVR_UNDEFINED +#define RasValidateEntryNameA OVR_UNDEFINED +#define RasConnectionNotificationA OVR_UNDEFINED +#define RasGetSubEntryHandleA OVR_UNDEFINED +#define RasGetCredentialsA OVR_UNDEFINED +#define RasSetCredentialsA OVR_UNDEFINED +#define RasGetSubEntryPropertiesA OVR_UNDEFINED +#define RasSetSubEntryPropertiesA OVR_UNDEFINED +#define RasGetAutodialAddressA OVR_UNDEFINED +#define RasSetAutodialAddressA OVR_UNDEFINED +#define RasEnumAutodialAddressesA OVR_UNDEFINED +#define RasGetAutodialEnableA OVR_UNDEFINED +#define RasSetAutodialEnableA OVR_UNDEFINED +#define RasGetAutodialParamA OVR_UNDEFINED +#define RasSetAutodialParamA OVR_UNDEFINED +#define RasGetEapUserDataA OVR_UNDEFINED +#define RasSetEapUserDataA OVR_UNDEFINED +#define RasGetCustomAuthDataA OVR_UNDEFINED +#define RasSetCustomAuthDataA OVR_UNDEFINED +#define RasGetEapUserIdentityA OVR_UNDEFINED +#define RasFreeEapUserIdentityA OVR_UNDEFINED +#define RasDeleteSubEntryA OVR_UNDEFINED +#define RasPhonebookDlgA OVR_UNDEFINED +#define RasEntryDlgA OVR_UNDEFINED +#define RasDialDlgA OVR_UNDEFINED +#define get_VisibleInWA OVR_UNDEFINED +#define put_VisibleInWA OVR_UNDEFINED +#define RpcNsBindingExportA OVR_UNDEFINED +#define RpcNsBindingUnexportA OVR_UNDEFINED +#define RpcNsBindingExportPnPA OVR_UNDEFINED +#define RpcNsBindingUnexportPnPA OVR_UNDEFINED +#define RpcNsBindingLookupBeginA OVR_UNDEFINED +#define RpcNsGroupDeleteA OVR_UNDEFINED +#define RpcNsGroupMbrAddA OVR_UNDEFINED +#define RpcNsGroupMbrRemoveA OVR_UNDEFINED +#define RpcNsGroupMbrInqBeginA OVR_UNDEFINED +#define RpcNsGroupMbrInqNextA OVR_UNDEFINED +#define RpcNsProfileDeleteA OVR_UNDEFINED +#define RpcNsProfileEltAddA OVR_UNDEFINED +#define RpcNsProfileEltRemoveA OVR_UNDEFINED +#define RpcNsProfileEltInqBeginA OVR_UNDEFINED +#define RpcNsProfileEltInqNextA OVR_UNDEFINED +#define RpcNsEntryObjectInqBeginA OVR_UNDEFINED +#define RpcNsEntryExpandNameA OVR_UNDEFINED +#define RpcNsMgmtBindingUnexportA OVR_UNDEFINED +#define RpcNsMgmtEntryCreateA OVR_UNDEFINED +#define RpcNsMgmtEntryDeleteA OVR_UNDEFINED +#define RpcNsMgmtEntryInqIfIdsA OVR_UNDEFINED +#define RpcNsBindingImportBeginA OVR_UNDEFINED +#define RpcCertGeneratePrincipalNameA OVR_UNDEFINED +#define TraceRegisterExA OVR_UNDEFINED +#define TraceDeregisterA OVR_UNDEFINED +#define TraceDeregisterExA OVR_UNDEFINED +#define TraceGetConsoleA OVR_UNDEFINED +#define TracePrintfA OVR_UNDEFINED +#define TracePrintfExA OVR_UNDEFINED +#define TraceVprintfExA OVR_UNDEFINED +#define TracePutsExA OVR_UNDEFINED +#define TraceDumpExA OVR_UNDEFINED +#define LogErrorA OVR_UNDEFINED +#define LogEventA OVR_UNDEFINED +#define RouterLogRegisterA OVR_UNDEFINED +#define RouterLogDeregisterA OVR_UNDEFINED +#define RouterLogEventA OVR_UNDEFINED +#define RouterLogEventDataA OVR_UNDEFINED +#define RouterLogEventStringA OVR_UNDEFINED +#define RouterLogEventExA OVR_UNDEFINED +#define RouterLogEventValistExA OVR_UNDEFINED +#define RouterGetErrorStringA OVR_UNDEFINED +#define SslEmptyCacheA OVR_UNDEFINED_In_LPSTRpszTargetName +#define IsDestinationReachableA OVR_UNDEFINED +#define SetupGetInfInformationA OVR_UNDEFINED +#define SetupQueryInfFileInformationA OVR_UNDEFINED +#define SetupQueryInfOriginalFileInformationA OVR_UNDEFINED +#define SetupQueryInfVersionInformationA OVR_UNDEFINED +#define SetupGetInfDriverStoreLocationA OVR_UNDEFINED +#define SetupGetInfPublishedNameA OVR_UNDEFINED +#define SetupGetInfFileListA OVR_UNDEFINED +#define SetupOpenInfFileA OVR_UNDEFINED +#define SetupOpenAppendInfFileA OVR_UNDEFINED +#define SetupFindFirstLineA OVR_UNDEFINED +#define SetupFindNextMatchLineA OVR_UNDEFINED +#define SetupGetLineByIndexA OVR_UNDEFINED +#define SetupGetLineCountA OVR_UNDEFINED +#define SetupGetLineTextA OVR_UNDEFINED +#define SetupGetStringFieldA OVR_UNDEFINED +#define SetupGetMultiSzFieldA OVR_UNDEFINED +#define SetupGetFileCompressionInfoA OVR_UNDEFINED +#define SetupGetFileCompressionInfoExA OVR_UNDEFINED +#define SetupDecompressOrCopyFileA OVR_UNDEFINED +#define SetupGetSourceFileLocationA OVR_UNDEFINED +#define SetupGetSourceFileSizeA OVR_UNDEFINED +#define SetupGetTargetPathA OVR_UNDEFINED +#define SetupSetSourceListA OVR_UNDEFINED +#define SetupAddToSourceListA OVR_UNDEFINED +#define SetupRemoveFromSourceListA OVR_UNDEFINED +#define SetupQuerySourceListA OVR_UNDEFINED +#define SetupFreeSourceListA OVR_UNDEFINED +#define SetupPromptForDiskA OVR_UNDEFINED +#define SetupCopyErrorA OVR_UNDEFINED +#define SetupRenameErrorA OVR_UNDEFINED +#define SetupDeleteErrorA OVR_UNDEFINED +#define SetupBackupErrorA OVR_UNDEFINED +#define SetupSetDirectoryIdA OVR_UNDEFINED +#define SetupSetDirectoryIdExA OVR_UNDEFINED +#define SetupGetSourceInfoA OVR_UNDEFINED +#define SetupInstallFileA OVR_UNDEFINED +#define SetupInstallFileExA OVR_UNDEFINED +#define SetupSetFileQueueAlternatePlatformA OVR_UNDEFINED +#define SetupSetPlatformPathOverrideA OVR_UNDEFINED +#define SetupQueueCopyA OVR_UNDEFINED +#define SetupQueueCopyIndirectA OVR_UNDEFINED +#define SetupQueueDefaultCopyA OVR_UNDEFINED +#define SetupQueueCopySectionA OVR_UNDEFINED +#define SetupQueueDeleteA OVR_UNDEFINED +#define SetupQueueDeleteSectionA OVR_UNDEFINED +#define SetupQueueRenameA OVR_UNDEFINED +#define SetupQueueRenameSectionA OVR_UNDEFINED +#define SetupCommitFileQueueA OVR_UNDEFINED +#define SetupScanFileQueueA OVR_UNDEFINED +#define SetupCopyOEMInfA OVR_UNDEFINED +#define SetupUninstallOEMInfA OVR_UNDEFINED +#define SetupCreateDiskSpaceListA OVR_UNDEFINED +#define SetupDuplicateDiskSpaceListA OVR_UNDEFINED +#define SetupQueryDrivesInDiskSpaceListA OVR_UNDEFINED +#define SetupQuerySpaceRequiredOnDriveA OVR_UNDEFINED +#define SetupAdjustDiskSpaceListA OVR_UNDEFINED +#define SetupAddToDiskSpaceListA OVR_UNDEFINED +#define SetupAddSectionToDiskSpaceListA OVR_UNDEFINED +#define SetupAddInstallSectionToDiskSpaceListA OVR_UNDEFINED +#define SetupRemoveFromDiskSpaceListA OVR_UNDEFINED +#define SetupRemoveSectionFromDiskSpaceListA OVR_UNDEFINED +#define SetupRemoveInstallSectionFromDiskSpaceListA OVR_UNDEFINED +#define SetupIterateCabinetA OVR_UNDEFINED +#define SetupDefaultQueueCallbackA OVR_UNDEFINED +#define SetupInstallFromInfSectionA OVR_UNDEFINED +#define SetupInstallFilesFromInfSectionA OVR_UNDEFINED +#define SetupInstallServicesFromInfSectionA OVR_UNDEFINED +#define SetupInstallServicesFromInfSectionExA OVR_UNDEFINED +#define InstallHinfSectionA OVR_UNDEFINED +#define SetupInitializeFileLogA OVR_UNDEFINED +#define SetupLogFileA OVR_UNDEFINED +#define SetupRemoveFileLogEntryA OVR_UNDEFINED +#define SetupQueryFileLogA OVR_UNDEFINED +#define SetupGetBackupInformationA OVR_UNDEFINED +#define SetupPrepareQueueForRestoreA OVR_UNDEFINED +#define SetupDiCreateDeviceInfoListExA OVR_UNDEFINED +#define SetupDiGetDeviceInfoListDetailA OVR_UNDEFINED +#define SetupDiCreateDeviceInfoA OVR_UNDEFINED +#define SetupDiOpenDeviceInfoA OVR_UNDEFINED +#define SetupDiGetDeviceInstanceIdA OVR_UNDEFINED +#define SetupDiCreateDeviceInterfaceA OVR_UNDEFINED +#define SetupDiOpenDeviceInterfaceA OVR_UNDEFINED +#define SetupDiGetDeviceInterfaceDetailA OVR_UNDEFINED +#define SetupDiEnumDriverInfoA OVR_UNDEFINED +#define SetupDiGetSelectedDriverA OVR_UNDEFINED +#define SetupDiSetSelectedDriverA OVR_UNDEFINED +#define SetupDiGetDriverInfoDetailA OVR_UNDEFINED +#define SetupDiGetClassDevsA OVR_UNDEFINED +#define SetupDiGetClassDevsExA OVR_UNDEFINED +#define SetupDiGetINFClassA OVR_UNDEFINED +#define SetupDiBuildClassInfoListExA OVR_UNDEFINED +#define SetupDiGetClassDescriptionA OVR_UNDEFINED +#define SetupDiGetClassDescriptionExA OVR_UNDEFINED +#define SetupDiInstallClassA OVR_UNDEFINED +#define SetupDiInstallClassExA OVR_UNDEFINED +#define SetupDiOpenClassRegKeyExA OVR_UNDEFINED +#define SetupDiCreateDeviceInterfaceRegKeyA OVR_UNDEFINED +#define SetupDiCreateDevRegKeyA OVR_UNDEFINED +#define SetupDiGetHwProfileListExA OVR_UNDEFINED +#define SetupDiGetDeviceRegistryPropertyA OVR_UNDEFINED +#define SetupDiGetClassRegistryPropertyA OVR_UNDEFINED +#define SetupDiSetDeviceRegistryPropertyA OVR_UNDEFINED +#define SetupDiSetClassRegistryPropertyA OVR_UNDEFINED +#define SetupDiGetDeviceInstallParamsA OVR_UNDEFINED +#define SetupDiGetClassInstallParamsA OVR_UNDEFINED +#define SetupDiSetDeviceInstallParamsA OVR_UNDEFINED +#define SetupDiSetClassInstallParamsA OVR_UNDEFINED +#define SetupDiGetDriverInstallParamsA OVR_UNDEFINED +#define SetupDiSetDriverInstallParamsA OVR_UNDEFINED +#define SetupDiGetClassImageListExA OVR_UNDEFINED +#define SetupDiGetClassDevPropertySheetsA OVR_UNDEFINED +#define SetupDiClassNameFromGuidA OVR_UNDEFINED +#define SetupDiClassNameFromGuidExA OVR_UNDEFINED +#define SetupDiClassGuidsFromNameA OVR_UNDEFINED +#define SetupDiClassGuidsFromNameExA OVR_UNDEFINED +#define SetupDiGetHwProfileFriendlyNameA OVR_UNDEFINED +#define SetupDiGetHwProfileFriendlyNameExA OVR_UNDEFINED +#define SetupDiGetActualModelsSectionA OVR_UNDEFINED +#define SetupDiGetActualSectionToInstallA OVR_UNDEFINED +#define SetupDiGetActualSectionToInstallExA OVR_UNDEFINED +#define SetupVerifyInfFileA OVR_UNDEFINED +#define SetupDiGetCustomDevicePropertyA OVR_UNDEFINED +#define SetupConfigureWmiFromInfSectionA OVR_UNDEFINED +#define DragQueryFileA OVR_UNDEFINED +#define ShellExecuteA OVR_UNDEFINED +#define FindExecutableA OVR_UNDEFINED +#define ShellAboutA OVR_UNDEFINED +#define ExtractAssociatedIconA OVR_UNDEFINED +#define ExtractAssociatedIconExA OVR_UNDEFINED +#define ExtractIconA OVR_UNDEFINED +#define DoEnvironmentSubstA OVR_UNDEFINED +#define ExtractIconExA OVR_UNDEFINED +#define SHFileOperationA OVR_UNDEFINED +#define ShellExecuteExA OVR_UNDEFINED +#define SHSHQueryRecycleBinA OVR_UNDEFINED +#define SHSHEmptyRecycleBinA OVR_UNDEFINED +#define Shell_NotifyIconA OVR_UNDEFINED +#define SHGetFileInfoA OVR_UNDEFINED +#define SHGetDiskFreeSpaceExA OVR_UNDEFINED +#define SHGetNewLinkInfoA OVR_UNDEFINED +#define SHInvokePrinterCommandA OVR_UNDEFINED +#define ShellMessageBoxA OVR_UNDEFINED +#define IsLFNDriveA OVR_UNDEFINED +#define SHEnumerateUnreadMailAccountsA OVR_UNDEFINED +#define SHGetUnreadMailCountA OVR_UNDEFINED +#define SHSetUnreadMailCountA OVR_UNDEFINED +#define SHGetIconOverlayIndexA OVR_UNDEFINED +#define ILCreateFromPathA OVR_UNDEFINED +#define SHGetPathFromIDListA OVR_UNDEFINED +#define SHCreateDirectoryExA OVR_UNDEFINED +#define SHGetSpecialFolderPathA OVR_UNDEFINED +#define SHGetFolderPathA OVR_UNDEFINED +#define SHSetFolderPathA OVR_UNDEFINED +#define SHGetFolderPathAndSubDirA OVR_UNDEFINED +#define SHBrowseForFolderA OVR_UNDEFINED +#define SHUpdateImageA OVR_UNDEFINED +#define SHSHGetDataFromIDListA OVR_UNDEFINED +#define PathIsSlowA OVR_UNDEFINED +#define SHSHStartNetConnectionDialogA OVR_UNDEFINED +#define SHSHDefExtractIconA OVR_UNDEFINED +#define Shell_GetCachedImageIndexA OVR_UNDEFINED +#define SHOpenPropSheetA OVR_UNDEFINED +#define SHSHPathPrepareForWriteA OVR_UNDEFINED +#define SHSHCreateFileExtractIconA OVR_UNDEFINED +#define StrChrA OVR_UNDEFINED +#define StrChrIA OVR_UNDEFINED +#define StrCmpNA OVR_UNDEFINED +#define StrCmpNIA OVR_UNDEFINED +#define StrCSpnA OVR_UNDEFINED +#define StrCSpnIA OVR_UNDEFINED +#define StrDupA OVR_UNDEFINED +#define StrFormatByteSizeA OVR_UNDEFINED +#define StrFormatByteSize64A OVR_UNDEFINED +#define StrFormatKBSizeA OVR_UNDEFINED +#define StrFromTimeIntervalA OVR_UNDEFINED +#define StrIsIntlEqualA OVR_UNDEFINED +#define StrNCatA OVR_UNDEFINED +#define StrPBrkA OVR_UNDEFINED +#define StrRChrA OVR_UNDEFINED +#define StrRChrIA OVR_UNDEFINED +#define StrRStrIA OVR_UNDEFINED +#define StrPBrkA OVR_UNDEFINED +#define StrRChrA OVR_UNDEFINED +#define StrRChrIA OVR_UNDEFINED +#define StrRStrIA OVR_UNDEFINED +#define StrSpnA OVR_UNDEFINED +#define StrStrA OVR_UNDEFINED +#define StrStrIA OVR_UNDEFINED +#define StrStrA OVR_UNDEFINED +#define StrStrIA OVR_UNDEFINED +#define StrToIntA OVR_UNDEFINED +#define StrToIntExA OVR_UNDEFINED +#define StrToInt64ExA OVR_UNDEFINED +#define StrTrimA OVR_UNDEFINED +#define StrCatBuffA OVR_UNDEFINED +#define ChrCmpIA OVR_UNDEFINED +#define wvnsprintfA OVR_UNDEFINED +#define wnsprintfA OVR_UNDEFINED +#define LWStrRetToStrA OVR_UNDEFINED +#define LWStrRetToBufA OVR_UNDEFINED +#define LWSHStrDupA OVR_UNDEFINED +#define SHLocalStrDupA OVR_UNDEFINED +#define IsCharSpaceA OVR_UNDEFINED +#define StrCmpCA OVR_UNDEFINED +#define StrCmpICA OVR_UNDEFINED +#define StrCmpNCA OVR_UNDEFINED +#define StrCmpNICA OVR_UNDEFINED +#define IntlStrEqWorkerA OVR_UNDEFINED +#define PathAddBackslashA OVR_UNDEFINED +#define PathAddExtensionA OVR_UNDEFINED +#define PathAppendA OVR_UNDEFINED +#define PathBuildRootA OVR_UNDEFINED +#define PathCanonicalizeA OVR_UNDEFINED +#define PathCombineA OVR_UNDEFINED +#define PathCompactPathA OVR_UNDEFINED +#define PathCompactPathExA OVR_UNDEFINED +#define PathCommonPrefixA OVR_UNDEFINED +#define PathFileExistsA OVR_UNDEFINED +#define PathFindExtensionA OVR_UNDEFINED +#define PathFindFileNameA OVR_UNDEFINED +#define PathFindNextComponentA OVR_UNDEFINED +#define PathFindExtensionA OVR_UNDEFINED +#define PathFindFileNameA OVR_UNDEFINED +#define PathFindNextComponentA OVR_UNDEFINED +#define PathFindOnPathA OVR_UNDEFINED +#define PathFindSuffixArrayA OVR_UNDEFINED +#define PathGetArgsA OVR_UNDEFINED +#define PathGetArgsA OVR_UNDEFINED +#define PathIsLFNFileSpecA OVR_UNDEFINED +#define PathGetCharTypeA OVR_UNDEFINED +#define PathGetDriveNumberA OVR_UNDEFINED +#define PathIsDirectoryA OVR_UNDEFINED +#define PathIsDirectoryEmptyA OVR_UNDEFINED +#define PathIsFileSpecA OVR_UNDEFINED +#define PathIsPrefixA OVR_UNDEFINED +#define PathIsRelativeA OVR_UNDEFINED +#define PathIsRootA OVR_UNDEFINED +#define PathIsSameRootA OVR_UNDEFINED +#define PathIsUNCA OVR_UNDEFINED +#define PathIsNetworkPathA OVR_UNDEFINED +#define PathIsUNCServerA OVR_UNDEFINED +#define PathIsUNCServerShareA OVR_UNDEFINED +#define PathIsContentTypeA OVR_UNDEFINED +#define PathIsURLA OVR_UNDEFINED +#define PathMakePrettyA OVR_UNDEFINED +#define PathMatchSpecA OVR_UNDEFINED +#define LWPathMatchSpecExA OVR_UNDEFINED +#define PathParseIconLocationA OVR_UNDEFINED +#define PathQuoteSpacesA OVR_UNDEFINED +#define PathRelativePathToA OVR_UNDEFINED +#define PathRemoveArgsA OVR_UNDEFINED +#define PathRemoveBackslashA OVR_UNDEFINED +#define PathRemoveBlanksA OVR_UNDEFINED +#define PathRemoveExtensionA OVR_UNDEFINED +#define PathRemoveFileSpecA OVR_UNDEFINED +#define PathRenameExtensionA OVR_UNDEFINED +#define PathSearchAndQualifyA OVR_UNDEFINED +#define PathSetDlgItemPathA OVR_UNDEFINED +#define PathSkipRootA OVR_UNDEFINED +#define PathSkipRootA OVR_UNDEFINED +#define PathStripPathA OVR_UNDEFINED +#define PathStripToRootA OVR_UNDEFINED +#define PathUnquoteSpacesA OVR_UNDEFINED +#define PathMakeSystemFolderA OVR_UNDEFINED +#define PathUnmakeSystemFolderA OVR_UNDEFINED +#define PathIsSystemFolderA OVR_UNDEFINED +#define PathUndecorateA OVR_UNDEFINED +#define PathUnExpandEnvStringsA OVR_UNDEFINED +#define UrlCompareA OVR_UNDEFINED +#define UrlCombineA OVR_UNDEFINED +#define UrlCanonicalizeA OVR_UNDEFINED +#define UrlIsOpaqueA OVR_UNDEFINED +#define UrlIsNoHistoryA OVR_UNDEFINED +#define UrlIsA OVR_UNDEFINED +#define UrlGetLocationA OVR_UNDEFINED +#define UrlUnescapeA OVR_UNDEFINED +#define UrlEscapeA OVR_UNDEFINED +#define UrlCreateFromPathA OVR_UNDEFINED +#define PathCreateFromUrlA OVR_UNDEFINED +#define UrlHashA OVR_UNDEFINED +#define UrlGetPartA OVR_UNDEFINED +#define UrlApplySchemeA OVR_UNDEFINED +#define ParseURLA OVR_UNDEFINED +#define SHDeleteEmptyKeyA OVR_UNDEFINED +#define SHDeleteKeyA OVR_UNDEFINED +#define SHDeleteValueA OVR_UNDEFINED +#define SHGetValueA OVR_UNDEFINED +#define SHSetValueA OVR_UNDEFINED +#define SHRegGetValueA OVR_UNDEFINED +#define SHQueryValueExA OVR_UNDEFINED +#define SHEnumKeyExA OVR_UNDEFINED +#define SHEnumValueA OVR_UNDEFINED +#define SHQueryInfoKeyA OVR_UNDEFINED +#define SHCopyKeyA OVR_UNDEFINED +#define SHRegGetPathA OVR_UNDEFINED +#define SHRegSetPathA OVR_UNDEFINED +#define SHRegCreateUSKeyA OVR_UNDEFINED +#define SHRegOpenUSKeyA OVR_UNDEFINED +#define SHRegQueryUSValueA OVR_UNDEFINED +#define SHRegWriteUSValueA OVR_UNDEFINED +#define SHRegDeleteUSValueA OVR_UNDEFINED +#define SHRegDeleteEmptyUSKeyA OVR_UNDEFINED +#define SHRegEnumUSKeyA OVR_UNDEFINED +#define SHRegEnumUSValueA OVR_UNDEFINED +#define SHRegQueryInfoUSKeyA OVR_UNDEFINED +#define SHRegGetUSValueA OVR_UNDEFINED +#define SHRegSetUSValueA OVR_UNDEFINED +#define SHRegGetBoolUSValueA OVR_UNDEFINED +#define LWAssocQueryStringA OVR_UNDEFINED +#define LWAssocQueryStringByKeyA OVR_UNDEFINED +#define LWAssocQueryKeyA OVR_UNDEFINED +#define HOpenRegStreamA OVR_UNDEFINED +#define SHOpenRegStream2A OVR_UNDEFINED +#define LWSHCreateStreamOnFileA OVR_UNDEFINED +#define LWGetAcceptLanguagesA OVR_UNDEFINED +#define SHFormatDateTimeA OVR_UNDEFINED +#define SHMessageBoxCheckA OVR_UNDEFINED +#define SHSendMessageBroadcastA OVR_UNDEFINED +#define SHStripMneumonicA OVR_UNDEFINED +#define StrChrA OVR_UNDEFINED +#define StrChrIA OVR_UNDEFINED +#define StrPBrkA OVR_UNDEFINED +#define StrRChrA OVR_UNDEFINED +#define StrRChrIA OVR_UNDEFINED +#define StrRStrIA OVR_UNDEFINED +#define StrStrA OVR_UNDEFINED +#define StrStrIA OVR_UNDEFINED +#define PathFindExtensionA OVR_UNDEFINED +#define PathFindFileNameA OVR_UNDEFINED +#define PathFindNextComponentA OVR_UNDEFINED +#define PathGetArgsA OVR_UNDEFINED +#define PathSkipRootA OVR_UNDEFINED +#define SnmpUtilOidToA OVR_UNDEFINED +#define SnmpUtilIdsToA OVR_UNDEFINED +#define SQLSetConnectAttrForDbcInfoA OVR_UNDEFINED +#define SQLSetDriverConnectInfoA OVR_UNDEFINED +#define SQLPoolConnectA OVR_UNDEFINED +#define SQLColAttributeA OVR_UNDEFINED +#define SQLColAttributeA OVR_UNDEFINED +#define SQLColAttributesA OVR_UNDEFINED +#define SQLConnectA OVR_UNDEFINED +#define SQLDescribeColA OVR_UNDEFINED +#define SQLErrorA OVR_UNDEFINED +#define SQLExecDirectA OVR_UNDEFINED +#define SQLGetConnectAttrA OVR_UNDEFINED +#define SQLGetCursorNameA OVR_UNDEFINED +#define SQLGetDescFieldA OVR_UNDEFINED +#define SQLGetDescRecA OVR_UNDEFINED +#define SQLGetDiagFieldA OVR_UNDEFINED +#define SQLGetDiagRecA OVR_UNDEFINED +#define SQLGetStmtAttrA OVR_UNDEFINED +#define SQLGetTypeInfoA OVR_UNDEFINED +#define SQLPrepareA OVR_UNDEFINED +#define SQLSetConnectAttrA OVR_UNDEFINED +#define SQLSetCursorNameA OVR_UNDEFINED +#define SQLColumnsA OVR_UNDEFINED +#define SQLGetConnectOptionA OVR_UNDEFINED +#define SQLGetInfoA OVR_UNDEFINED +#define SQLGetStmtOptionA OVR_UNDEFINED +#define SQLSetConnectOptionA OVR_UNDEFINED +#define SQLSetStmtOptionA OVR_UNDEFINED +#define SQLSpecialColumnsA OVR_UNDEFINED +#define SQLStatisticsA OVR_UNDEFINED +#define SQLTablesA OVR_UNDEFINED +#define SQLDataSourcesA OVR_UNDEFINED +#define SQLDriverConnectA OVR_UNDEFINED +#define SQLBrowseConnectA OVR_UNDEFINED +#define SQLColumnPrivilegesA OVR_UNDEFINED +#define SQLDescribeParamA OVR_UNDEFINED +#define SQLForeignKeysA OVR_UNDEFINED +#define SQLNativeSqlA OVR_UNDEFINED +#define SQLPrimaryKeysA OVR_UNDEFINED +#define SQLProcedureColumnsA OVR_UNDEFINED +#define SQLProceduresA OVR_UNDEFINED +#define SQLTablePrivilegesA OVR_UNDEFINED +#define SQLDriversA OVR_UNDEFINED +#define SRSetRestorePointA OVR_UNDEFINED +#define AcquireCredentialsHandleA OVR_UNDEFINED +#define AddCredentialsA OVR_UNDEFINED +#define SspiAcquireCredentialsHandleAsyncA OVR_UNDEFINED +#define SspiInitializeSecurityContextAsyncA OVR_UNDEFINED +#define ChangeAccountPasswordA OVR_UNDEFINED +#define InitializeSecurityContextA OVR_UNDEFINED +#define QueryContextAttributesA OVR_UNDEFINED +#define QueryContextAttributesExA OVR_UNDEFINED +#define SetContextAttributesA OVR_UNDEFINED +#define QueryCredentialsAttributesA OVR_UNDEFINED +#define QueryCredentialsAttributesExA OVR_UNDEFINED +#define SetCredentialsAttributesA OVR_UNDEFINED +#define EnumerateSecurityPackagesA OVR_UNDEFINED +#define QuerySecurityPackageInfoA OVR_UNDEFINED +#define ImportSecurityContextA OVR_UNDEFINED +#define InitSecurityInterfaceA OVR_UNDEFINED +#define SaslEnumerateProfilesA OVR_UNDEFINED +#define SaslGetProfilePackageA OVR_UNDEFINED +#define SaslIdentifyPackageA OVR_UNDEFINED +#define SaslInitializeSecurityContextA OVR_UNDEFINED +#define SspiPromptForCredentialsA OVR_UNDEFINED +#define AddSecurityPackageA OVR_UNDEFINED +#define DeleteSecurityPackageA OVR_UNDEFINED +#define CreateMutexA OVR_UNDEFINED +#define CreateEventA OVR_UNDEFINED +#define OpenEventA OVR_UNDEFINED +#define CreateMutexExA OVR_UNDEFINED +#define CreateEventExA OVR_UNDEFINED +#define GetSystemDirectoryA OVR_UNDEFINED +#define GetWindowsDirectoryA OVR_UNDEFINED +#define GetSystemWindowsDirectoryA OVR_UNDEFINED +#define GetComputerNameExA OVR_UNDEFINED +#define GetVersionExA OVR_UNDEFINED +#define SetComputerNameA OVR_UNDEFINED +#define SetComputerNameExA OVR_UNDEFINED +#define lineAddProviderA OVR_UNDEFINED +#define lineBlindTransferA OVR_UNDEFINED +#define lineConfigDialogA OVR_UNDEFINED +#define lineConfigDialogEditA OVR_UNDEFINED +#define lineCreateAgentA OVR_UNDEFINED +#define lineCreateAgentSessionA OVR_UNDEFINED +#define lineDialA OVR_UNDEFINED +#define lineForwardA OVR_UNDEFINED +#define lineGatherDigitsA OVR_UNDEFINED +#define lineGenerateDigitsA OVR_UNDEFINED +#define lineGetAddressCapsA OVR_UNDEFINED +#define lineGetAddressIDA OVR_UNDEFINED +#define lineGetAddressStatusA OVR_UNDEFINED +#define lineGetAgentActivityListA OVR_UNDEFINED +#define lineGetAgentCapsA OVR_UNDEFINED +#define lineGetAgentGroupListA OVR_UNDEFINED +#define lineGetAgentStatusA OVR_UNDEFINED +#define lineGetAppPriorityA OVR_UNDEFINED +#define lineGetCallInfoA OVR_UNDEFINED +#define lineGetCountryA OVR_UNDEFINED +#define lineGetDevCapsA OVR_UNDEFINED +#define lineGetDevConfigA OVR_UNDEFINED +#define lineGetGroupListA OVR_UNDEFINED +#define lineGetIconA OVR_UNDEFINED +#define lineGetIDA OVR_UNDEFINED +#define lineGetLineDevStatusA OVR_UNDEFINED +#define lineGetProviderListA OVR_UNDEFINED +#define lineGetQueueListA OVR_UNDEFINED +#define lineGetRequestA OVR_UNDEFINED +#define lineGetTranslateCapsA OVR_UNDEFINED +#define lineHandoffA OVR_UNDEFINED +#define lineInitializeExA OVR_UNDEFINED +#define lineMakeCallA OVR_UNDEFINED +#define lineOpenA OVR_UNDEFINED +#define lineParkA OVR_UNDEFINED +#define linePickupA OVR_UNDEFINED +#define linePrepareAddToConferenceA OVR_UNDEFINED +#define lineRedirectA OVR_UNDEFINED +#define lineSetAppPriorityA OVR_UNDEFINED +#define lineSetDevConfigA OVR_UNDEFINED +#define lineSetTollListA OVR_UNDEFINED +#define lineSetupConferenceA OVR_UNDEFINED +#define lineSetupTransferA OVR_UNDEFINED +#define lineTranslateAddressA OVR_UNDEFINED +#define lineTranslateDialogA OVR_UNDEFINED +#define lineUnparkA OVR_UNDEFINED +#define phoneConfigDialogA OVR_UNDEFINED +#define phoneGetButtonInfoA OVR_UNDEFINED +#define phoneGetDevCapsA OVR_UNDEFINED +#define phoneGetIconA OVR_UNDEFINED +#define phoneGetIDA OVR_UNDEFINED +#define phoneGetStatusA OVR_UNDEFINED +#define phoneInitializeExA OVR_UNDEFINED +#define phoneSetButtonInfoA OVR_UNDEFINED +#define tapiGetLocationInfoA OVR_UNDEFINED +#define tapiRequestMakeCallA OVR_UNDEFINED +#define tapiRequestMediaCallA OVR_UNDEFINED +#define URLOpenStreamA OVR_UNDEFINED +#define URLOpenPullStreamA OVR_UNDEFINED +#define URLDownloadToFileA OVR_UNDEFINED +#define URLDownloadToCacheFileA OVR_UNDEFINED +#define URLOpenBlockingStreamA OVR_UNDEFINED +#define IsLoggingEnabledA OVR_UNDEFINED +#define LoadUserProfileA OVR_UNDEFINED +#define GetProfilesDirectoryA OVR_UNDEFINED +#define GetDefaultUserProfileDirectoryA OVR_UNDEFINED +#define GetAllUsersProfileDirectoryA OVR_UNDEFINED +#define GetUserProfileDirectoryA OVR_UNDEFINED +#define ExpandEnvironmentStringsForUserA OVR_UNDEFINED +#define AVIStreamOpenFromFileA OVR_UNDEFINED +#define AVISaveVA OVR_UNDEFINED +#define AVIBuildFilterA OVR_UNDEFINED +#define EditStreamSetNameA OVR_UNDEFINED +#define EditStreamSetInfoA OVR_UNDEFINED +#define MCIWndCreateA OVR_UNDEFINED +#define GetOpenFileNamePreviewA OVR_UNDEFINED +#define GetSaveFileNamePreviewA OVR_UNDEFINED +#define ExtMatchPatternA OVR_UNDEFINED +#define GetBinaryTypeA OVR_UNDEFINED +#define GetShortPathNameA OVR_UNDEFINED +#define GetLongPathNameTransactedA OVR_UNDEFINED +#define SetEnvironmentStringsA OVR_UNDEFINED +#define SetFileShortNameA OVR_UNDEFINED +//#define FormatMessageA OVR_UNDEFINED +#define CreateMailslotA OVR_UNDEFINED +#define EncryptFileA OVR_UNDEFINED +#define DecryptFileA OVR_UNDEFINED +#define FileEncryptionStatusA OVR_UNDEFINED +#define OpenEncryptedFileRawA OVR_UNDEFINED +#define lstrcmpA OVR_UNDEFINED +#define lstrcmpiA OVR_UNDEFINED +#define lstrcpynA OVR_UNDEFINED +#define lstrcpyA OVR_UNDEFINED +#define lstrcatA OVR_UNDEFINED +#define lstrlenA OVR_UNDEFINED +#define OpenMutexA OVR_UNDEFINED +#define CreateSemaphoreA OVR_UNDEFINED +#define OpenSemaphoreA OVR_UNDEFINED +#define CreateWaitableTimerA OVR_UNDEFINED +#define OpenWaitableTimerA OVR_UNDEFINED +#define CreateSemaphoreExA OVR_UNDEFINED +#define CreateWaitableTimerExA OVR_UNDEFINED +#define CreateFileMappingA OVR_UNDEFINED +#define CreateFileMappingNumaA OVR_UNDEFINED +#define OpenFileMappingA OVR_UNDEFINED +#define GetLogicalDriveStringsA OVR_UNDEFINED +#define QueryFullProcessImageNameA OVR_UNDEFINED +#define GetStartupInfoA OVR_UNDEFINED +#define GetFirmwareEnvironmentVariableA OVR_UNDEFINED +#define GetFirmwareEnvironmentVariableExA OVR_UNDEFINED +#define SetFirmwareEnvironmentVariableA OVR_UNDEFINED +#define SetFirmwareEnvironmentVariableExA OVR_UNDEFINED +#define FindResourceA OVR_UNDEFINED +#define FindResourceExA OVR_UNDEFINED +#define EnumResourceTypesA OVR_UNDEFINED +#define EnumResourceNamesA OVR_UNDEFINED +#define EnumResourceLanguagesA OVR_UNDEFINED +#define BeginUpdateResourceA OVR_UNDEFINED +#define UpdateResourceA OVR_UNDEFINED +#define EndUpdateResourceA OVR_UNDEFINED +#define GlobalAddAtomA OVR_UNDEFINED +#define GlobalAddAtomExA OVR_UNDEFINED +#define GlobalFindAtomA OVR_UNDEFINED +#define GlobalGetAtomNameA OVR_UNDEFINED +#define AddAtomA OVR_UNDEFINED +#define FindAtomA OVR_UNDEFINED +#define GetAtomNameA OVR_UNDEFINED +#define GetProfileIntA OVR_UNDEFINED +#define GetProfileStringA OVR_UNDEFINED +#define WriteProfileStringA OVR_UNDEFINED +#define GetProfileSectionA OVR_UNDEFINED +#define WriteProfileSectionA OVR_UNDEFINED +#define GetPrivateProfileIntA OVR_UNDEFINED +#define GetPrivateProfileStringA OVR_UNDEFINED +#define WritePrivateProfileStringA OVR_UNDEFINED +#define GetPrivateProfileSectionA OVR_UNDEFINED +#define WritePrivateProfileSectionA OVR_UNDEFINED +#define GetPrivateProfileSectionNamesA OVR_UNDEFINED +#define GetPrivateProfileStructA OVR_UNDEFINED +#define WritePrivateProfileStructA OVR_UNDEFINED +#define SetDllDirectoryA OVR_UNDEFINED +#define GetDllDirectoryA OVR_UNDEFINED +#define CreateDirectoryExA OVR_UNDEFINED +#define CreateDirectoryTransactedA OVR_UNDEFINED +#define RemoveDirectoryTransactedA OVR_UNDEFINED +#define GetFullPathNameTransactedA OVR_UNDEFINED +#define DefineDosDeviceA OVR_UNDEFINED +#define QueryDosDeviceA OVR_UNDEFINED +#define CreateFileTransactedA OVR_UNDEFINED +#define SetFileAttributesTransactedA OVR_UNDEFINED +#define GetFileAttributesTransactedA OVR_UNDEFINED +#define GetCompressedFileSizeTransactedA OVR_UNDEFINED +#define DeleteFileTransactedA OVR_UNDEFINED +#define CheckNameLegalDOS8Dot3A OVR_UNDEFINED +#define FindFirstFileTransactedA OVR_UNDEFINED +#define CopyFileA OVR_UNDEFINED +#define CopyFileExA OVR_UNDEFINED +#define CopyFileTransactedA OVR_UNDEFINED +#define MoveFileA OVR_UNDEFINED +#define MoveFileExA OVR_UNDEFINED +#define MoveFileWithProgressA OVR_UNDEFINED +#define MoveFileTransactedA OVR_UNDEFINED +#define ReplaceFileA OVR_UNDEFINED +#define CreateHardLinkA OVR_UNDEFINED +#define CreateHardLinkTransactedA OVR_UNDEFINED +#define CreateNamedPipeA OVR_UNDEFINED +#define GetNamedPipeHandleStateA OVR_UNDEFINED +#define CallNamedPipeA OVR_UNDEFINED +#define WaitNamedPipeA OVR_UNDEFINED +#define GetNamedPipeClientComputerNameA OVR_UNDEFINED +#define SetVolumeLabelA OVR_UNDEFINED +#define IsBadStringPtrA OVR_UNDEFINED +#define LookupAccountSidA OVR_UNDEFINED +#define LookupAccountNameA OVR_UNDEFINED +#define LookupAccountNameLocalA OVR_UNDEFINED +#define LookupAccountSidLocalA OVR_UNDEFINED +#define LookupPrivilegeValueA OVR_UNDEFINED +#define LookupPrivilegeNameA OVR_UNDEFINED +#define LookupPrivilegeDisplayNameA OVR_UNDEFINED +#define BuildCommDCBA OVR_UNDEFINED +#define BuildCommDCBAndTimeoutsA OVR_UNDEFINED +#define CommConfigDialogA OVR_UNDEFINED +#define GetDefaultCommConfigA OVR_UNDEFINED +#define SetDefaultCommConfigA OVR_UNDEFINED +#define CreatePrivateNamespaceA OVR_UNDEFINED +#define OpenPrivateNamespaceA OVR_UNDEFINED +#define CreateBoundaryDescriptorA OVR_UNDEFINED +#define VerifyVersionInfoA OVR_UNDEFINED +#define CreateJobObjectA OVR_UNDEFINED +#define OpenJobObjectA OVR_UNDEFINED +#define FindFirstVolumeA OVR_UNDEFINED +#define FindNextVolumeA OVR_UNDEFINED +#define FindFirstVolumeMountPointA OVR_UNDEFINED +#define FindNextVolumeMountPointA OVR_UNDEFINED +#define SetVolumeMountPointA OVR_UNDEFINED +#define DeleteVolumeMountPointA OVR_UNDEFINED +#define GetVolumeNameForVolumeMountPointA OVR_UNDEFINED +#define GetVolumePathNameA OVR_UNDEFINED +#define GetVolumePathNamesForVolumeNameA OVR_UNDEFINED +#define CreateActCtxA OVR_UNDEFINED +#define FindActCtxSectionStringA OVR_UNDEFINED +#define WriteConsoleInputA OVR_UNDEFINED +#define ReadConsoleOutputA OVR_UNDEFINED +#define WriteConsoleOutputA OVR_UNDEFINED +#define ReadConsoleOutputCharacterA OVR_UNDEFINED +#define WriteConsoleOutputCharacterA OVR_UNDEFINED +#define FillConsoleOutputCharacterA OVR_UNDEFINED +#define ScrollConsoleScreenBufferA OVR_UNDEFINED +#define GetConsoleTitleA OVR_UNDEFINED +#define GetConsoleOriginalTitleA OVR_UNDEFINED +#define SetConsoleTitleA OVR_UNDEFINED +#define AddConsoleAliasA OVR_UNDEFINED +#define GetConsoleAliasA OVR_UNDEFINED +#define GetConsoleAliasesLengthA OVR_UNDEFINED +#define GetConsoleAliasExesLengthA OVR_UNDEFINED +#define GetConsoleAliasesA OVR_UNDEFINED +#define GetConsoleAliasExesA OVR_UNDEFINED +#define CredMarshalCredentialA OVR_UNDEFINED +#define CredUnmarshalCredentialA OVR_UNDEFINED +#define CredIsMarshaledCredentialA OVR_UNDEFINED +#define CredUnPackAuthenticationBufferA OVR_UNDEFINED +#define CredPackAuthenticationBufferA OVR_UNDEFINED +#define CredProtectA OVR_UNDEFINED +#define CredUnprotectA OVR_UNDEFINED +#define CredIsProtectedA OVR_UNDEFINED +#define CredUIPromptForCredentialsA OVR_UNDEFINED +#define CredUIPromptForWindowsCredentialsA OVR_UNDEFINED +#define CredUIParseUserNameA OVR_UNDEFINED +#define CredUICmdLinePromptForCredentialsA OVR_UNDEFINED +#define CredUIConfirmCredentialsA OVR_UNDEFINED +#define CryptAcquireContextA OVR_UNDEFINED +#define CryptAcquireContextA OVR_UNDEFINED +#define CryptAcquireContextA OVR_UNDEFINED +#define CryptSignHashA OVR_UNDEFINED +#define CryptSignHashA OVR_UNDEFINED +#define CryptSignHashA OVR_UNDEFINED +#define CryptVerifySignatureA OVR_UNDEFINED +#define CryptVerifySignatureA OVR_UNDEFINED +#define CryptVerifySignatureA OVR_UNDEFINED +#define CryptSetProviderA OVR_UNDEFINED +#define CryptSetProviderA OVR_UNDEFINED +#define CryptSetProviderExA OVR_UNDEFINED +#define CryptSetProviderExA OVR_UNDEFINED +#define CryptGetDefaultProviderA OVR_UNDEFINED +#define CryptGetDefaultProviderA OVR_UNDEFINED +#define CryptEnumProviderTypesA OVR_UNDEFINED +#define CryptEnumProviderTypesA OVR_UNDEFINED +#define CryptEnumProviderTypesA OVR_UNDEFINED +#define CryptEnumProvidersA OVR_UNDEFINED +#define CryptEnumProvidersA OVR_UNDEFINED +#define CryptEnumProvidersA OVR_UNDEFINED +#define CertRDNValueToStrA OVR_UNDEFINED +#define CertNameToStrA OVR_UNDEFINED +#define CertStrToNameA OVR_UNDEFINED +#define CertGetNameStringA OVR_UNDEFINED +#define CertOpenSystemStoreA OVR_UNDEFINED +#define CertAddEncodedCertificateToSystemStoreA OVR_UNDEFINED +#define CryptStringToBinaryA OVR_UNDEFINED +#define CryptBinaryToStringA OVR_UNDEFINED +#define DnsQuery_A OVR_UNDEFINED +#define DnsAcquireContextHandle_A OVR_UNDEFINED +#define DnsModifyRecordsInSet_A OVR_UNDEFINED +#define DnsReplaceRecordSetA OVR_UNDEFINED +#define DnsValidateName_A OVR_UNDEFINED +#define DnsNameCompare_A OVR_UNDEFINED +#define FaxConnectFaxServerA OVR_UNDEFINED +#define FaxCompleteJobParamsA OVR_UNDEFINED +#define FaxSendDocumentA OVR_UNDEFINED +#define FaxSendDocumentForBroadcastA OVR_UNDEFINED +#define FaxEnumJobsA OVR_UNDEFINED +#define FaxGetJobA OVR_UNDEFINED +#define FaxSetJobA OVR_UNDEFINED +#define FaxGetDeviceStatusA OVR_UNDEFINED +#define FaxGetConfigurationA OVR_UNDEFINED +#define FaxSetConfigurationA OVR_UNDEFINED +#define FaxGetLoggingCategoriesA OVR_UNDEFINED +#define FaxSetLoggingCategoriesA OVR_UNDEFINED +#define FaxEnumPortsA OVR_UNDEFINED +#define FaxGetPortA OVR_UNDEFINED +#define FaxSetPortA OVR_UNDEFINED +#define FaxEnumRoutingMethodsA OVR_UNDEFINED +#define FaxEnableRoutingMethodA OVR_UNDEFINED +#define FaxEnumGlobalRoutingInfoA OVR_UNDEFINED +#define FaxSetGlobalRoutingInfoA OVR_UNDEFINED +#define FaxGetRoutingInfoA OVR_UNDEFINED +#define FaxSetRoutingInfoA OVR_UNDEFINED +#define FaxStartPrintJobA OVR_UNDEFINED +#define FaxPrintCoverPageA OVR_UNDEFINED +#define FaxUnregisterRoutingExtensionA OVR_UNDEFINED +#define AddFontResourceA OVR_UNDEFINED +#define CopyMetaFileA OVR_UNDEFINED +#define CreateDCA OVR_UNDEFINED +#define CreateFontIndirectA OVR_UNDEFINED +#define CreateFontA OVR_UNDEFINED +#define CreateICA OVR_UNDEFINED +#define CreateMetaFileA OVR_UNDEFINED +#define CreateScalableFontResourceA OVR_UNDEFINED +#define DeviceCapabilitiesA OVR_UNDEFINED +#define EnumFontFamiliesExA OVR_UNDEFINED +#define EnumFontFamiliesA OVR_UNDEFINED +#define EnumFontsA OVR_UNDEFINED +#define GetCharWidthA OVR_UNDEFINED +#define GetCharWidth32A OVR_UNDEFINED +#define GetCharWidthFloatA OVR_UNDEFINED +#define GetCharABCWidthsA OVR_UNDEFINED +#define GetCharABCWidthsFloatA OVR_UNDEFINED +#define GetGlyphOutlineA OVR_UNDEFINED +#define GetMetaFileA OVR_UNDEFINED +#define GetOutlineTextMetricsA OVR_UNDEFINED +#define GetTextExtentPointA OVR_UNDEFINED +#define GetTextExtentPoint32A OVR_UNDEFINED +#define GetTextExtentExPointA OVR_UNDEFINED +#define GetCharacterPlacementA OVR_UNDEFINED_ +#define GetGlyphIndicesA OVR_UNDEFINED +#define AddFontResourceExA OVR_UNDEFINED +#define RemoveFontResourceExA OVR_UNDEFINED +#define CreateFontIndirectExA OVR_UNDEFINED +#define LineDDA OVR_UNDEFINED +#define ResetDCA OVR_UNDEFINED +#define RemoveFontResourceA OVR_UNDEFINED +#define CopyEnhMetaFileA OVR_UNDEFINED +#define CreateEnhMetaFileA OVR_UNDEFINED +#define GetEnhMetaFileA OVR_UNDEFINED +#define GetEnhMetaFileDescriptionA OVR_UNDEFINED +#define GetTextMetricsA OVR_UNDEFINED +#define StartDocA OVR_UNDEFINED +#define GetObjectA OVR_UNDEFINED +#define TextOutA OVR_UNDEFINED +#define ExtTextOutA OVR_UNDEFINED +#define PolyTextOutA OVR_UNDEFINED +#define GetTextFaceA OVR_UNDEFINED +#define GetKerningPairsA OVR_UNDEFINED +#define GetLogColorSpaceA OVR_UNDEFINED +#define CreateColorSpaceA OVR_UNDEFINED +#define GetICMProfileA OVR_UNDEFINED +#define SetICMProfileA OVR_UNDEFINED +#define EnumICMProfilesA OVR_UNDEFINED +#define UpdateICMRegKeyA OVR_UNDEFINED +#define wglUseFontBitmapsA OVR_UNDEFINED +#define wglUseFontOutlinesA OVR_UNDEFINED +#define InternetTimeFromSystemTimeA OVR_UNDEFINED +#define InternetTimeToSystemTimeA OVR_UNDEFINED +#define InternetCrackUrlA OVR_UNDEFINED +#define InternetCreateUrlA OVR_UNDEFINED +#define InternetCanonicalizeUrlA OVR_UNDEFINED +#define InternetCombineUrlA OVR_UNDEFINED +#define InternetOpenA OVR_UNDEFINED +#define InternetConnectA OVR_UNDEFINED +#define InternetOpenUrlA OVR_UNDEFINED +#define InternetReadFileExA OVR_UNDEFINED +#define InternetFindNextFileA OVR_UNDEFINED +#define InternetQueryOptionA OVR_UNDEFINED +#define InternetSetOptionA OVR_UNDEFINED +#define InternetSetOptionExA OVR_UNDEFINED +#define InternetGetLastResponseInfoA OVR_UNDEFINED +#define InternetSetStatusCallbackA OVR_UNDEFINED +#define FtpFindFirstFileA OVR_UNDEFINED +#define FtpGetFileA OVR_UNDEFINED +#define FtpPutFileA OVR_UNDEFINED +#define FtpDeleteFileA OVR_UNDEFINED +#define FtpRenameFileA OVR_UNDEFINED +#define FtpOpenFileA OVR_UNDEFINED +#define FtpCreateDirectoryA OVR_UNDEFINED +#define FtpRemoveDirectoryA OVR_UNDEFINED +#define FtpSetCurrentDirectoryA OVR_UNDEFINED +#define FtpGetCurrentDirectoryA OVR_UNDEFINED +#define FtpCommandA OVR_UNDEFINED +#define GopherCreateLocatorA OVR_UNDEFINED +#define GopherGetLocatorTypeA OVR_UNDEFINED +#define GopherFindFirstFileA OVR_UNDEFINED +#define GopherOpenFileA OVR_UNDEFINED +#define GopherGetAttributeA OVR_UNDEFINED +#define HttpOpenRequestA OVR_UNDEFINED +#define HttpAddRequestHeadersA OVR_UNDEFINED +#define HttpSendRequestA OVR_UNDEFINED +#define HttpSendRequestExA OVR_UNDEFINED +#define HttpEndRequestA OVR_UNDEFINED +#define HttpQueryInfoA OVR_UNDEFINED +#define InternetSetCookieA OVR_UNDEFINED +#define InternetGetCookieA OVR_UNDEFINED +#define InternetSetCookieExA OVR_UNDEFINED +#define InternetGetCookieExA OVR_UNDEFINED +#define InternetCheckConnectionA OVR_UNDEFINED +#define InternetConfirmZoneCrossingA OVR_UNDEFINED +#define CreateUrlCacheEntryA OVR_UNDEFINED +#define CommitUrlCacheEntryA OVR_UNDEFINED +#define RetrieveUrlCacheEntryFileA OVR_UNDEFINED +#define UnlockUrlCacheEntryFileA OVR_UNDEFINED +#define RetrieveUrlCacheEntryStreamA OVR_UNDEFINED +#define GetUrlCacheEntryInfoA OVR_UNDEFINED +#define GetUrlCacheGroupAttributeA OVR_UNDEFINED +#define SetUrlCacheGroupAttributeA OVR_UNDEFINED +#define GetUrlCacheEntryInfoExA OVR_UNDEFINED +#define SetUrlCacheEntryInfoA OVR_UNDEFINED +#define SetUrlCacheEntryGroupA OVR_UNDEFINED +#define FindFirstUrlCacheEntryExA OVR_UNDEFINED +#define FindNextUrlCacheEntryExA OVR_UNDEFINED +#define FindFirstUrlCacheEntryA OVR_UNDEFINED +#define FindNextUrlCacheEntryA OVR_UNDEFINED +#define DeleteUrlCacheEntryA OVR_UNDEFINED +//#define INTERNETAPI_ OVR_UNDEFINED +#define InternetDialA OVR_UNDEFINED +#define InternetGoOnlineA OVR_UNDEFINED +#define InternetGetConnectedStateExA OVR_UNDEFINED +#define InternetSetDialStateA OVR_UNDEFINED +#define InternetSetPerSiteCookieDecisionA OVR_UNDEFINED +#define InternetGetPerSiteCookieDecisionA OVR_UNDEFINED +#define InternetEnumPerSiteCookieDecisionA OVR_UNDEFINED +#define InternetAlgIdToStringA OVR_UNDEFINED +#define InternetSecurityProtocolToStringA OVR_UNDEFINED +#define InternetGetSecurityInfoByURLA OVR_UNDEFINED +#define InternetShowSecurityInfoByURLA OVR_UNDEFINED +#define InternetWriteFileExA OVR_UNDEFINED +#define HttpCheckDavComplianceA OVR_UNDEFINED +#define IsUrlCacheEntryExpiredA OVR_UNDEFINED +#define CreateUrlCacheContainerA OVR_UNDEFINED +#define DeleteUrlCacheContainerA OVR_UNDEFINED +#define FindFirstUrlCacheContainerA OVR_UNDEFINED +#define FindNextUrlCacheContainerA OVR_UNDEFINED +#define FreeUrlCacheSpaceA OVR_UNDEFINED +#define GetUrlCacheConfigInfoA OVR_UNDEFINED +#define SetUrlCacheConfigInfoA OVR_UNDEFINED +#define GetUrlCacheContainerInfoA OVR_UNDEFINED +#define InternetGoOnlineA OVR_UNDEFINED +#define InternetGetConnectedStateExA OVR_UNDEFINED +#define InternetSetDialStateA OVR_UNDEFINED +#define GetDiskInfoA OVR_UNDEFINED +#define PerformOperationOverUrlCacheA OVR_UNDEFINED +#define ImportCookieFileA OVR_UNDEFINED +#define ExportCookieFileA OVR_UNDEFINED +#define IsDomainLegalCookieDomainA OVR_UNDEFINED +#define InternetEnumPerSiteCookieDecisionA OVR_UNDEFINED +#define ldap_openA OVR_UNDEFINED +#define ldap_initA OVR_UNDEFINED +#define ldap_sslinitA OVR_UNDEFINED +#define cldap_openA OVR_UNDEFINED +#define ldap_simple_bindA OVR_UNDEFINED +#define ldap_simple_bind_sA OVR_UNDEFINED +#define ldap_bindA OVR_UNDEFINED +#define ldap_bind_sA OVR_UNDEFINED +#define ldap_sasl_bindA OVR_UNDEFINED +#define ldap_sasl_bind_sA OVR_UNDEFINED +#define ldap_searchA OVR_UNDEFINED +#define ldap_search_sA OVR_UNDEFINED +#define ldap_search_stA OVR_UNDEFINED +#define ldap_search_extA OVR_UNDEFINED +#define ldap_search_ext_sA OVR_UNDEFINED +#define ldap_check_filterA OVR_UNDEFINED +#define ldap_modifyA OVR_UNDEFINED +#define ldap_modify_sA OVR_UNDEFINED +#define ldap_modify_extA OVR_UNDEFINED +#define ldap_modify_ext_sA OVR_UNDEFINED +#define ldap_rename_extA OVR_UNDEFINED +#define ldap_rename_ext_sA OVR_UNDEFINED +#define ldap_addA OVR_UNDEFINED +#define ldap_add_sA OVR_UNDEFINED +#define ldap_add_extA OVR_UNDEFINED +#define ldap_add_ext_sA OVR_UNDEFINED +#define ldap_compareA OVR_UNDEFINED +#define ldap_compare_sA OVR_UNDEFINED +#define ldap_compare_extA OVR_UNDEFINED +#define ldap_compare_ext_sA OVR_UNDEFINED +#define ldap_deleteA OVR_UNDEFINED +#define ldap_delete_sA OVR_UNDEFINED +#define ldap_delete_extA OVR_UNDEFINED +#define ldap_delete_ext_sA OVR_UNDEFINED +#define ldap_err2stringA OVR_UNDEFINEDUerr +#define ldap_first_attributeA OVR_UNDEFINED +#define ldap_next_attributeA OVR_UNDEFINED +#define ldap_get_valuesA OVR_UNDEFINED +#define ldap_count_valuesA OVR_UNDEFINED +#define ldap_value_freeA OVR_UNDEFINED +#define ldap_get_dnA OVR_UNDEFINED +#define ldap_explode_dnA OVR_UNDEFINED +#define ldap_dn2ufnA OVR_UNDEFINED +#define ldap_memfreeA OVR_UNDEFINED +#define ldap_create_page_controlA OVR_UNDEFINED +#define LDAPAPIldap_search_init_pageA OVR_UNDEFINED +#define ldap_extended_operationA OVR_UNDEFINED +#define WNetAddConnectionA OVR_UNDEFINED +#define WNetAddConnection2A OVR_UNDEFINED +#define WNetAddConnection3A OVR_UNDEFINED +#define WNetCancelConnectionA OVR_UNDEFINED +#define WNetCancelConnection2A OVR_UNDEFINED +#define WNetGetConnectionA OVR_UNDEFINED +#define WNetUseConnectionA OVR_UNDEFINED +#define WNetConnectionDialog1A OVR_UNDEFINED +#define WNetDisconnectDialog1A OVR_UNDEFINED +#define WNetOpenEnumA OVR_UNDEFINED +#define WNetEnumResourceA OVR_UNDEFINED +#define WNetGetResourceParentA OVR_UNDEFINED +#define WNetGetResourceInformationA OVR_UNDEFINED +#define WNetGetUniversalNameA OVR_UNDEFINED +#define WNetGetUserA OVR_UNDEFINED +#define WNetGetProviderNameA OVR_UNDEFINED +#define WNetGetNetworkInformationA OVR_UNDEFINED +#define WNetGetLastErrorA OVR_UNDEFINED +#define MultinetGetConnectionPerformanceA OVR_UNDEFINED +#define GetCPInfoExA OVR_UNDEFINED +#define CompareStringA OVR_UNDEFINED +#define LCMapStringA OVR_UNDEFINED +#define GetLocaleInfoA OVR_UNDEFINED +#define SetLocaleInfoA OVR_UNDEFINED +#define GetCalendarInfoA OVR_UNDEFINED +#define SetCalendarInfoA OVR_UNDEFINED +#define GetNumberFormatA OVR_UNDEFINED +#define GetCurrencyFormatA OVR_UNDEFINED +#define EnumCalendarInfoA OVR_UNDEFINED +#define EnumCalendarInfoExA OVR_UNDEFINED +#define EnumTimeFormatsA OVR_UNDEFINED +#define EnumDateFormatsA OVR_UNDEFINED +#define EnumDateFormatsExA OVR_UNDEFINED +#define GetGeoInfoA OVR_UNDEFINED +#define GetStringTypeExA OVR_UNDEFINED +#define GetStringTypeA OVR_UNDEFINED +#define FoldStringA OVR_UNDEFINED +#define EnumSystemLocalesA OVR_UNDEFINED +#define EnumSystemLanguageGroupsA OVR_UNDEFINED +#define EnumLanguageGroupLocalesA OVR_UNDEFINED +#define EnumUILanguagesA OVR_UNDEFINED +#define EnumSystemCodePagesA OVR_UNDEFINED +#define IMPGetIMEA OVR_UNDEFINED +#define IMPQueryIMEA OVR_UNDEFINED +#define IMPSetIMEA OVR_UNDEFINED +#define RegCreateKeyExA OVR_UNDEFINED +#define RegDeleteKeyExA OVR_UNDEFINED +#define RegDeleteValueA OVR_UNDEFINED +#define RegEnumKeyExA OVR_UNDEFINED +#define RegEnumValueA OVR_UNDEFINED +#define RegLoadKeyA OVR_UNDEFINED +#define RegOpenKeyExA OVR_UNDEFINED +#define RegQueryInfoKeyA OVR_UNDEFINED +#define RegQueryValueExA OVR_UNDEFINED +#define RegRestoreKeyA OVR_UNDEFINED +#define RegSetValueExA OVR_UNDEFINED +#define RegUnLoadKeyA OVR_UNDEFINED +#define RegDeleteKeyValueA OVR_UNDEFINED +#define RegSetKeyValueA OVR_UNDEFINED +#define RegDeleteTreeA OVR_UNDEFINED +#define RegGetValueA OVR_UNDEFINED +#define RegLoadMUIStringA OVR_UNDEFINED +#define RegLoadAppKeyA OVR_UNDEFINED +#define InitiateSystemShutdownA OVR_UNDEFINED +#define AbortSystemShutdownA OVR_UNDEFINED +#define InitiateSystemShutdownExA OVR_UNDEFINED +#define InitiateShutdownA OVR_UNDEFINED +#define RegSaveKeyExA OVR_UNDEFINED +#define SCardListReaderGroupsA OVR_UNDEFINED +#define SCardListReadersA OVR_UNDEFINED +#define SCardListCardsA OVR_UNDEFINED +#define SCardListInterfacesA OVR_UNDEFINED +#define SCardGetProviderIdA OVR_UNDEFINED +#define SCardGetCardTypeProviderNameA OVR_UNDEFINED +#define SCardIntroduceReaderGroupA OVR_UNDEFINED +#define SCardForgetReaderGroupA OVR_UNDEFINED +#define SCardIntroduceReaderA OVR_UNDEFINED +#define SCardForgetReaderA OVR_UNDEFINED +#define SCardAddReaderToGroupA OVR_UNDEFINED +#define SCardRemoveReaderFromGroupA OVR_UNDEFINED +#define SCardIntroduceCardTypeA OVR_UNDEFINED +#define SCardSetCardTypeProviderNameA OVR_UNDEFINED +#define SCardForgetCardTypeA OVR_UNDEFINED +#define SCardLocateCardsA OVR_UNDEFINED +#define SCardLocateCardsByATRA OVR_UNDEFINED +#define SCardGetStatusChangeA OVR_UNDEFINED +#define SCardConnectA OVR_UNDEFINED +#define SCardStatusA OVR_UNDEFINED +#define SCardUIDlgSelectCardA OVR_UNDEFINED +#define GetOpenCardNameA OVR_UNDEFINED +#define SCardReadCacheA OVR_UNDEFINED +#define SCardWriteCacheA OVR_UNDEFINED +#define SCardGetReaderIconA OVR_UNDEFINED +#define SCardGetDeviceTypeIdA OVR_UNDEFINED +#define SCardGetReaderDeviceInstanceIdA OVR_UNDEFINED +#define SCardListReadersWithDeviceInstanceIdA OVR_UNDEFINED +#define WSAConnectByNameA OVR_UNDEFINED +#define WSADuplicateSocketA OVR_UNDEFINED +#define WSAEnumProtocolsA OVR_UNDEFINED +#define WSASocketA OVR_UNDEFINED +#define WSAAddressToStringA OVR_UNDEFINED +#define WSAStringToAddressA OVR_UNDEFINED +#define WSALookupServiceBeginA OVR_UNDEFINED +#define WSALookupServiceNextA OVR_UNDEFINED +#define WSAInstallServiceClassA OVR_UNDEFINED +#define WSAGetServiceClassInfoA OVR_UNDEFINED +#define WSAEnumNameSpaceProvidersA OVR_UNDEFINED +#define WSAEnumNameSpaceProvidersExA OVR_UNDEFINED +#define WSAGetServiceClassNameByClassIdA OVR_UNDEFINED +#define WSASetServiceA OVR_UNDEFINED +#define EnumPrintersA OVR_UNDEFINED +#define OpenPrinterA OVR_UNDEFINED +#define ResetPrinterA OVR_UNDEFINED +#define SetJobA OVR_UNDEFINED +#define GetJobA OVR_UNDEFINED +#define EnumJobsA OVR_UNDEFINED +#define AddPrinterA OVR_UNDEFINED +#define SetPrinterA OVR_UNDEFINED +#define GetPrinterA OVR_UNDEFINED +#define AddPrinterDriverA OVR_UNDEFINED +#define AddPrinterDriverExA OVR_UNDEFINED +#define EnumPrinterDriversA OVR_UNDEFINED +#define GetPrinterDriverA OVR_UNDEFINED +#define GetPrinterDriverDirectoryA OVR_UNDEFINED +#define DeletePrinterDriverA OVR_UNDEFINED +#define DeletePrinterDriverExA OVR_UNDEFINED +#define AddPrintProcessorA OVR_UNDEFINED +#define EnumPrintProcessorsA OVR_UNDEFINED +#define GetPrintProcessorDirectoryA OVR_UNDEFINED +#define EnumPrintProcessorDatatypesA OVR_UNDEFINED +#define DeletePrintProcessorA OVR_UNDEFINED +#define StartDocPrinterA OVR_UNDEFINED +#define AddJobA OVR_UNDEFINED +#define DocumentPropertiesA OVR_UNDEFINED +#define AdvancedDocumentPropertiesA OVR_UNDEFINED +#define GetPrinterDataA OVR_UNDEFINED +#define GetPrinterDataExA OVR_UNDEFINED +#define EnumPrinterDataA OVR_UNDEFINED +#define EnumPrinterDataExA OVR_UNDEFINED +#define EnumPrinterKeyA OVR_UNDEFINED +#define SetPrinterDataA OVR_UNDEFINED +#define SetPrinterDataExA OVR_UNDEFINED +#define DeletePrinterDataA OVR_UNDEFINED +#define DeletePrinterDataExA OVR_UNDEFINED +#define DeletePrinterKeyA OVR_UNDEFINED +#define PrinterMessageBoxA OVR_UNDEFINED +#define AddFormA OVR_UNDEFINED +#define DeleteFormA OVR_UNDEFINED +#define GetFormA OVR_UNDEFINED +#define SetFormA OVR_UNDEFINED +#define EnumFormsA OVR_UNDEFINED +#define EnumMonitorsA OVR_UNDEFINED +#define AddMonitorA OVR_UNDEFINED +#define DeleteMonitorA OVR_UNDEFINED +#define EnumPortsA OVR_UNDEFINED +#define AddPortA OVR_UNDEFINED +#define ConfigurePortA OVR_UNDEFINED +#define DeletePortA OVR_UNDEFINED +#define GetDefaultPrinterA OVR_UNDEFINED +#define SetDefaultPrinterA OVR_UNDEFINED +#define SetPortA OVR_UNDEFINED +#define AddPrinterConnectionA OVR_UNDEFINED +#define DeletePrinterConnectionA OVR_UNDEFINED +#define AddPrintProvidorA OVR_UNDEFINED +#define DeletePrintProvidorA OVR_UNDEFINED +#define IsValidDevmodeA OVR_UNDEFINED +#define OpenPrinter2A OVR_UNDEFINED +#define AddPrinterConnection2A OVR_UNDEFINED +#define InstallPrinterDriverFromPackageA OVR_UNDEFINED +#define UploadPrinterDriverPackageA OVR_UNDEFINED +#define GetCorePrinterDriversA OVR_UNDEFINED +#define CorePrinterDriverInstalledA OVR_UNDEFINED +#define GetPrinterDriverPackagePathA OVR_UNDEFINED +#define DeletePrinterDriverPackageA OVR_UNDEFINED +#define GetPrinterDriver2A OVR_UNDEFINED +#define ChangeServiceConfigA OVR_UNDEFINED +#define ChangeServiceConfig2A OVR_UNDEFINED +#define CreateServiceA OVR_UNDEFINED +#define EnumDependentServicesA OVR_UNDEFINED +#define EnumServicesStatusA OVR_UNDEFINED +#define EnumServicesStatusExA OVR_UNDEFINED +#define GetServiceKeyNameA OVR_UNDEFINED +#define GetServiceDisplayNameA OVR_UNDEFINED +#define OpenSCManagerA OVR_UNDEFINED +#define OpenServiceA OVR_UNDEFINED +#define QueryServiceConfigA OVR_UNDEFINED +#define QueryServiceConfig2A OVR_UNDEFINED +#define QueryServiceLockStatusA OVR_UNDEFINED +#define RegisterServiceCtrlHandlerA OVR_UNDEFINED +#define RegisterServiceCtrlHandlerExA OVR_UNDEFINED +#define StartServiceCtrlDispatcherA OVR_UNDEFINED +#define StartServiceA OVR_UNDEFINED +#define ControlServiceExA OVR_UNDEFINED +#define wvsprintfA OVR_UNDEFINED +#define wsprintfA OVR_UNDEFINED +#define LoadKeyboardLayoutA OVR_UNDEFINED +#define GetKeyboardLayoutNameA OVR_UNDEFINED +#define CreateDesktopA OVR_UNDEFINED +#define CreateDesktopExA OVR_UNDEFINED +#define OpenDesktopA OVR_UNDEFINED +#define EnumDesktopsA OVR_UNDEFINED +#define CreateWindowStationA OVR_UNDEFINED +#define OpenWindowStationA OVR_UNDEFINED +#define EnumWindowStationsA OVR_UNDEFINED +#define GetUserObjectInformationA OVR_UNDEFINED +#define SetUserObjectInformationA OVR_UNDEFINED +#define RegisterWindowMessageA OVR_UNDEFINED +#define GetMessageA OVR_UNDEFINED +#define DispatchMessageA OVR_UNDEFINED +#define PeekMessageA OVR_UNDEFINED +#define SendMessageA OVR_UNDEFINED +#define SendMessageTimeoutA OVR_UNDEFINED +#define SendNotifyMessageA OVR_UNDEFINED +#define SendMessageCallbackA OVR_UNDEFINED +#define BroadcastSystemMessageExA OVR_UNDEFINED +#define BroadcastSystemMessageA OVR_UNDEFINED +#define RegisterDeviceNotificationA OVR_UNDEFINED +#define PostMessageA OVR_UNDEFINED +#define PostThreadMessageA OVR_UNDEFINED +#define DefWindowProcA OVR_UNDEFINED +#define CallWindowProcA OVR_UNDEFINED +#define CallWindowProcA OVR_UNDEFINED +#define RegisterClassA OVR_UNDEFINED +#define UnregisterClassA OVR_UNDEFINED +#define GetClassInfoA OVR_UNDEFINED +#define RegisterClassExA OVR_UNDEFINED +#define GetClassInfoExA OVR_UNDEFINED +#define CreateWindowExA OVR_UNDEFINED +#define CreateDialogParamA OVR_UNDEFINED +#define CreateDialogIndirectParamA OVR_UNDEFINED +#define DialogBoxParamA OVR_UNDEFINED +#define DialogBoxIndirectParamA OVR_UNDEFINED +#define SetDlgItemTextA OVR_UNDEFINED +#define GetDlgItemTextA OVR_UNDEFINED +#define SendDlgItemMessageA OVR_UNDEFINED +#define DefDlgProcA OVR_UNDEFINED +#define CallMsgFilterA OVR_UNDEFINED +#define RegisterClipboardFormatA OVR_UNDEFINED +#define GetClipboardFormatNameA OVR_UNDEFINED +#define CharToOemA OVR_UNDEFINED +#define OemToCharA OVR_UNDEFINED +#define CharToOemBuffA OVR_UNDEFINED +#define OemToCharBuffA OVR_UNDEFINED +#define CharUpperA OVR_UNDEFINED +#define CharUpperBuffA OVR_UNDEFINED +#define CharLowerA OVR_UNDEFINED +#define CharLowerBuffA OVR_UNDEFINED +#define CharNextA OVR_UNDEFINED +#define CharPrevA OVR_UNDEFINED +#define CharNextExA OVR_UNDEFINED +#define CharPrevExA OVR_UNDEFINED +#define IsCharAlphaA OVR_UNDEFINED +#define IsCharAlphaNumericA OVR_UNDEFINED +#define IsCharUpperA OVR_UNDEFINED +#define IsCharLowerA OVR_UNDEFINED +#define GetKeyNameTextA OVR_UNDEFINED +#define VkKeyScanA OVR_UNDEFINED +#define VkKeyScanExA OVR_UNDEFINED +#define MapVirtualKeyA OVR_UNDEFINED +#define MapVirtualKeyExA OVR_UNDEFINED +#define LoadAcceleratorsA OVR_UNDEFINED +#define CreateAcceleratorTableA OVR_UNDEFINED +#define CopyAcceleratorTableA OVR_UNDEFINED +#define TranslateAcceleratorA OVR_UNDEFINED +#define LoadMenuA OVR_UNDEFINED +#define LoadMenuIndirectA OVR_UNDEFINED +#define ChangeMenuA OVR_UNDEFINED +#define GetMenuStringA OVR_UNDEFINED +#define InsertMenuA OVR_UNDEFINED +#define AppendMenuA OVR_UNDEFINED +#define ModifyMenuA OVR_UNDEFINED +#define InsertMenuItemA OVR_UNDEFINED +#define GetMenuItemInfoA OVR_UNDEFINED +#define SetMenuItemInfoA OVR_UNDEFINED +#define DrawTextA OVR_UNDEFINED +#define DrawTextExA OVR_UNDEFINED +#define GrayStringA OVR_UNDEFINED +#define DrawStateA OVR_UNDEFINED +#define TabbedTextOutA OVR_UNDEFINED +#define GetTabbedTextExtentA OVR_UNDEFINED +#define SetPropA OVR_UNDEFINED +#define GetPropA OVR_UNDEFINED +#define RemovePropA OVR_UNDEFINED +#define EnumPropsExA OVR_UNDEFINED +#define EnumPropsA OVR_UNDEFINED +#define SetWindowTextA OVR_UNDEFINED +#define GetWindowTextA OVR_UNDEFINED +#define GetWindowTextLengthA OVR_UNDEFINED +#define MessageBoxA OVR_UNDEFINED +#define MessageBoxExA OVR_UNDEFINED +#define MessageBoxIndirectA OVR_UNDEFINED +#define GetWindowLongA OVR_UNDEFINED +#define SetWindowLongA OVR_UNDEFINED +#define GetWindowLongPtrA OVR_UNDEFINED +#define SetWindowLongPtrA OVR_UNDEFINED +#define GetClassLongA OVR_UNDEFINED +#define SetClassLongA OVR_UNDEFINED +#define GetClassLongPtrA OVR_UNDEFINED +#define SetClassLongPtrA OVR_UNDEFINED +#define FindWindowA OVR_UNDEFINED +#define FindWindowExA OVR_UNDEFINED +#define GetClassNameA OVR_UNDEFINED +#define SetWindowsHookA OVR_UNDEFINED +#define SetWindowsHookA OVR_UNDEFINED +#define SetWindowsHookExA OVR_UNDEFINED +#define LoadBitmapA OVR_UNDEFINED +#define LoadCursorA OVR_UNDEFINED +#define LoadCursorFromFileA OVR_UNDEFINED +#define LoadIconA OVR_UNDEFINED +#define PrivateExtractIconsA OVR_UNDEFINED +#define LoadImageA OVR_UNDEFINED +#define GetIconInfoExA OVR_UNDEFINED +#define LoadStringA OVR_UNDEFINED +#define IsDialogMessageA OVR_UNDEFINED +#define DlgDirListA OVR_UNDEFINED +#define DlgDirSelectExA OVR_UNDEFINED +#define DlgDirListComboBoxA OVR_UNDEFINED +#define DlgDirSelectComboBoxExA OVR_UNDEFINED +#define DefFrameProcA OVR_UNDEFINED +#define DefMDIChildProcA OVR_UNDEFINED +#define CreateMDIWindowA OVR_UNDEFINED +#define WinHelpA OVR_UNDEFINED +#define ChangeDisplaySettingsA OVR_UNDEFINED +#define ChangeDisplaySettingsExA OVR_UNDEFINED +#define EnumDisplaySettingsA OVR_UNDEFINED +#define EnumDisplaySettingsExA OVR_UNDEFINED +#define EnumDisplayDevicesA OVR_UNDEFINED +#define SystemParametersInfoA OVR_UNDEFINED +#define GetMonitorInfoA OVR_UNDEFINED +#define GetWindowModuleFileNameA OVR_UNDEFINED +#define RealGetWindowClassA OVR_UNDEFINED +#define GetAltTabInfoA OVR_UNDEFINED +#define GetRawInputDeviceInfoA OVR_UNDEFINED +#define VerFindFileA OVR_UNDEFINED +#define VerInstallFileA OVR_UNDEFINED +#define GetFileVersionInfoSizeA OVR_UNDEFINED +#define GetFileVersionInfoA OVR_UNDEFINED +#define GetFileVersionInfoSizeExA OVR_UNDEFINED +#define GetFileVersionInfoExA OVR_UNDEFINED +#define VerLanguageNameA OVR_UNDEFINED +#define VerQueryValueA OVR_UNDEFINED +#define WmiQueryAllDataA OVR_UNDEFINED +#define WmiQueryAllDataMultipleA OVR_UNDEFINED +#define WmiQuerySingleInstanceA OVR_UNDEFINED +#define WmiQuerySingleInstanceMultipleA OVR_UNDEFINED +#define WmiSetSingleInstanceA OVR_UNDEFINED +#define WmiSetSingleItemA OVR_UNDEFINED +#define WmiExecuteMethodA OVR_UNDEFINED +#define WmiNotificationRegistrationA OVR_UNDEFINED +#define WmiMofEnumerateResourcesA OVR_UNDEFINED +#define WmiFileHandleToInstanceNameA OVR_UNDEFINED +#define WmiDevInstToInstanceNameA OVR_UNDEFINED +#define WmiReceiveNotificationsA OVR_UNDEFINED +#define GetSystemWow64DirectoryA OVR_UNDEFINED +#define GetSystemWow64Directory2A OVR_UNDEFINED +#define GetAddrInfoExA OVR_UNDEFINED +#define SetAddrInfoExA OVR_UNDEFINED +#define gai_strerrorA OVR_UNDEFINED +#define WTSStartRemoteControlSessionA OVR_UNDEFINED +#define WTSConnectSessionA OVR_UNDEFINED +#define WTSEnumerateServersA OVR_UNDEFINED +#define WTSOpenServerA OVR_UNDEFINED +#define WTSOpenServerExA OVR_UNDEFINED +#define WTSEnumerateSessionsA OVR_UNDEFINED +#define WTSEnumerateSessionsExA OVR_UNDEFINED +#define WTSEnumerateProcessesA OVR_UNDEFINED +#define WTSQuerySessionInformationA OVR_UNDEFINED +#define WTSQueryUserConfigA OVR_UNDEFINED +#define WTSSetUserConfigA OVR_UNDEFINED +#define WTSSendMessageA OVR_UNDEFINED +#define WTSFreeMemoryExA OVR_UNDEFINED +#define WTSSetListenerSecurityA OVR_UNDEFINED +#define WTSGetListenerSecurityA OVR_UNDEFINED +#define DtcGetTransactionManagerExA OVR_UNDEFINED +#define WriteConsoleOutputA OVR_UNDEFINED +#define WriteConsoleOutputCharacterA OVR_UNDEFINED +#define FillConsoleOutputCharacterA OVR_UNDEFINED +#define ScrollConsoleScreenBufferA OVR_UNDEFINED +#define WriteConsoleInputA OVR_UNDEFINED +#define ReadConsoleOutputA OVR_UNDEFINED +#define ReadConsoleOutputCharacterA OVR_UNDEFINED +#define CreateHardLinkA OVR_UNDEFINED +#define CreateProcessInternalA OVR_UNDEFINED +#define DosPathToSessionPathA OVR_UNDEFINED + +// Non A/W versions +// This is a copy of the set above but with "A " replace with " ". +// We want to allow only explicit W-using functions, and not the A or default functions. +#define RtlIpv4AddressToStringEx OVR_UNDEFINED +#define RtlIpv6AddressToStringEx OVR_UNDEFINED +#define ConvertInterfaceNameToLuid OVR_UNDEFINED +#define ConvertInterfaceLuidToName OVR_UNDEFINED +#define StrToIntEx OVR_UNDEFINED +#define PathCompactPathEx OVR_UNDEFINED +#define PathCanonicalize OVR_UNDEFINED +#define ConvertSidToStringSid OVR_UNDEFINED +#define ConvertStringSidToSid OVR_UNDEFINED +#define ConvertStringSecurityDescriptorToSecurityDescriptor OVR_UNDEFINED +#define ConvertSecurityDescriptorToStringSecurityDescriptor OVR_UNDEFINED +#define GetUserNameEx OVR_UNDEFINED +#define GetComputerObjectName OVR_UNDEFINED +#define TranslateName OVR_UNDEFINED +#define StrToIntEx OVR_UNDEFINED +#define PathCompactPathEx OVR_UNDEFINED +#define AcquireCredentialsHandle OVR_UNDEFINED +#define AddCredentials OVR_UNDEFINED +#define SspiAcquireCredentialsHandleAsync OVR_UNDEFINED +#define SspiInitializeSecurityContextAsync OVR_UNDEFINED +#define ChangeAccountPassword OVR_UNDEFINED +#define InitializeSecurityContext OVR_UNDEFINED +#define QueryContextAttributes OVR_UNDEFINED +#define QueryContextAttributesEx OVR_UNDEFINED +#define SetContextAttributes OVR_UNDEFINED +#define QueryCredentialsAttributes OVR_UNDEFINED +#define QueryCredentialsAttributesEx OVR_UNDEFINED +#define SetCredentialsAttributes OVR_UNDEFINED +#define EnumerateSecurityPackages OVR_UNDEFINED +#define QuerySecurityPackageInfo OVR_UNDEFINED +#define ImportSecurityContext OVR_UNDEFINED +#define InitSecurityInterface OVR_UNDEFINED +#define SaslEnumerateProfiles OVR_UNDEFINED +#define SaslGetProfilePackage OVR_UNDEFINED +#define SaslIdentifyPackage OVR_UNDEFINED +#define SaslInitializeSecurityContext OVR_UNDEFINED +#define SspiPromptForCredentials OVR_UNDEFINED +#define AddSecurityPackage OVR_UNDEFINED +#define DeleteSecurityPackage OVR_UNDEFINED +#define StringLengthWorker OVR_UNDEFINED +#define StringExValidateSrc OVR_UNDEFINED +#define StringValidateDest OVR_UNDEFINED +#define StringValidateDestAndLength OVR_UNDEFINED +#define StringExValidateDest OVR_UNDEFINED +#define StringExValidateDestAndLength OVR_UNDEFINED +#define StringCopyWorker OVR_UNDEFINED +#define StringVPrintfWorker OVR_UNDEFINED +#define StringVPrintf_lWorker OVR_UNDEFINED +#define StringGetsWorker OVR_UNDEFINED +#define StringExHandleFillBehindNull OVR_UNDEFINED +#define StringExHandleOtherFlags OVR_UNDEFINED +#define StringCchCopy OVR_UNDEFINED +#define StringCbCopy OVR_UNDEFINED +#define StringCchCopyEx OVR_UNDEFINED +#define AddCredentials OVR_UNDEFINED +#define SspiAcquireCredentialsHandleAsync OVR_UNDEFINED +#define SspiInitializeSecurityContextAsync OVR_UNDEFINED +#define ChangeAccountPassword OVR_UNDEFINED +#define RtlStringLengthWorker OVR_UNDEFINED +#define RtlStringExValidateSrc OVR_UNDEFINED +#define RtlStringValidateDest OVR_UNDEFINED +#define RtlStringValidateDestAndLength OVR_UNDEFINED +#define RtlStringExValidateDest OVR_UNDEFINED +#define RtlStringExValidateDestAndLength OVR_UNDEFINED +#define RtlStringCopyWorker OVR_UNDEFINED +#define RtlStringVPrintfWorker OVR_UNDEFINED +#define RtlStringExHandleFillBehindNull OVR_UNDEFINED +#define RtlStringExHandleOtherFlags OVR_UNDEFINED +#define RtlStringCchCopy OVR_UNDEFINED +#define RtlStringCbCopy OVR_UNDEFINED +#define RtlStringCchCopyEx OVR_UNDEFINED +#define RtlStringCbCopyEx OVR_UNDEFINED +#define RtlStringCchCopyN OVR_UNDEFINED +#define RtlStringCbCopyN OVR_UNDEFINED +#define RtlStringCchCopyNEx OVR_UNDEFINED +#define RtlStringCbCopyNEx OVR_UNDEFINED +#define RtlStringCchCat OVR_UNDEFINED +#define RtlStringCbCat OVR_UNDEFINED +#define RtlStringCchCatEx OVR_UNDEFINED +#define RtlStringCbCatEx OVR_UNDEFINED +#define RtlStringCchCatN OVR_UNDEFINED +#define RtlStringCbCatN OVR_UNDEFINED +#define RtlStringCchCatNEx OVR_UNDEFINED +#define RtlStringCbCatNEx OVR_UNDEFINED +#define RtlStringCchVPrintf OVR_UNDEFINED +#define RtlStringCbVPrintf OVR_UNDEFINED +#define RtlStringCchPrintf OVR_UNDEFINED +#define RtlStringCbPrintf OVR_UNDEFINED +#define RtlStringCchPrintfEx OVR_UNDEFINED +#define RtlStringCbPrintfEx OVR_UNDEFINED +#define RtlStringCchVPrintfEx OVR_UNDEFINED +#define RtlStringCbVPrintfEx OVR_UNDEFINED +#define RtlStringCchLength OVR_UNDEFINED +#define RtlStringCbLength OVR_UNDEFINED +#define RtlStringLengthWorker OVR_UNDEFINED +#define RtlStringExValidateSrc OVR_UNDEFINED +#define RtlStringValidateDest OVR_UNDEFINED +#define RtlStringValidateDestAndLength OVR_UNDEFINED +#define RtlStringExValidateDest OVR_UNDEFINED +#define RtlStringExValidateDestAndLength OVR_UNDEFINED +#define RtlStringCopyWorker OVR_UNDEFINED +#define RtlStringVPrintfWorker OVR_UNDEFINED +#define RtlStringExHandleFillBehindNull OVR_UNDEFINED +#define RtlStringExHandleOtherFlags OVR_UNDEFINED +#define RtlIpv4AddressToStringEx OVR_UNDEFINED +#define RtlIpv6AddressToStringEx OVR_UNDEFINED +#define ConvertInterfaceNameToLuid OVR_UNDEFINED +#define ConvertInterfaceLuidToName OVR_UNDEFINED +#define PathCanonicalize OVR_UNDEFINED +#define PathCompactPathEx OVR_UNDEFINED +#define PathCanonicalize OVR_UNDEFINED +#define ConvertSidToStringSid OVR_UNDEFINED +#define ConvertStringSidToSid OVR_UNDEFINED +#define ConvertStringSecurityDescriptorToSecurityDescriptor OVR_UNDEFINED +#define ConvertSecurityDescriptorToStringSecurityDescriptor OVR_UNDEFINED +#define GetUserNameEx OVR_UNDEFINED +#define GetComputerObjectName OVR_UNDEFINED +#define TranslateName OVR_UNDEFINED +#define StrToIntEx OVR_UNDEFINED +#define PathCompactPathEx OVR_UNDEFINED +#define PathCanonicalize OVR_UNDEFINED +#define AcquireCredentialsHandle OVR_UNDEFINED +#define AddCredentials OVR_UNDEFINED +#define SspiAcquireCredentialsHandleAsync OVR_UNDEFINED +#define SspiInitializeSecurityContextAsync OVR_UNDEFINED +#define ChangeAccountPassword OVR_UNDEFINED +#define InitializeSecurityContext OVR_UNDEFINED +#define QueryContextAttributes OVR_UNDEFINED +#define QueryContextAttributesEx OVR_UNDEFINED +#define SetContextAttributes OVR_UNDEFINED +#define QueryCredentialsAttributes OVR_UNDEFINED +#define QueryCredentialsAttributesEx OVR_UNDEFINED +#define SetCredentialsAttributes OVR_UNDEFINED +#define EnumerateSecurityPackages OVR_UNDEFINED +#define QuerySecurityPackageInfo OVR_UNDEFINED +#define ImportSecurityContext OVR_UNDEFINED +#define InitSecurityInterface OVR_UNDEFINED +#define SaslEnumerateProfiles OVR_UNDEFINED +#define SaslGetProfilePackage OVR_UNDEFINED +#define SaslIdentifyPackage OVR_UNDEFINED +#define SaslInitializeSecurityContext OVR_UNDEFINED +#define SspiPromptForCredentials OVR_UNDEFINED +#define AddSecurityPackage OVR_UNDEFINED +#define DeleteSecurityPackage OVR_UNDEFINED +#define StringLengthWorker OVR_UNDEFINED +#define StringExValidateSrc OVR_UNDEFINED +#define StringValidateDest OVR_UNDEFINED +#define StringValidateDestAndLength OVR_UNDEFINED +#define StringExValidateDest OVR_UNDEFINED +#define StringExValidateDestAndLength OVR_UNDEFINED +#define StringCopyWorker OVR_UNDEFINED +#define StringVPrintfWorker OVR_UNDEFINED +#define StringVPrintf_lWorker OVR_UNDEFINED +#define StringGetsWorker OVR_UNDEFINED +#define StringExHandleFillBehindNull OVR_UNDEFINED +#define StringExHandleOtherFlags OVR_UNDEFINED +#define StringCchCopy OVR_UNDEFINED +#define TcOpenInterface OVR_UNDEFINED +#define TcQueryFlow OVR_UNDEFINED +#define TcSetFlow OVR_UNDEFINED +#define TcGetFlowName OVR_UNDEFINED +#define _VCrtDbgReport OVR_UNDEFINED +#define SetEntriesInAcl OVR_UNDEFINED +#define GetExplicitEntriesFromAcl OVR_UNDEFINED +#define GetEffectiveRightsFromAcl OVR_UNDEFINED +#define GetAuditedPermissionsFromAcl OVR_UNDEFINED +#define GetNamedSecurityInfo OVR_UNDEFINED +#define SetNamedSecurityInfo OVR_UNDEFINED +#define GetInheritanceSource OVR_UNDEFINED +#define TreeResetNamedSecurityInfo OVR_UNDEFINED +#define TreeSetNamedSecurityInfo OVR_UNDEFINED +#define BuildSecurityDescriptor OVR_UNDEFINED +#define LookupSecurityDescriptorParts OVR_UNDEFINED +#define BuildExplicitAccessWithName OVR_UNDEFINED +#define BuildImpersonateExplicitAccessWithName OVR_UNDEFINED +#define BuildTrusteeWithName OVR_UNDEFINED +#define BuildImpersonateTrustee OVR_UNDEFINED +#define BuildTrusteeWithSid OVR_UNDEFINED +#define BuildTrusteeWithObjectsAndSid OVR_UNDEFINED +#define BuildTrusteeWithObjectsAndName OVR_UNDEFINED +#define GetTrusteeName OVR_UNDEFINED +#define GetTrusteeType OVR_UNDEFINED +#define GetTrusteeForm OVR_UNDEFINED +#define GetMultipleTrusteeOperation OVR_UNDEFINED +#define GetMultipleTrustee OVR_UNDEFINED +#define RunSetupCommand OVR_UNDEFINED +#define RebootCheckOnInstall OVR_UNDEFINED +#define TranslateInfString OVR_UNDEFINED +#define RegInstall OVR_UNDEFINED +#define LaunchINFSectionEx OVR_UNDEFINED +#define ExecuteCab OVR_UNDEFINED +#define AdvInstallFile OVR_UNDEFINED +#define RegSaveRestore OVR_UNDEFINED +#define RegSaveRestoreOnINF OVR_UNDEFINED +#define RegRestoreAll OVR_UNDEFINED +#define FileSaveRestore OVR_UNDEFINED +#define FileSaveRestoreOnINF OVR_UNDEFINED +#define AddDelBackupEntry OVR_UNDEFINED +#define FileSaveMarkNotExist OVR_UNDEFINED +#define GetVersionFromFile OVR_UNDEFINED +#define GetVersionFromFileEx OVR_UNDEFINED +#define DelNode OVR_UNDEFINED +#define DelNodeRunDLL32 OVR_UNDEFINED +#define OpenINFEngine OVR_UNDEFINED +#define TranslateInfStringEx OVR_UNDEFINED +#define ExtractFiles OVR_UNDEFINED +#define LaunchINFSection OVR_UNDEFINED +#define UserInstStubWrapper OVR_UNDEFINED +#define UserUnInstStubWrapper OVR_UNDEFINED +#define SetPerUserSecValues OVR_UNDEFINED +#define ceGetOIDName OVR_UNDEFINED +#define ceVerifyObjId OVR_UNDEFINED +#define CAEnumFirstC OVR_UNDEFINED +#define CAEnumNextC OVR_UNDEFINED +#define CACreateNewC OVR_UNDEFINED +#define CAUpdateC OVR_UNDEFINED +#define CADeleteC OVR_UNDEFINED +#define CACloseC OVR_UNDEFINED +#define CAEnumCertTypesForC OVR_UNDEFINED +#define CM_Add_ID OVR_UNDEFINED +#define CM_Add_ID_Ex OVR_UNDEFINED +#define CM_Connect_Machine OVR_UNDEFINED +#define CM_Create_DevNode OVR_UNDEFINED +#define CM_Create_DevNode_Ex OVR_UNDEFINED +#define CM_Enumerate_Enumerators OVR_UNDEFINED +#define CM_Enumerate_Enumerators_Ex OVR_UNDEFINED +#define CM_Get_Class_Name OVR_UNDEFINED +#define CM_Get_Class_Name_Ex OVR_UNDEFINED +#define CM_Get_Class_Key_Name OVR_UNDEFINED +#define CM_Get_Class_Key_Name_Ex OVR_UNDEFINED +#define CM_Get_Device_ID OVR_UNDEFINED +#define CM_Get_Device_ID_Ex OVR_UNDEFINED +#define CM_Get_Device_ID_List OVR_UNDEFINED +#define CM_Get_Device_ID_List_Ex OVR_UNDEFINED +#define CM_Get_Device_ID_List_Size OVR_UNDEFINED +#define CM_Get_Device_ID_List_Size_Ex OVR_UNDEFINED +#define CM_Get_DevNode_Registry_Property OVR_UNDEFINED +#define CM_Get_DevNode_Registry_Property_Ex OVR_UNDEFINED +#define CM_Get_DevNode_Custom_Property OVR_UNDEFINED +#define CM_Get_DevNode_Custom_Property_Ex OVR_UNDEFINED +#define CM_Get_Hardware_Profile_Info OVR_UNDEFINED +#define CM_Get_Hardware_Profile_Info_Ex OVR_UNDEFINED +#define CM_Get_HW_Prof_Flags OVR_UNDEFINED +#define CM_Get_HW_Prof_Flags_Ex OVR_UNDEFINED +#define CM_Get_Device_Interface_Alias OVR_UNDEFINED +#define CM_Get_Device_Interface_Alias_Ex OVR_UNDEFINED +#define CM_Get_Device_Interface_List OVR_UNDEFINED +#define CM_Get_Device_Interface_List_Ex OVR_UNDEFINED +#define CM_Get_Device_Interface_List_Size OVR_UNDEFINED +#define CM_Get_Device_Interface_List_Size_Ex OVR_UNDEFINED +#define CM_Locate_DevNode OVR_UNDEFINED +#define CM_Locate_DevNode_Ex OVR_UNDEFINED +#define CM_Open_Class_Key OVR_UNDEFINED +#define CM_Open_Class_Key_Ex OVR_UNDEFINED +#define CM_Open_Device_Interface_Key OVR_UNDEFINED +#define CM_Open_Device_Interface_Key_Ex OVR_UNDEFINED +#define CM_Delete_Device_Interface_Key OVR_UNDEFINED +#define CM_Delete_Device_Interface_Key_Ex OVR_UNDEFINED +#define CM_Query_And_Remove_SubTree OVR_UNDEFINED +#define CM_Query_And_Remove_SubTree_Ex OVR_UNDEFINED +#define CM_Request_Device_Eject OVR_UNDEFINED +#define CM_Request_Device_Eject_Ex OVR_UNDEFINED +#define CM_Register_Device_Interface OVR_UNDEFINED +#define CM_Register_Device_Interface_Ex OVR_UNDEFINED +#define CM_Unregister_Device_Interface OVR_UNDEFINED +#define CM_Unregister_Device_Interface_Ex OVR_UNDEFINED +#define CM_Set_DevNode_Registry_Property OVR_UNDEFINED +#define CM_Set_DevNode_Registry_Property_Ex OVR_UNDEFINED +#define CM_Set_HW_Prof_Flags OVR_UNDEFINED +#define CM_Set_HW_Prof_Flags_Ex OVR_UNDEFINED +#define CM_Get_Resource_Conflict_Details OVR_UNDEFINED +#define CM_Get_Class_Registry_Property OVR_UNDEFINED +#define CM_Set_Class_Registry_Property OVR_UNDEFINED +#define CmWwanPlusAuthAK OVR_UNDEFINED +#define ImageList_LoadImage OVR_UNDEFINED +#define DrawStatusText OVR_UNDEFINED +#define CreateStatusWindow OVR_UNDEFINED +#define GetOpenFileName OVR_UNDEFINED +#define GetSaveFileName OVR_UNDEFINED +#define GetFileTitle OVR_UNDEFINED +#define ChooseColor OVR_UNDEFINED +#define FindText OVR_UNDEFINED +#define ReplaceText OVR_UNDEFINED +#define AfxReplaceText OVR_UNDEFINED +#define ChooseFont OVR_UNDEFINED +#define PrintDlgEx OVR_UNDEFINED +#define PageSetupDlg OVR_UNDEFINED +#define CommonPropertySheetUI OVR_UNDEFINED +#define CommonPropertySheetUI OVR_UNDEFINED +#define PeekConsoleInput OVR_UNDEFINED +#define ReadConsole OVR_UNDEFINED +#define ReadConsoleInput OVR_UNDEFINED +#define WriteConsole OVR_UNDEFINED +#define CertSelectCertificate OVR_UNDEFINED +#define CertViewProperties OVR_UNDEFINED +#define GetFriendlyNameOfCert OVR_UNDEFINED +#define CertConfigureTrust OVR_UNDEFINED +#define CryptUIDlgViewCertificate OVR_UNDEFINED +#define CustomControlInfo OVR_UNDEFINED +#define D3DX10CompileFromFile OVR_UNDEFINED +#define D3DX10CompileFromResource OVR_UNDEFINED +#define D3DX10CreateEffectFromFile OVR_UNDEFINED +#define D3DX10CreateEffectFromResource OVR_UNDEFINED +#define D3DX10CreateEffectPoolFromFile OVR_UNDEFINED +#define D3DX10CreateEffectPoolFromResource OVR_UNDEFINED +#define D3DX10PreprocessShaderFromFile OVR_UNDEFINED +#define D3DX10PreprocessShaderFromResource OVR_UNDEFINED +#define D3DX10CreateAsyncFileLoader OVR_UNDEFINED +#define D3DX10CreateAsyncResourceLoader OVR_UNDEFINED +#define D3DX10CreateFont OVR_UNDEFINED +#define D3DX10CreateFontIndirect OVR_UNDEFINED +#define D3DX10GetImageInfoFromFile OVR_UNDEFINED +#define D3DX10GetImageInfoFromResource OVR_UNDEFINED +#define D3DX10CreateShaderResourceViewFromFile OVR_UNDEFINED +#define D3DX10CreateTextureFromFile OVR_UNDEFINED +#define D3DX10CreateShaderResourceViewFromResource OVR_UNDEFINED +#define D3DX10CreateTextureFromResource OVR_UNDEFINED +#define D3DX10SaveTextureToFile OVR_UNDEFINED +#define D3DXCreateFont OVR_UNDEFINED +#define D3DXCreateFontIndirect OVR_UNDEFINED +#define D3DXCreateEffectFromFile OVR_UNDEFINED +#define D3DXCreateEffectFromResource OVR_UNDEFINED +#define D3DXCreateEffectFromFileEx OVR_UNDEFINED +#define D3DXCreateEffectFromResourceEx OVR_UNDEFINED +#define D3DXCreateEffectCompilerFromFile OVR_UNDEFINED +#define D3DXCreateEffectCompilerFromResource OVR_UNDEFINED +#define D3DXLoadMeshFromX OVR_UNDEFINED +#define D3DXSaveMeshToX OVR_UNDEFINED +#define D3DXLoadPRTBufferFromFile OVR_UNDEFINED +#define D3DXSavePRTBufferToFile OVR_UNDEFINED +#define D3DXLoadPRTCompBufferFromFile OVR_UNDEFINED +#define D3DXSavePRTCompBufferToFile OVR_UNDEFINED +#define D3DXAssembleShaderFromFile OVR_UNDEFINED +#define D3DXAssembleShaderFromResource OVR_UNDEFINED +#define D3DXCompileShaderFromFile OVR_UNDEFINED +#define D3DXCompileShaderFromResource OVR_UNDEFINED +#define D3DXPreprocessShaderFromFile OVR_UNDEFINED +#define D3DXPreprocessShaderFromResource OVR_UNDEFINED +#define D3DXCreateText OVR_UNDEFINED +#define D3DXGetImageInfoFromFile OVR_UNDEFINED +#define D3DXGetImageInfoFromResource OVR_UNDEFINED +#define D3DXLoadSurfaceFromFile OVR_UNDEFINED +#define D3DXLoadSurfaceFromResource OVR_UNDEFINED +#define D3DXSaveSurfaceToFile OVR_UNDEFINED +#define D3DXLoadVolumeFromFile OVR_UNDEFINED +#define D3DXLoadVolumeFromResource OVR_UNDEFINED +#define D3DXSaveVolumeToFile OVR_UNDEFINED +#define D3DXCreateTextureFromFile OVR_UNDEFINED +#define D3DXCreateCubeTextureFromFile OVR_UNDEFINED +#define D3DXCreateVolumeTextureFromFile OVR_UNDEFINED +#define D3DXCreateTextureFromResource OVR_UNDEFINED +#define D3DXCreateCubeTextureFromResource OVR_UNDEFINED +#define D3DXCreateVolumeTextureFromResource OVR_UNDEFINED +#define D3DXCreateTextureFromFileEx OVR_UNDEFINED +#define D3DXCreateCubeTextureFromFileEx OVR_UNDEFINED +#define D3DXCreateVolumeTextureFromFileEx OVR_UNDEFINED +#define D3DXCreateTextureFromResourceEx OVR_UNDEFINED +#define D3DXCreateCubeTextureFromResourceEx OVR_UNDEFINED +#define D3DXCreateVolumeTextureFromResourceEx OVR_UNDEFINED +#define D3DXSaveTextureToFile OVR_UNDEFINED +#define GetDateFormat OVR_UNDEFINED +#define GetTimeFormat OVR_UNDEFINED +#define SymMatchString OVR_UNDEFINED +#define SymAddSourceStream OVR_UNDEFINED +#define DdeInitialize OVR_UNDEFINED +#define DdeCreateStringHandle OVR_UNDEFINED +#define DdeQueryString OVR_UNDEFINED +#define DirectDrawEnumerate OVR_UNDEFINED +#define DirectDrawEnumerateEx OVR_UNDEFINED +//#define OutputDebugString OVR_UNDEFINED +#define DriverPackagePreinstall OVR_UNDEFINED +#define DriverPackageInstall OVR_UNDEFINED +#define DriverPackageUninstall OVR_UNDEFINED +#define DriverPackageGetPath OVR_UNDEFINED +#define SetDifxLogCallback OVR_UNDEFINED +#define DIFXAPISetLogCallback OVR_UNDEFINED +#define ConfigureIME OVR_UNDEFINED +#define EnumRegisterWord OVR_UNDEFINED +#define Escape OVR_UNDEFINED +#define GetCandidateList OVR_UNDEFINED +#define GetCandidateListCount OVR_UNDEFINED +#define GetCompositionFont OVR_UNDEFINED +#define GetCompositionString OVR_UNDEFINED +#define GetConversionList OVR_UNDEFINED +#define GetDescription OVR_UNDEFINED +#define GetGuideLine OVR_UNDEFINED +#define GetIMEFileName OVR_UNDEFINED +#define GetRegisterWordStyle OVR_UNDEFINED +#define InstallIME OVR_UNDEFINED +#define IsUIMessage OVR_UNDEFINED +#define RegisterWord OVR_UNDEFINED +#define SetCompositionFont OVR_UNDEFINED +#define SetCompositionString OVR_UNDEFINED +#define UnregisterWord OVR_UNDEFINED +#define GetCodePage OVR_UNDEFINED +#define GetImeMenuItems OVR_UNDEFINED +#define ConfigureIME OVR_UNDEFINED +#define EnumRegisterWord OVR_UNDEFINED +#define Escape OVR_UNDEFINED +#define GetCandidateList OVR_UNDEFINED +#define GetCandidateListCount OVR_UNDEFINED +#define GetCompositionFont OVR_UNDEFINED +#define GetCompositionString OVR_UNDEFINED +#define GetConversionList OVR_UNDEFINED +#define GetDescription OVR_UNDEFINED +#define GetGuideLine OVR_UNDEFINED +#define GetIMEFileName OVR_UNDEFINED +#define GetRegisterWordStyle OVR_UNDEFINED +#define InstallIME OVR_UNDEFINED +#define IsUIMessage OVR_UNDEFINED +#define RegisterWord OVR_UNDEFINED +#define SetCompositionFont OVR_UNDEFINED +#define SetCompositionString OVR_UNDEFINED +#define UnregisterWord OVR_UNDEFINED +#define GetCodePage OVR_UNDEFINED +#define GetImeMenuItems OVR_UNDEFINED +#define RequestMessage OVR_UNDEFINED +#define SendIMC OVR_UNDEFINED +#define DsBrowseForContainer OVR_UNDEFINED +#define DsGetDcName OVR_UNDEFINED +#define DsGetSiteName OVR_UNDEFINED +#define DsValidateSubnetName OVR_UNDEFINED +#define DsAddressToSiteNames OVR_UNDEFINED +#define DsAddressToSiteNamesEx OVR_UNDEFINED +#define DsGetDcSiteCoverage OVR_UNDEFINED +#define DsGetDcOpen OVR_UNDEFINED +#define DsGetDcNext OVR_UNDEFINED +#define DirectSoundEnumerate OVR_UNDEFINED +#define DirectSoundCaptureEnumerate OVR_UNDEFINED +#define DsMakeSpn OVR_UNDEFINED +#define DsCrackSpn OVR_UNDEFINED +#define DsQuoteRdnValue OVR_UNDEFINED +#define DsUnquoteRdnValue OVR_UNDEFINED +#define DsCrackUnquotedMangledRdn OVR_UNDEFINED +#define DsIsMangledRdnValue OVR_UNDEFINED +#define DsIsMangledDn OVR_UNDEFINED +#define DsCrackSpn2 OVR_UNDEFINED +#define FatalAppExit OVR_UNDEFINED +#define AddERExcludedApplication OVR_UNDEFINED +#define AMGetErrorText OVR_UNDEFINED +#define JetInit3 OVR_UNDEFINED +#define JetCreateInstance OVR_UNDEFINED +#define JetCreateInstance2 OVR_UNDEFINED +#define JetSetSystemParameter OVR_UNDEFINED +#define JetGetSystemParameter OVR_UNDEFINED +#define JetEnableMultiInstance OVR_UNDEFINED +#define JetBeginSession OVR_UNDEFINED +#define JetCreateDatabase OVR_UNDEFINED +#define JetCreateDatabase2 OVR_UNDEFINED +#define JetAttachDatabase OVR_UNDEFINED +#define JetAttachDatabase2 OVR_UNDEFINED +#define JetDetachDatabase OVR_UNDEFINED +#define JetDetachDatabase2 OVR_UNDEFINED +#define JetGetObjectInfo OVR_UNDEFINED +#define JetGetTableInfo OVR_UNDEFINED +#define JetCreateTable OVR_UNDEFINED +#define JetCreateTableColumnIndex OVR_UNDEFINED +#define JetCreateTableColumnIndex2 OVR_UNDEFINED +#define JetCreateTableColumnIndex3 OVR_UNDEFINED +#define JetCreateTableColumnIndex4 OVR_UNDEFINED +#define JetDeleteTable OVR_UNDEFINED +#define JetRenameTable OVR_UNDEFINED +#define JetGetTableColumnInfo OVR_UNDEFINED +#define JetGetColumnInfo OVR_UNDEFINED +#define JetAddColumn OVR_UNDEFINED +#define JetDeleteColumn OVR_UNDEFINED +#define JetDeleteColumn2 OVR_UNDEFINED +#define JetRenameColumn OVR_UNDEFINED +#define JetSetColumnDefaultValue OVR_UNDEFINED +#define JetGetTableIndexInfo OVR_UNDEFINED +#define JetGetIndexInfo OVR_UNDEFINED +#define JetCreateIndex OVR_UNDEFINED +#define JetCreateIndex2 OVR_UNDEFINED +#define JetCreateIndex3 OVR_UNDEFINED +#define JetCreateIndex4 OVR_UNDEFINED +#define JetDeleteIndex OVR_UNDEFINED +#define JetGetDatabaseInfo OVR_UNDEFINED +#define JetGetDatabaseFileInfo OVR_UNDEFINED +#define JetOpenDatabase OVR_UNDEFINED +#define JetOpenTable OVR_UNDEFINED +#define JetGetCurrentIndex OVR_UNDEFINED +#define JetSetCurrentIndex OVR_UNDEFINED +#define JetSetCurrentIndex2 OVR_UNDEFINED +#define JetSetCurrentIndex3 OVR_UNDEFINED +#define JetSetCurrentIndex4 OVR_UNDEFINED +#define JetCompact OVR_UNDEFINED +#define JetDefragment OVR_UNDEFINED +#define JetDefragment2 OVR_UNDEFINED +#define JetDefragment3 OVR_UNDEFINED +#define JetSetDatabaseSize OVR_UNDEFINED +#define JetBackup OVR_UNDEFINED +#define JetBackupInstance OVR_UNDEFINED +#define JetRestore OVR_UNDEFINED +#define JetRestore2 OVR_UNDEFINED +#define JetRestoreInstance OVR_UNDEFINED +#define JetGetAttachInfo OVR_UNDEFINED +#define JetGetAttachInfoInstance OVR_UNDEFINED +#define JetOpenFile OVR_UNDEFINED +#define JetOpenFileInstance OVR_UNDEFINED +#define JetGetLogInfo OVR_UNDEFINED +#define JetGetLogInfoInstance OVR_UNDEFINED +#define JetGetLogInfoInstance2 OVR_UNDEFINED +#define JetGetTruncateLogInfoInstance OVR_UNDEFINED +#define JetExternalRestore OVR_UNDEFINED +#define JetExternalRestore2 OVR_UNDEFINED +#define JetGetInstanceInfo OVR_UNDEFINED +#define JetOSSnapshotFreeze OVR_UNDEFINED +#define JetOSSnapshotGetFreezeInfo OVR_UNDEFINED +#define JetInit3 OVR_UNDEFINED +#define JetInit4 OVR_UNDEFINED +#define JetCreateInstance OVR_UNDEFINED +#define JetCreateInstance2 OVR_UNDEFINED +#define JetSetSystemParameter OVR_UNDEFINED +#define JetGetSystemParameter OVR_UNDEFINED +#define JetEnableMultiInstance OVR_UNDEFINED +#define JetBeginSession OVR_UNDEFINED +#define JetCreateDatabase OVR_UNDEFINED +#define JetCreateDatabase2 OVR_UNDEFINED +#define JetAttachDatabase OVR_UNDEFINED +#define JetAttachDatabase2 OVR_UNDEFINED +#define JetDetachDatabase OVR_UNDEFINED +#define JetDetachDatabase2 OVR_UNDEFINED +#define JetGetObjectInfo OVR_UNDEFINED +#define JetGetTableInfo OVR_UNDEFINED +#define JetSetTableInfo OVR_UNDEFINED +#define JetCreateTable OVR_UNDEFINED +#define JetCreateTableColumnIndex OVR_UNDEFINED +#define JetCreateTableColumnIndex2 OVR_UNDEFINED +#define JetCreateTableColumnIndex3 OVR_UNDEFINED +#define JetCreateTableColumnIndex4 OVR_UNDEFINED +#define JetCreateTableColumnIndex5 OVR_UNDEFINED +#define JetDeleteTable OVR_UNDEFINED +#define JetRenameTable OVR_UNDEFINED +#define JetGetTableColumnInfo OVR_UNDEFINED +#define JetGetColumnInfo OVR_UNDEFINED +#define JetAddColumn OVR_UNDEFINED +#define JetDeleteColumn OVR_UNDEFINED +#define JetDeleteColumn2 OVR_UNDEFINED +#define JetRenameColumn OVR_UNDEFINED +#define JetSetColumnDefaultValue OVR_UNDEFINED +#define JetGetTableIndexInfo OVR_UNDEFINED +#define JetGetIndexInfo OVR_UNDEFINED +#define JetCreateIndex OVR_UNDEFINED +#define JetCreateIndex2 OVR_UNDEFINED +#define JetCreateIndex3 OVR_UNDEFINED +#define JetCreateIndex4 OVR_UNDEFINED +#define JetDeleteIndex OVR_UNDEFINED +#define JetGetDatabaseInfo OVR_UNDEFINED +#define JetGetDatabaseFileInfo OVR_UNDEFINED +#define JetGetLogFileInfo OVR_UNDEFINED +#define JetOpenDatabase OVR_UNDEFINED +#define JetOpenTable OVR_UNDEFINED +#define JetGetCurrentIndex OVR_UNDEFINED +#define JetSetCurrentIndex OVR_UNDEFINED +#define JetSetCurrentIndex2 OVR_UNDEFINED +#define JetSetCurrentIndex3 OVR_UNDEFINED +#define JetSetCurrentIndex4 OVR_UNDEFINED +#define JetCompact OVR_UNDEFINED +#define JetDefragment OVR_UNDEFINED +#define JetDefragment2 OVR_UNDEFINED +#define JetDefragment3 OVR_UNDEFINED +#define JetConvertDDL OVR_UNDEFINED +#define JetUpgradeDatabase OVR_UNDEFINED +#define JetSetDatabaseSize OVR_UNDEFINED +#define JetDBUtilities OVR_UNDEFINED +#define JetBackup OVR_UNDEFINED +#define JetBackupInstance OVR_UNDEFINED +#define JetRestore OVR_UNDEFINED +#define JetRestore2 OVR_UNDEFINED +#define JetRestoreInstance OVR_UNDEFINED +#define JetGetAttachInfo OVR_UNDEFINED +#define JetGetAttachInfoInstance OVR_UNDEFINED +#define JetOpenFile OVR_UNDEFINED +#define JetOpenFileInstance OVR_UNDEFINED +#define JetOpenFileSectionInstance OVR_UNDEFINED +#define JetGetLogInfo OVR_UNDEFINED +#define JetGetLogInfoInstance OVR_UNDEFINED +#define JetGetLogInfoInstance2 OVR_UNDEFINED +#define JetGetTruncateLogInfoInstance OVR_UNDEFINED +#define JetExternalRestore OVR_UNDEFINED +#define JetExternalRestore2 OVR_UNDEFINED +#define JetSnapshotStart OVR_UNDEFINED +#define JetGetInstanceInfo OVR_UNDEFINED +#define JetOSSnapshotFreeze OVR_UNDEFINED +#define JetOSSnapshotGetFreezeInfo OVR_UNDEFINED +#define JetRemoveLogfile OVR_UNDEFINED +#define JetBeginDatabaseIncrementalReseed OVR_UNDEFINED +#define JetEndDatabaseIncrementalReseed OVR_UNDEFINED +#define JetPatchDatabasePages OVR_UNDEFINED +#define CreateDirectory OVR_UNDEFINED +#define CreateFile OVR_UNDEFINED +#define DeleteFile OVR_UNDEFINED +#define FindFirstChangeNotification OVR_UNDEFINED +#define FindFirstFile OVR_UNDEFINED +#define FindFirstFileEx OVR_UNDEFINED +#define FindNextFile OVR_UNDEFINED +#define GetDiskFreeSpace OVR_UNDEFINED +#define GetDiskFreeSpaceEx OVR_UNDEFINED +#define GetDriveType OVR_UNDEFINED +#define GetFileAttributes OVR_UNDEFINED +#define GetFileAttributesEx OVR_UNDEFINED +#define GetFinalPathNameByHandle OVR_UNDEFINED +#define GetFullPathName OVR_UNDEFINED +#define GetLongPathName OVR_UNDEFINED +#define RemoveDirectory OVR_UNDEFINED +#define SetFileAttributes OVR_UNDEFINED +#define GetCompressedFileSize OVR_UNDEFINED +#define GetTempPath OVR_UNDEFINED +#define GetVolumeInformation OVR_UNDEFINED +#define GetTempFileName OVR_UNDEFINED +#define GdipCreateTextureI OVR_UNDEFINED +#define GdipCreateFontFromLogfont OVR_UNDEFINED +#define GdipGetLogFont OVR_UNDEFINED +#define GetLogFont OVR_UNDEFINED +#define GetLogFont OVR_UNDEFINED +#define HtmlHelp OVR_UNDEFINED +#define OpenColorProfile OVR_UNDEFINED +#define CreateProfileFromLogColorSpace OVR_UNDEFINED +#define CreateColorTransform OVR_UNDEFINED +#define RegisterCMM OVR_UNDEFINED +#define UnregisterCMM OVR_UNDEFINED +#define GetColorDirectory OVR_UNDEFINED +#define InstallColorProfile OVR_UNDEFINED +#define UninstallColorProfile OVR_UNDEFINED +#define EnumColorProfiles OVR_UNDEFINED +#define SetStandardColorSpaceProfile OVR_UNDEFINED +#define GetStandardColorSpaceProfile OVR_UNDEFINED +#define AssociateColorProfileWithDevice OVR_UNDEFINED +#define DisassociateColorProfileFromDevice OVR_UNDEFINED +#define SetupColorMatching OVR_UNDEFINED +#define WcsOpenColorProfile OVR_UNDEFINED +#define SymMatchString OVR_UNDEFINED +#define SymAddSourceStream OVR_UNDEFINED +#define SendIMEMessageEx OVR_UNDEFINED +#define ImmInstallIME OVR_UNDEFINED +#define UImmGetDescription OVR_UNDEFINED +#define UImmGetIMEFileName OVR_UNDEFINED +#define ImmGetCompositionString OVR_UNDEFINED +#define ImmSetCompositionString OVR_UNDEFINED +#define ImmGetCandidateListCount OVR_UNDEFINED +#define ImmGetCandidateList OVR_UNDEFINED +#define ImmGetGuideLine OVR_UNDEFINED +#define ImmGetCompositionFont OVR_UNDEFINED +#define ImmSetCompositionFont OVR_UNDEFINED +#define ImmConfigureIME OVR_UNDEFINED +#define ImmEscape OVR_UNDEFINED +#define ImmGetConversionList OVR_UNDEFINED +#define ImmIsUIMessage OVR_UNDEFINED +#define ImmRegisterWord OVR_UNDEFINED +#define ImmUnregisterWord OVR_UNDEFINED +#define UImmGetRegisterWordStyle OVR_UNDEFINED +#define UImmEnumRegisterWord OVR_UNDEFINED +#define ImmGetImeMenuItems OVR_UNDEFINED +#define ImmInstallIME OVR_UNDEFINED +#define UImmGetDescription OVR_UNDEFINED +#define UImmGetIMEFileName OVR_UNDEFINED +#define ImmGetCompositionString OVR_UNDEFINED +#define ImmSetCompositionString OVR_UNDEFINED +#define ImmGetCandidateListCount OVR_UNDEFINED +#define ImmGetCandidateList OVR_UNDEFINED +#define ImmGetGuideLine OVR_UNDEFINED +#define ImmGetCompositionFont OVR_UNDEFINED +#define ImmSetCompositionFont OVR_UNDEFINED +#define ImmConfigureIME OVR_UNDEFINED +#define ImmEscape OVR_UNDEFINED +#define ImmGetConversionList OVR_UNDEFINED +#define ImmIsUIMessage OVR_UNDEFINED +#define ImmRegisterWord OVR_UNDEFINED +#define ImmUnregisterWord OVR_UNDEFINED +#define UImmGetRegisterWordStyle OVR_UNDEFINED +#define UImmEnumRegisterWord OVR_UNDEFINED +#define ImmGetImeMenuItems OVR_UNDEFINED +#define ImmRequestMessage OVR_UNDEFINED +#define INTSHCUTAPITranslateURL OVR_UNDEFINED +#define INTSHCUTAPIURLAssociationDialog OVR_UNDEFINED +#define INTSHCUTAPIMIMEAssociationDialog OVR_UNDEFINED +#define GetIScsiTargetInformation OVR_UNDEFINED +#define AddIScsiConnection OVR_UNDEFINED +#define ReportIScsiTargets OVR_UNDEFINED +#define AddIScsiStaticTarget OVR_UNDEFINED +#define RemoveIScsiStaticTarget OVR_UNDEFINED +#define AddIScsiSendTargetPortal OVR_UNDEFINED +#define RemoveIScsiSendTargetPortal OVR_UNDEFINED +#define RefreshIScsiSendTargetPortal OVR_UNDEFINED +#define ReportIScsiSendTargetPortals OVR_UNDEFINED +#define ReportIScsiSendTargetPortalsEx OVR_UNDEFINED +#define LoginIScsiTarget OVR_UNDEFINED +#define ReportIScsiPersistentLogins OVR_UNDEFINED +#define RemoveIScsiPersistentTarget OVR_UNDEFINED +#define ReportIScsiInitiatorList OVR_UNDEFINED +#define ReportActiveIScsiTargetMappings OVR_UNDEFINED +#define SetIScsiTunnelModeOuterAddress OVR_UNDEFINED +#define SetIScsiIKEInfo OVR_UNDEFINED +#define GetIScsiIKEInfo OVR_UNDEFINED +#define SetIScsiInitiatorNodeName OVR_UNDEFINED +#define GetIScsiInitiatorNodeName OVR_UNDEFINED +#define AddISNSServer OVR_UNDEFINED +#define RemoveISNSServer OVR_UNDEFINED +#define RefreshISNSServer OVR_UNDEFINED +#define ReportISNSServerList OVR_UNDEFINED +#define GetIScsiSessionList OVR_UNDEFINED +#define GetDevicesForIScsiSession OVR_UNDEFINED +#define AddPersistentIScsiDevice OVR_UNDEFINED +#define RemovePersistentIScsiDevice OVR_UNDEFINED +#define ReportPersistentIScsiDevices OVR_UNDEFINED +#define ReportIScsiTargetPortals OVR_UNDEFINED +#define AddRadiusServer OVR_UNDEFINED +#define RemoveRadiusServer OVR_UNDEFINED +#define ReportRadiusServerList OVR_UNDEFINED +#define joyGetDevCaps OVR_UNDEFINED +#define GetModuleFileName OVR_UNDEFINED +#define GetModuleHandle OVR_UNDEFINED +#define GetModuleHandleEx OVR_UNDEFINED +#define LoadLibraryEx OVR_UNDEFINED +#define LoadString OVR_UNDEFINED +#define EnumResourceLanguagesEx OVR_UNDEFINED +#define EnumResourceNamesEx OVR_UNDEFINED +#define EnumResourceTypesEx OVR_UNDEFINED +#define LoadLibrary OVR_UNDEFINED +#define InstallPerfDll OVR_UNDEFINED +#define LoadPerfCounterTextStrings OVR_UNDEFINED +#define UnloadPerfCounterTextStrings OVR_UNDEFINED +#define UpdatePerfNameFiles OVR_UNDEFINED +#define SetServiceAsTrusted OVR_UNDEFINED +#define GetExpandedName OVR_UNDEFINED +#define LZOpenFile OVR_UNDEFINED +#define mciSendCommand OVR_UNDEFINED +#define mciSendString OVR_UNDEFINED +#define mciGetDeviceID OVR_UNDEFINED +#define mciGetDeviceIDFromElementID OVR_UNDEFINED +#define mciGetErrorString OVR_UNDEFINED +#define MFConvertColorInfoToDXV OVR_UNDEFINED +#define MFConvertColorInfoFromDXV OVR_UNDEFINED +#define MI_Instance_Is OVR_UNDEFINED +#define SetStrBuf OVR_UNDEFINED +#define GetStrBuf OVR_UNDEFINED +#define LcidToRfc1766 OVR_UNDEFINED +#define Rfc1766ToLcid OVR_UNDEFINED +#define waveOutGetDevCaps OVR_UNDEFINED +#define waveOutGetErrorText OVR_UNDEFINED +#define waveInGetDevCaps OVR_UNDEFINED +#define waveInGetErrorText OVR_UNDEFINED +#define midiOutGetDevCaps OVR_UNDEFINED +#define midiOutGetErrorText OVR_UNDEFINED +#define midiInGetDevCaps OVR_UNDEFINED +#define midiInGetErrorText OVR_UNDEFINED +#define auxGetDevCaps OVR_UNDEFINED +#define mixerGetDevCaps OVR_UNDEFINED +#define mixerGetLineInfo OVR_UNDEFINED +#define mixerGetLineControls OVR_UNDEFINED +#define mixerGetControlDetails OVR_UNDEFINED +#define mmioStringToFOURCC OVR_UNDEFINED +#define mmioInstallIOProc OVR_UNDEFINED +#define mmioOpen OVR_UNDEFINED +#define mmioRename OVR_UNDEFINED +#define PeekMessage OVR_UNDEFINED +#define GetMessage OVR_UNDEFINED +#define GetDeltaInfo OVR_UNDEFINED +#define ApplyDelta OVR_UNDEFINED +#define CreateDelta OVR_UNDEFINED +#define GetDeltaSignature OVR_UNDEFINED +#define ConfigureIME OVR_UNDEFINED +#define EnumRegisterWord OVR_UNDEFINED +#define Escape OVR_UNDEFINED +#define GetCandidateList OVR_UNDEFINED +#define GetCandidateListCount OVR_UNDEFINED +#define GetCompositionFont OVR_UNDEFINED +#define GetCompositionString OVR_UNDEFINED +#define GetConversionList OVR_UNDEFINED +#define GetDescription OVR_UNDEFINED +#define GetGuideLine OVR_UNDEFINED +#define GetIMEFileName OVR_UNDEFINED +#define GetRegisterWordStyle OVR_UNDEFINED +#define InstallIME OVR_UNDEFINED +#define IsUIMessage OVR_UNDEFINED +#define RegisterWord OVR_UNDEFINED +#define SetCompositionFont OVR_UNDEFINED +#define SetCompositionString OVR_UNDEFINED +#define UnregisterWord OVR_UNDEFINED +#define GetCodePage OVR_UNDEFINED +#define GetImeMenuItems OVR_UNDEFINED +#define ConfigureIME OVR_UNDEFINED +#define EnumRegisterWord OVR_UNDEFINED +#define Escape OVR_UNDEFINED +#define GetCandidateList OVR_UNDEFINED +#define GetCandidateListCount OVR_UNDEFINED +#define GetCompositionFont OVR_UNDEFINED +#define GetCompositionString OVR_UNDEFINED +#define GetConversionList OVR_UNDEFINED +#define GetDescription OVR_UNDEFINED +#define GetGuideLine OVR_UNDEFINED +#define GetIMEFileName OVR_UNDEFINED +#define GetRegisterWordStyle OVR_UNDEFINED +#define InstallIME OVR_UNDEFINED +#define IsUIMessage OVR_UNDEFINED +#define RegisterWord OVR_UNDEFINED +#define SetCompositionFont OVR_UNDEFINED +#define SetCompositionString OVR_UNDEFINED +#define UnregisterWord OVR_UNDEFINED +#define GetCodePage OVR_UNDEFINED +#define GetImeMenuItems OVR_UNDEFINED +#define MsiSetExternalUI OVR_UNDEFINED +#define UMsiEnableLog OVR_UNDEFINED +#define MsiQueryProductState OVR_UNDEFINED +#define UMsiGetProductInfo OVR_UNDEFINED +#define UMsiGetProductInfoEx OVR_UNDEFINED +#define UMsiInstallProduct OVR_UNDEFINED +#define UMsiConfigureProduct OVR_UNDEFINED +#define UMsiConfigureProductEx OVR_UNDEFINED +#define UMsiReinstallProduct OVR_UNDEFINED +#define UMsiAdvertiseProductEx OVR_UNDEFINED +#define UMsiAdvertiseProduct OVR_UNDEFINED +#define UMsiProcessAdvertiseScript OVR_UNDEFINED +#define UMsiAdvertiseScript OVR_UNDEFINED +#define UMsiGetProductInfoFromScript OVR_UNDEFINED +#define UMsiGetProductCode OVR_UNDEFINED +#define USERINFOSTATEMsiGetUserInfo OVR_UNDEFINED +#define UMsiCollectUserInfo OVR_UNDEFINED +#define UMsiApplyPatch OVR_UNDEFINED +#define UMsiGetPatchInfo OVR_UNDEFINED +#define UMsiEnumPatches OVR_UNDEFINED +#define UMsiRemovePatches OVR_UNDEFINED +#define UMsiExtractPatchXMLData OVR_UNDEFINED +#define UMsiGetPatchInfoEx OVR_UNDEFINED +#define UMsiApplyMultiplePatches OVR_UNDEFINED +#define UMsiDeterminePatchSequence OVR_UNDEFINED +#define UMsiDetermineApplicablePatches OVR_UNDEFINED +#define UMsiEnumPatchesEx OVR_UNDEFINED +#define MsiQueryFeatureState OVR_UNDEFINED +#define UMsiQueryFeatureStateEx OVR_UNDEFINED +#define MsiUseFeature OVR_UNDEFINED +#define MsiUseFeatureEx OVR_UNDEFINED +#define UMsiGetFeatureUsage OVR_UNDEFINED +#define UMsiConfigureFeature OVR_UNDEFINED +#define UMsiReinstallFeature OVR_UNDEFINED +#define UMsiProvideComponent OVR_UNDEFINED +#define UMsiProvideQualifiedComponent OVR_UNDEFINED +#define UMsiProvideQualifiedComponentEx OVR_UNDEFINED +#define MsiGetComponentPath OVR_UNDEFINED +#define MsiGetComponentPathEx OVR_UNDEFINED #define #define +#define UMsiProvideAssembly OVR_UNDEFINED +#define UMsiQueryComponentState OVR_UNDEFINED +#define UMsiEnumProducts OVR_UNDEFINED +#define UMsiEnumProductsEx OVR_UNDEFINED +#define UMsiEnumRelatedProducts OVR_UNDEFINED +#define UMsiEnumFeatures OVR_UNDEFINED +#define UMsiEnumComponents OVR_UNDEFINED +#define UMsiEnumComponentsEx OVR_UNDEFINED #define +#define UMsiEnumClients OVR_UNDEFINED +#define UMsiEnumComponentQualifiers OVR_UNDEFINED +#define UMsiOpenProduct OVR_UNDEFINED +#define UMsiOpenPackage OVR_UNDEFINED +#define UMsiOpenPackageEx OVR_UNDEFINED +#define UMsiGetPatchFileList OVR_UNDEFINED +#define UMsiGetProductProperty OVR_UNDEFINED +#define UMsiVerifyPackage OVR_UNDEFINED +#define UMsiGetFeatureInfo OVR_UNDEFINED +#define UMsiInstallMissingComponent OVR_UNDEFINED +#define UMsiInstallMissingFile OVR_UNDEFINED +#define MsiLocateComponent OVR_UNDEFINED +#define UMsiSourceListClearAll OVR_UNDEFINED +#define UMsiSourceListAddSource OVR_UNDEFINED +#define UMsiSourceListForceResolution OVR_UNDEFINED +#define UMsiSourceListAddSourceEx OVR_UNDEFINED +#define UMsiSourceListAddMediaDisk OVR_UNDEFINED +#define UMsiSourceListClearSource OVR_UNDEFINED +#define UMsiSourceListClearMediaDisk OVR_UNDEFINED +#define UMsiSourceListClearAllEx OVR_UNDEFINED +#define UMsiSourceListForceResolutionEx OVR_UNDEFINED +#define UMsiSourceListSetInfo OVR_UNDEFINED +#define UMsiSourceListGetInfo OVR_UNDEFINED +#define UMsiSourceListEnumSources OVR_UNDEFINED +#define UMsiSourceListEnumMediaDisks OVR_UNDEFINED +#define UMsiGetFileVersion OVR_UNDEFINED +#define UMsiGetFileHash OVR_UNDEFINED +#define MsiGetFileSignatureInformation OVR_UNDEFINED +#define UMsiGetShortcutTarget OVR_UNDEFINED +#define UMsiIsProductElevated OVR_UNDEFINED +#define UMsiNotifySidChange OVR_UNDEFINED +#define UMsiBeginTransaction OVR_UNDEFINED +#define UMsiDatabaseOpenView OVR_UNDEFINED +#define MSIDBERRORMsiViewGetError OVR_UNDEFINED +#define UMsiDatabaseGetPrimaryKeys OVR_UNDEFINED +#define MSICONDITIONMsiDatabaseIsTablePersistent OVR_UNDEFINED +#define UMsiGetSummaryInformation OVR_UNDEFINED +#define UMsiSummaryInfoSetProperty OVR_UNDEFINED +#define UMsiSummaryInfoGetProperty OVR_UNDEFINED +#define UMsiOpenDatabase OVR_UNDEFINED +#define UMsiDatabaseImport OVR_UNDEFINED +#define UMsiDatabaseExport OVR_UNDEFINED +#define UMsiDatabaseMerge OVR_UNDEFINED +#define UMsiDatabaseGenerateTransform OVR_UNDEFINED +#define UMsiDatabaseApplyTransform OVR_UNDEFINED +#define UMsiCreateTransformSummaryInfo OVR_UNDEFINED +#define UMsiRecordSetString OVR_UNDEFINED +#define UMsiRecordGetString OVR_UNDEFINED +#define UMsiRecordSetStream OVR_UNDEFINED +#define UMsiSetProperty OVR_UNDEFINED +#define UMsiGetProperty OVR_UNDEFINED +#define UMsiFormatRecord OVR_UNDEFINED +#define UMsiDoAction OVR_UNDEFINED +#define UMsiSequence OVR_UNDEFINED +#define MsiEvaluateCondition OVR_UNDEFINED +#define UMsiGetFeatureState OVR_UNDEFINED +#define UMsiSetFeatureState OVR_UNDEFINED +#define UMsiSetFeatureAttributes OVR_UNDEFINED +#define UMsiGetComponentState OVR_UNDEFINED +#define UMsiSetComponentState OVR_UNDEFINED +#define UMsiGetFeatureCost OVR_UNDEFINED +#define UMsiEnumComponentCosts OVR_UNDEFINED +#define UMsiGetFeatureValidStates OVR_UNDEFINED +#define UMsiGetSourcePath OVR_UNDEFINED +#define UMsiGetTargetPath OVR_UNDEFINED +#define UMsiSetTargetPath OVR_UNDEFINED +#define UMsiPreviewDialog OVR_UNDEFINED +#define UMsiPreviewBillboard OVR_UNDEFINED +#define LoadMUILibrary OVR_UNDEFINED +#define NMRtlIpv6AddressToString OVR_UNDEFINED +#define NMRtlIpv6StringToAddress OVR_UNDEFINED +#define UpdateDriverForPlugAndPlayDevices OVR_UNDEFINED +#define DiInstallDriver OVR_UNDEFINED +#define WNetSetLastError OVR_UNDEFINED +#define DsBind OVR_UNDEFINED +#define DsBindWithCred OVR_UNDEFINED +#define DsBindWithSpn OVR_UNDEFINED +#define DsBindWithSpnEx OVR_UNDEFINED +#define DsBindByInstance OVR_UNDEFINED +#define DsBindToISTG OVR_UNDEFINED +#define DsUnBind OVR_UNDEFINED +#define DsMakePasswordCredentials OVR_UNDEFINED +#define DsCrackNames OVR_UNDEFINED +#define DsFreeNameResult OVR_UNDEFINED +#define DsGetSpn OVR_UNDEFINED +#define DsFreeSpnArray OVR_UNDEFINED +#define DsWriteAccountSpn OVR_UNDEFINED +#define DsClientMakeSpnForTargetServer OVR_UNDEFINED +#define DsServerRegisterSpn OVR_UNDEFINED +#define DsReplicaSync OVR_UNDEFINED +#define DsReplicaAdd OVR_UNDEFINED +#define DsReplicaDel OVR_UNDEFINED +#define DsReplicaModify OVR_UNDEFINED +#define DsReplicaUpdateRefs OVR_UNDEFINED +#define DsRemoveDsServer OVR_UNDEFINED +#define DsRemoveDsDomain OVR_UNDEFINED +#define DsListSites OVR_UNDEFINED +#define DsListServersInSite OVR_UNDEFINED +#define DsListDomainsInSite OVR_UNDEFINED +#define DsListServersForDomainInSite OVR_UNDEFINED +#define DsListInfoForServer OVR_UNDEFINED +#define DsListRoles OVR_UNDEFINED +#define DsQuerySitesByCost OVR_UNDEFINED +#define DsMapSchemaGuids OVR_UNDEFINED +#define DsFreeSchemaGuidMap OVR_UNDEFINED +#define DsGetDomainControllerInfo OVR_UNDEFINED +#define DsFreeDomainControllerInfo OVR_UNDEFINED +#define DsReplicaVerifyObjects OVR_UNDEFINED +#define DsAddSidHistory OVR_UNDEFINED +#define DsInheritSecurityIdentity OVR_UNDEFINED +#define HANDLEOpenNtmsSession OVR_UNDEFINED +#define CreateNtmsMediaPool OVR_UNDEFINED +#define GetNtmsMediaPoolName OVR_UNDEFINED +#define GetNtmsObjectInformation OVR_UNDEFINED +#define SetNtmsObjectInformation OVR_UNDEFINED +#define CreateNtmsMedia OVR_UNDEFINED +#define GetNtmsObjectAttribute OVR_UNDEFINED +#define SetNtmsObjectAttribute OVR_UNDEFINED +#define GetNtmsUIOptions OVR_UNDEFINED +#define SetNtmsUIOptions OVR_UNDEFINED +#define SubmitNtmsOperatorRequest OVR_UNDEFINED +#define EjectDiskFromSADrive OVR_UNDEFINED +#define GetVolumesFromDrive OVR_UNDEFINED +#define LocateCatalogs OVR_UNDEFINED_In_PCSTRpwszScope +#define AuditLookupCategoryName OVR_UNDEFINED +#define AuditLookupSubCategoryName OVR_UNDEFINED +#define AuditSetGlobalSacl OVR_UNDEFINED +#define AuditQueryGlobalSacl OVR_UNDEFINED +#define GetRoleText OVR_UNDEFINED +#define GetStateText OVR_UNDEFINED +#define CreateStdAccessibleProxy OVR_UNDEFINED +#define LHashValOfNameSys OVR_UNDEFINED +#define OleUIAddVerbMenu OVR_UNDEFINED +#define OleUIInsertObject OVR_UNDEFINED +#define OleUIPasteSpecial OVR_UNDEFINED +#define OleUIEditLinks OVR_UNDEFINED +#define OleUIChangeIcon OVR_UNDEFINED +#define OleUIConvert OVR_UNDEFINED +#define OleUIBusy OVR_UNDEFINED +#define OleUIChangeSource OVR_UNDEFINED +#define OleUIObjectProperties OVR_UNDEFINED +#define OleUIPromptUser OVR_UNDEFINED +#define OleUIUpdateLinks OVR_UNDEFINED +#define ConfigureIME OVR_UNDEFINED +#define EnumRegisterWord OVR_UNDEFINED +#define Escape OVR_UNDEFINED +#define GetCandidateList OVR_UNDEFINED +#define GetCandidateListCount OVR_UNDEFINED +#define GetCompositionFont OVR_UNDEFINED +#define GetCompositionString OVR_UNDEFINED +#define GetConversionList OVR_UNDEFINED +#define GetDescription OVR_UNDEFINED +#define GetGuideLine OVR_UNDEFINED +#define GetIMEFileName OVR_UNDEFINED +#define GetRegisterWordStyle OVR_UNDEFINED +#define InstallIME OVR_UNDEFINED +#define IsUIMessage OVR_UNDEFINED +#define RegisterWord OVR_UNDEFINED +#define SetCompositionFont OVR_UNDEFINED +#define SetCompositionString OVR_UNDEFINED +#define UnregisterWord OVR_UNDEFINED +#define GetCodePage OVR_UNDEFINED +#define GetImeMenuItems OVR_UNDEFINED +#define CreatePatchFile OVR_UNDEFINED +#define CreatePatchFileEx OVR_UNDEFINED +#define ExtractPatchHeaderToFile OVR_UNDEFINED +#define TestApplyPatchToFile OVR_UNDEFINED +#define ApplyPatchToFile OVR_UNDEFINED +#define ApplyPatchToFileEx OVR_UNDEFINED +#define GetFilePatchSignature OVR_UNDEFINED +#define UUiCreatePatchPackage OVR_UNDEFINED +#define UUiCreatePatchPackageEx OVR_UNDEFINED +#define PdhOpenQuery OVR_UNDEFINED +#define PdhAddCounter OVR_UNDEFINED +#define PdhAddEnglishCounter OVR_UNDEFINED +#define PdhValidatePathEx OVR_UNDEFINED +#define PdhGetFormattedCounterArray OVR_UNDEFINED +#define PdhGetRawCounterArray OVR_UNDEFINED +#define PdhGetCounterInfo OVR_UNDEFINED +#define PdhConnectMachine OVR_UNDEFINED +#define PdhEnumMachines OVR_UNDEFINED +#define PdhEnumObjects OVR_UNDEFINED +#define PdhEnumObjectItems OVR_UNDEFINED +#define PdhMakeCounterPath OVR_UNDEFINED +#define PdhParseCounterPath OVR_UNDEFINED +#define PdhParseInstanceName OVR_UNDEFINED +#define PdhValidatePath OVR_UNDEFINED +#define PdhGetDefaultPerfObject OVR_UNDEFINED +#define PdhGetDefaultPerfCounter OVR_UNDEFINED +#define PdhBrowseCounters OVR_UNDEFINED +#define PdhExpandCounterPath OVR_UNDEFINED +#define PdhLookupPerfNameByIndex OVR_UNDEFINED +#define PdhLookupPerfIndexByName OVR_UNDEFINED +#define PdhExpandWildCardPath OVR_UNDEFINED +#define PdhOpenLog OVR_UNDEFINED +#define PdhUpdateLog OVR_UNDEFINED +#define PdhSelectDataSource OVR_UNDEFINED +#define PdhGetDataSourceTimeRange OVR_UNDEFINED +#define PdhBindInputDataSource OVR_UNDEFINED +#define PdhEnumMachinesH OVR_UNDEFINED +#define PdhEnumObjectsH OVR_UNDEFINED +#define PdhEnumObjectItemsH OVR_UNDEFINED +#define PdhExpandWildCardPathH OVR_UNDEFINED +#define PdhGetDefaultPerfObjectH OVR_UNDEFINED +#define PdhGetDefaultPerfCounterH OVR_UNDEFINED +#define PdhBrowseCountersH OVR_UNDEFINED +#define PdhVerifySQLDB OVR_UNDEFINED +#define PdhCreateSQLTables OVR_UNDEFINED +#define PdhEnumLogSetNames OVR_UNDEFINED +#define sndPlaySound OVR_UNDEFINED +#define PlaySound OVR_UNDEFINED +#define FreeEnvironmentStrings OVR_UNDEFINED +#define GetCommandLine OVR_UNDEFINED +#define GetEnvironmentVariable OVR_UNDEFINED +#define SetEnvironmentVariable OVR_UNDEFINED +#define ExpandEnvironmentStrings OVR_UNDEFINED +#define SetCurrentDirectory OVR_UNDEFINED +#define GetCurrentDirectory OVR_UNDEFINED +#define SearchPath OVR_UNDEFINED +#define NeedCurrentDirectoryForExePath OVR_UNDEFINED +#define CreateProcess OVR_UNDEFINED +#define CreateProcessAsUser OVR_UNDEFINED +#define CreatePropertySheetPage OVR_UNDEFINED +#define PropertySheet OVR_UNDEFINED +#define GetModuleBaseName OVR_UNDEFINED +#define GetModuleFileNameEx OVR_UNDEFINED +#define RasDial OVR_UNDEFINED +#define RasEnumConnections OVR_UNDEFINED +#define RasEnumEntries OVR_UNDEFINED +#define RasGetConnectStatus OVR_UNDEFINED +#define RasGetErrorString OVR_UNDEFINED +#define RasHangUp OVR_UNDEFINED_In_HRASCONN +#define RasGetProjectionInfo OVR_UNDEFINED +#define RasCreatePhonebookEntry OVR_UNDEFINED +#define RasEditPhonebookEntry OVR_UNDEFINED +#define RasSetEntryDialParams OVR_UNDEFINED +#define RasGetEntryDialParams OVR_UNDEFINED +#define RasEnumDevices OVR_UNDEFINED +#define RasGetCountryInfo OVR_UNDEFINED +#define RasGetEntryProperties OVR_UNDEFINED +#define RasSetEntryProperties OVR_UNDEFINED +#define RasRenameEntry OVR_UNDEFINED +#define RasDeleteEntry OVR_UNDEFINED +#define RasValidateEntryName OVR_UNDEFINED +#define RasConnectionNotification OVR_UNDEFINED +#define RasGetSubEntryHandle OVR_UNDEFINED +#define RasGetCredentials OVR_UNDEFINED +#define RasSetCredentials OVR_UNDEFINED +#define RasGetSubEntryProperties OVR_UNDEFINED +#define RasSetSubEntryProperties OVR_UNDEFINED +#define RasGetAutodialAddress OVR_UNDEFINED +#define RasSetAutodialAddress OVR_UNDEFINED +#define RasEnumAutodialAddresses OVR_UNDEFINED +#define RasGetAutodialEnable OVR_UNDEFINED +#define RasSetAutodialEnable OVR_UNDEFINED +#define RasGetAutodialParam OVR_UNDEFINED +#define RasSetAutodialParam OVR_UNDEFINED +#define RasGetEapUserData OVR_UNDEFINED +#define RasSetEapUserData OVR_UNDEFINED +#define RasGetCustomAuthData OVR_UNDEFINED +#define RasSetCustomAuthData OVR_UNDEFINED +#define RasGetEapUserIdentity OVR_UNDEFINED +#define RasFreeEapUserIdentity OVR_UNDEFINED +#define RasDeleteSubEntry OVR_UNDEFINED +#define RasPhonebookDlg OVR_UNDEFINED +#define RasEntryDlg OVR_UNDEFINED +#define RasDialDlg OVR_UNDEFINED +#define get_VisibleInW OVR_UNDEFINED +#define put_VisibleInW OVR_UNDEFINED +#define RpcNsBindingExport OVR_UNDEFINED +#define RpcNsBindingUnexport OVR_UNDEFINED +#define RpcNsBindingExportPnP OVR_UNDEFINED +#define RpcNsBindingUnexportPnP OVR_UNDEFINED +#define RpcNsBindingLookupBegin OVR_UNDEFINED +#define RpcNsGroupDelete OVR_UNDEFINED +#define RpcNsGroupMbrAdd OVR_UNDEFINED +#define RpcNsGroupMbrRemove OVR_UNDEFINED +#define RpcNsGroupMbrInqBegin OVR_UNDEFINED +#define RpcNsGroupMbrInqNext OVR_UNDEFINED +#define RpcNsProfileDelete OVR_UNDEFINED +#define RpcNsProfileEltAdd OVR_UNDEFINED +#define RpcNsProfileEltRemove OVR_UNDEFINED +#define RpcNsProfileEltInqBegin OVR_UNDEFINED +#define RpcNsProfileEltInqNext OVR_UNDEFINED +#define RpcNsEntryObjectInqBegin OVR_UNDEFINED +#define RpcNsEntryExpandName OVR_UNDEFINED +#define RpcNsMgmtBindingUnexport OVR_UNDEFINED +#define RpcNsMgmtEntryCreate OVR_UNDEFINED +#define RpcNsMgmtEntryDelete OVR_UNDEFINED +#define RpcNsMgmtEntryInqIfIds OVR_UNDEFINED +#define RpcNsBindingImportBegin OVR_UNDEFINED +#define RpcCertGeneratePrincipalName OVR_UNDEFINED +#define TraceRegisterEx OVR_UNDEFINED +#define TraceDeregister OVR_UNDEFINED +#define TraceDeregisterEx OVR_UNDEFINED +#define TraceGetConsole OVR_UNDEFINED +#define TracePrintf OVR_UNDEFINED +#define TracePrintfEx OVR_UNDEFINED +#define TraceVprintfEx OVR_UNDEFINED +#define TracePutsEx OVR_UNDEFINED +#define TraceDumpEx OVR_UNDEFINED +#define LogError OVR_UNDEFINED +#define LogEvent OVR_UNDEFINED +#define RouterLogRegister OVR_UNDEFINED +#define RouterLogDeregister OVR_UNDEFINED +#define RouterLogEvent OVR_UNDEFINED +#define RouterLogEventData OVR_UNDEFINED +#define RouterLogEventString OVR_UNDEFINED +#define RouterLogEventEx OVR_UNDEFINED +#define RouterLogEventValistEx OVR_UNDEFINED +#define RouterGetErrorString OVR_UNDEFINED +#define SslEmptyCache OVR_UNDEFINED_In_LPSTRpszTargetName +#define IsDestinationReachable OVR_UNDEFINED +#define SetupGetInfInformation OVR_UNDEFINED +#define SetupQueryInfFileInformation OVR_UNDEFINED +#define SetupQueryInfOriginalFileInformation OVR_UNDEFINED +#define SetupQueryInfVersionInformation OVR_UNDEFINED +#define SetupGetInfDriverStoreLocation OVR_UNDEFINED +#define SetupGetInfPublishedName OVR_UNDEFINED +#define SetupGetInfFileList OVR_UNDEFINED +#define SetupOpenInfFile OVR_UNDEFINED +#define SetupOpenAppendInfFile OVR_UNDEFINED +#define SetupFindFirstLine OVR_UNDEFINED +#define SetupFindNextMatchLine OVR_UNDEFINED +#define SetupGetLineByIndex OVR_UNDEFINED +#define SetupGetLineCount OVR_UNDEFINED +#define SetupGetLineText OVR_UNDEFINED +#define SetupGetStringField OVR_UNDEFINED +#define SetupGetMultiSzField OVR_UNDEFINED +#define SetupGetFileCompressionInfo OVR_UNDEFINED +#define SetupGetFileCompressionInfoEx OVR_UNDEFINED +#define SetupDecompressOrCopyFile OVR_UNDEFINED +#define SetupGetSourceFileLocation OVR_UNDEFINED +#define SetupGetSourceFileSize OVR_UNDEFINED +#define SetupGetTargetPath OVR_UNDEFINED +#define SetupSetSourceList OVR_UNDEFINED +#define SetupAddToSourceList OVR_UNDEFINED +#define SetupRemoveFromSourceList OVR_UNDEFINED +#define SetupQuerySourceList OVR_UNDEFINED +#define SetupFreeSourceList OVR_UNDEFINED +#define SetupPromptForDisk OVR_UNDEFINED +#define SetupCopyError OVR_UNDEFINED +#define SetupRenameError OVR_UNDEFINED +#define SetupDeleteError OVR_UNDEFINED +#define SetupBackupError OVR_UNDEFINED +#define SetupSetDirectoryId OVR_UNDEFINED +#define SetupSetDirectoryIdEx OVR_UNDEFINED +#define SetupGetSourceInfo OVR_UNDEFINED +#define SetupInstallFile OVR_UNDEFINED +#define SetupInstallFileEx OVR_UNDEFINED +#define SetupSetFileQueueAlternatePlatform OVR_UNDEFINED +#define SetupSetPlatformPathOverride OVR_UNDEFINED +#define SetupQueueCopy OVR_UNDEFINED +#define SetupQueueCopyIndirect OVR_UNDEFINED +#define SetupQueueDefaultCopy OVR_UNDEFINED +#define SetupQueueCopySection OVR_UNDEFINED +#define SetupQueueDelete OVR_UNDEFINED +#define SetupQueueDeleteSection OVR_UNDEFINED +#define SetupQueueRename OVR_UNDEFINED +#define SetupQueueRenameSection OVR_UNDEFINED +#define SetupCommitFileQueue OVR_UNDEFINED +#define SetupScanFileQueue OVR_UNDEFINED +#define SetupCopyOEMInf OVR_UNDEFINED +#define SetupUninstallOEMInf OVR_UNDEFINED +#define SetupCreateDiskSpaceList OVR_UNDEFINED +#define SetupDuplicateDiskSpaceList OVR_UNDEFINED +#define SetupQueryDrivesInDiskSpaceList OVR_UNDEFINED +#define SetupQuerySpaceRequiredOnDrive OVR_UNDEFINED +#define SetupAdjustDiskSpaceList OVR_UNDEFINED +#define SetupAddToDiskSpaceList OVR_UNDEFINED +#define SetupAddSectionToDiskSpaceList OVR_UNDEFINED +#define SetupAddInstallSectionToDiskSpaceList OVR_UNDEFINED +#define SetupRemoveFromDiskSpaceList OVR_UNDEFINED +#define SetupRemoveSectionFromDiskSpaceList OVR_UNDEFINED +#define SetupRemoveInstallSectionFromDiskSpaceList OVR_UNDEFINED +#define SetupIterateCabinet OVR_UNDEFINED +#define SetupDefaultQueueCallback OVR_UNDEFINED +#define SetupInstallFromInfSection OVR_UNDEFINED +#define SetupInstallFilesFromInfSection OVR_UNDEFINED +#define SetupInstallServicesFromInfSection OVR_UNDEFINED +#define SetupInstallServicesFromInfSectionEx OVR_UNDEFINED +#define InstallHinfSection OVR_UNDEFINED +#define SetupInitializeFileLog OVR_UNDEFINED +#define SetupLogFile OVR_UNDEFINED +#define SetupRemoveFileLogEntry OVR_UNDEFINED +#define SetupQueryFileLog OVR_UNDEFINED +#define SetupGetBackupInformation OVR_UNDEFINED +#define SetupPrepareQueueForRestore OVR_UNDEFINED +#define SetupDiCreateDeviceInfoListEx OVR_UNDEFINED +#define SetupDiGetDeviceInfoListDetail OVR_UNDEFINED +#define SetupDiCreateDeviceInfo OVR_UNDEFINED +#define SetupDiOpenDeviceInfo OVR_UNDEFINED +#define SetupDiGetDeviceInstanceId OVR_UNDEFINED +#define SetupDiCreateDeviceInterface OVR_UNDEFINED +#define SetupDiOpenDeviceInterface OVR_UNDEFINED +#define SetupDiGetDeviceInterfaceDetail OVR_UNDEFINED +#define SetupDiEnumDriverInfo OVR_UNDEFINED +#define SetupDiGetSelectedDriver OVR_UNDEFINED +#define SetupDiSetSelectedDriver OVR_UNDEFINED +#define SetupDiGetDriverInfoDetail OVR_UNDEFINED +#define SetupDiGetClassDevs OVR_UNDEFINED +#define SetupDiGetClassDevsEx OVR_UNDEFINED +#define SetupDiGetINFClass OVR_UNDEFINED +#define SetupDiBuildClassInfoListEx OVR_UNDEFINED +#define SetupDiGetClassDescription OVR_UNDEFINED +#define SetupDiGetClassDescriptionEx OVR_UNDEFINED +#define SetupDiInstallClass OVR_UNDEFINED +#define SetupDiInstallClassEx OVR_UNDEFINED +#define SetupDiOpenClassRegKeyEx OVR_UNDEFINED +#define SetupDiCreateDeviceInterfaceRegKey OVR_UNDEFINED +#define SetupDiCreateDevRegKey OVR_UNDEFINED +#define SetupDiGetHwProfileListEx OVR_UNDEFINED +#define SetupDiGetDeviceRegistryProperty OVR_UNDEFINED +#define SetupDiGetClassRegistryProperty OVR_UNDEFINED +#define SetupDiSetDeviceRegistryProperty OVR_UNDEFINED +#define SetupDiSetClassRegistryProperty OVR_UNDEFINED +#define SetupDiGetDeviceInstallParams OVR_UNDEFINED +#define SetupDiGetClassInstallParams OVR_UNDEFINED +#define SetupDiSetDeviceInstallParams OVR_UNDEFINED +#define SetupDiSetClassInstallParams OVR_UNDEFINED +#define SetupDiGetDriverInstallParams OVR_UNDEFINED +#define SetupDiSetDriverInstallParams OVR_UNDEFINED +#define SetupDiGetClassImageListEx OVR_UNDEFINED +#define SetupDiGetClassDevPropertySheets OVR_UNDEFINED +#define SetupDiClassNameFromGuid OVR_UNDEFINED +#define SetupDiClassNameFromGuidEx OVR_UNDEFINED +#define SetupDiClassGuidsFromName OVR_UNDEFINED +#define SetupDiClassGuidsFromNameEx OVR_UNDEFINED +#define SetupDiGetHwProfileFriendlyName OVR_UNDEFINED +#define SetupDiGetHwProfileFriendlyNameEx OVR_UNDEFINED +#define SetupDiGetActualModelsSection OVR_UNDEFINED +#define SetupDiGetActualSectionToInstall OVR_UNDEFINED +#define SetupDiGetActualSectionToInstallEx OVR_UNDEFINED +#define SetupVerifyInfFile OVR_UNDEFINED +#define SetupDiGetCustomDeviceProperty OVR_UNDEFINED +#define SetupConfigureWmiFromInfSection OVR_UNDEFINED +#define DragQueryFile OVR_UNDEFINED +#define ShellExecute OVR_UNDEFINED +#define FindExecutable OVR_UNDEFINED +#define ShellAbout OVR_UNDEFINED +#define ExtractAssociatedIcon OVR_UNDEFINED +#define ExtractAssociatedIconEx OVR_UNDEFINED +#define ExtractIcon OVR_UNDEFINED +#define DoEnvironmentSubst OVR_UNDEFINED +#define ExtractIconEx OVR_UNDEFINED +#define SHFileOperation OVR_UNDEFINED +#define ShellExecuteEx OVR_UNDEFINED +#define SHSHQueryRecycleBin OVR_UNDEFINED +#define SHSHEmptyRecycleBin OVR_UNDEFINED +#define Shell_NotifyIcon OVR_UNDEFINED +#define SHGetFileInfo OVR_UNDEFINED +#define SHGetDiskFreeSpaceEx OVR_UNDEFINED +#define SHGetNewLinkInfo OVR_UNDEFINED +#define SHInvokePrinterCommand OVR_UNDEFINED +#define ShellMessageBox OVR_UNDEFINED +#define IsLFNDrive OVR_UNDEFINED +#define SHEnumerateUnreadMailAccounts OVR_UNDEFINED +#define SHGetUnreadMailCount OVR_UNDEFINED +#define SHSetUnreadMailCount OVR_UNDEFINED +#define SHGetIconOverlayIndex OVR_UNDEFINED +#define ILCreateFromPath OVR_UNDEFINED +#define SHGetPathFromIDList OVR_UNDEFINED +#define SHCreateDirectoryEx OVR_UNDEFINED +#define SHGetSpecialFolderPath OVR_UNDEFINED +#define SHGetFolderPath OVR_UNDEFINED +#define SHSetFolderPath OVR_UNDEFINED +#define SHGetFolderPathAndSubDir OVR_UNDEFINED +#define SHBrowseForFolder OVR_UNDEFINED +#define SHUpdateImage OVR_UNDEFINED +#define SHSHGetDataFromIDList OVR_UNDEFINED +#define PathIsSlow OVR_UNDEFINED +#define SHSHStartNetConnectionDialog OVR_UNDEFINED +#define SHSHDefExtractIcon OVR_UNDEFINED +#define Shell_GetCachedImageIndex OVR_UNDEFINED +#define SHOpenPropSheet OVR_UNDEFINED +#define SHSHPathPrepareForWrite OVR_UNDEFINED +#define SHSHCreateFileExtractIcon OVR_UNDEFINED +#define StrChr OVR_UNDEFINED +#define StrChrI OVR_UNDEFINED +#define StrCmpN OVR_UNDEFINED +#define StrCmpNI OVR_UNDEFINED +#define StrCSpn OVR_UNDEFINED +#define StrCSpnI OVR_UNDEFINED +#define StrDup OVR_UNDEFINED +#define StrFormatByteSize OVR_UNDEFINED +#define StrFormatByteSize64 OVR_UNDEFINED +#define StrFormatKBSize OVR_UNDEFINED +#define StrFromTimeInterval OVR_UNDEFINED +#define StrIsIntlEqual OVR_UNDEFINED +#define StrNCat OVR_UNDEFINED +#define StrPBrk OVR_UNDEFINED +#define StrRChr OVR_UNDEFINED +#define StrRChrI OVR_UNDEFINED +#define StrRStrI OVR_UNDEFINED +#define StrPBrk OVR_UNDEFINED +#define StrRChr OVR_UNDEFINED +#define StrRChrI OVR_UNDEFINED +#define StrRStrI OVR_UNDEFINED +#define StrSpn OVR_UNDEFINED +#define StrStr OVR_UNDEFINED +#define StrStrI OVR_UNDEFINED +#define StrStr OVR_UNDEFINED +#define StrStrI OVR_UNDEFINED +#define StrToInt OVR_UNDEFINED +#define StrToIntEx OVR_UNDEFINED +#define StrToInt64Ex OVR_UNDEFINED +#define StrTrim OVR_UNDEFINED +#define StrCatBuff OVR_UNDEFINED +#define ChrCmpI OVR_UNDEFINED +#define wvnsprintf OVR_UNDEFINED +#define wnsprintf OVR_UNDEFINED +#define LWStrRetToStr OVR_UNDEFINED +#define LWStrRetToBuf OVR_UNDEFINED +#define LWSHStrDup OVR_UNDEFINED +#define SHLocalStrDup OVR_UNDEFINED +#define IsCharSpace OVR_UNDEFINED +#define StrCmpC OVR_UNDEFINED +#define StrCmpIC OVR_UNDEFINED +#define StrCmpNC OVR_UNDEFINED +#define StrCmpNIC OVR_UNDEFINED +#define IntlStrEqWorker OVR_UNDEFINED +#define PathAddBackslash OVR_UNDEFINED +#define PathAddExtension OVR_UNDEFINED +#define PathAppend OVR_UNDEFINED +#define PathBuildRoot OVR_UNDEFINED +#define PathCanonicalize OVR_UNDEFINED +#define PathCombine OVR_UNDEFINED +#define PathCompactPath OVR_UNDEFINED +#define PathCompactPathEx OVR_UNDEFINED +#define PathCommonPrefix OVR_UNDEFINED +#define PathFileExists OVR_UNDEFINED +#define PathFindExtension OVR_UNDEFINED +#define PathFindFileName OVR_UNDEFINED +#define PathFindNextComponent OVR_UNDEFINED +#define PathFindExtension OVR_UNDEFINED +#define PathFindFileName OVR_UNDEFINED +#define PathFindNextComponent OVR_UNDEFINED +#define PathFindOnPath OVR_UNDEFINED +#define PathFindSuffixArray OVR_UNDEFINED +#define PathGetArgs OVR_UNDEFINED +#define PathGetArgs OVR_UNDEFINED +#define PathIsLFNFileSpec OVR_UNDEFINED +#define PathGetCharType OVR_UNDEFINED +#define PathGetDriveNumber OVR_UNDEFINED +#define PathIsDirectory OVR_UNDEFINED +#define PathIsDirectoryEmpty OVR_UNDEFINED +#define PathIsFileSpec OVR_UNDEFINED +#define PathIsPrefix OVR_UNDEFINED +#define PathIsRelative OVR_UNDEFINED +#define PathIsRoot OVR_UNDEFINED +#define PathIsSameRoot OVR_UNDEFINED +#define PathIsUNC OVR_UNDEFINED +#define PathIsNetworkPath OVR_UNDEFINED +#define PathIsUNCServer OVR_UNDEFINED +#define PathIsUNCServerShare OVR_UNDEFINED +#define PathIsContentType OVR_UNDEFINED +#define PathIsURL OVR_UNDEFINED +#define PathMakePretty OVR_UNDEFINED +#define PathMatchSpec OVR_UNDEFINED +#define LWPathMatchSpecEx OVR_UNDEFINED +#define PathParseIconLocation OVR_UNDEFINED +#define PathQuoteSpaces OVR_UNDEFINED +#define PathRelativePathTo OVR_UNDEFINED +#define PathRemoveArgs OVR_UNDEFINED +#define PathRemoveBackslash OVR_UNDEFINED +#define PathRemoveBlanks OVR_UNDEFINED +#define PathRemoveExtension OVR_UNDEFINED +#define PathRemoveFileSpec OVR_UNDEFINED +#define PathRenameExtension OVR_UNDEFINED +#define PathSearchAndQualify OVR_UNDEFINED +#define PathSetDlgItemPath OVR_UNDEFINED +#define PathSkipRoot OVR_UNDEFINED +#define PathSkipRoot OVR_UNDEFINED +#define PathStripPath OVR_UNDEFINED +#define PathStripToRoot OVR_UNDEFINED +#define PathUnquoteSpaces OVR_UNDEFINED +#define PathMakeSystemFolder OVR_UNDEFINED +#define PathUnmakeSystemFolder OVR_UNDEFINED +#define PathIsSystemFolder OVR_UNDEFINED +#define PathUndecorate OVR_UNDEFINED +#define PathUnExpandEnvStrings OVR_UNDEFINED +#define UrlCompare OVR_UNDEFINED +#define UrlCombine OVR_UNDEFINED +#define UrlCanonicalize OVR_UNDEFINED +#define UrlIsOpaque OVR_UNDEFINED +#define UrlIsNoHistory OVR_UNDEFINED +#define UrlIs OVR_UNDEFINED +#define UrlGetLocation OVR_UNDEFINED +#define UrlUnescape OVR_UNDEFINED +#define UrlEscape OVR_UNDEFINED +#define UrlCreateFromPath OVR_UNDEFINED +#define PathCreateFromUrl OVR_UNDEFINED +#define UrlHash OVR_UNDEFINED +#define UrlGetPart OVR_UNDEFINED +#define UrlApplyScheme OVR_UNDEFINED +#define ParseURL OVR_UNDEFINED +#define SHDeleteEmptyKey OVR_UNDEFINED +#define SHDeleteKey OVR_UNDEFINED +#define SHDeleteValue OVR_UNDEFINED +#define SHGetValue OVR_UNDEFINED +#define SHSetValue OVR_UNDEFINED +#define SHRegGetValue OVR_UNDEFINED +#define SHQueryValueEx OVR_UNDEFINED +#define SHEnumKeyEx OVR_UNDEFINED +#define SHEnumValue OVR_UNDEFINED +#define SHQueryInfoKey OVR_UNDEFINED +#define SHCopyKey OVR_UNDEFINED +#define SHRegGetPath OVR_UNDEFINED +#define SHRegSetPath OVR_UNDEFINED +#define SHRegCreateUSKey OVR_UNDEFINED +#define SHRegOpenUSKey OVR_UNDEFINED +#define SHRegQueryUSValue OVR_UNDEFINED +#define SHRegWriteUSValue OVR_UNDEFINED +#define SHRegDeleteUSValue OVR_UNDEFINED +#define SHRegDeleteEmptyUSKey OVR_UNDEFINED +#define SHRegEnumUSKey OVR_UNDEFINED +#define SHRegEnumUSValue OVR_UNDEFINED +#define SHRegQueryInfoUSKey OVR_UNDEFINED +#define SHRegGetUSValue OVR_UNDEFINED +#define SHRegSetUSValue OVR_UNDEFINED +#define SHRegGetBoolUSValue OVR_UNDEFINED +#define LWAssocQueryString OVR_UNDEFINED +#define LWAssocQueryStringByKey OVR_UNDEFINED +#define LWAssocQueryKey OVR_UNDEFINED +#define HOpenRegStream OVR_UNDEFINED +#define SHOpenRegStream2 OVR_UNDEFINED +#define LWSHCreateStreamOnFile OVR_UNDEFINED +#define LWGetAcceptLanguages OVR_UNDEFINED +#define SHFormatDateTime OVR_UNDEFINED +#define SHMessageBoxCheck OVR_UNDEFINED +#define SHSendMessageBroadcast OVR_UNDEFINED +#define SHStripMneumonic OVR_UNDEFINED +#define StrChr OVR_UNDEFINED +#define StrChrI OVR_UNDEFINED +#define StrPBrk OVR_UNDEFINED +#define StrRChr OVR_UNDEFINED +#define StrRChrI OVR_UNDEFINED +#define StrRStrI OVR_UNDEFINED +#define StrStr OVR_UNDEFINED +#define StrStrI OVR_UNDEFINED +#define PathFindExtension OVR_UNDEFINED +#define PathFindFileName OVR_UNDEFINED +#define PathFindNextComponent OVR_UNDEFINED +#define PathGetArgs OVR_UNDEFINED +#define PathSkipRoot OVR_UNDEFINED +#define SnmpUtilOidTo OVR_UNDEFINED +#define SnmpUtilIdsTo OVR_UNDEFINED +#define SQLSetConnectAttrForDbcInfo OVR_UNDEFINED +#define SQLSetDriverConnectInfo OVR_UNDEFINED +#define SQLPoolConnect OVR_UNDEFINED +#define SQLColAttribute OVR_UNDEFINED +#define SQLColAttribute OVR_UNDEFINED +#define SQLColAttributes OVR_UNDEFINED +#define SQLConnect OVR_UNDEFINED +#define SQLDescribeCol OVR_UNDEFINED +#define SQLError OVR_UNDEFINED +#define SQLExecDirect OVR_UNDEFINED +#define SQLGetConnectAttr OVR_UNDEFINED +#define SQLGetCursorName OVR_UNDEFINED +#define SQLGetDescField OVR_UNDEFINED +#define SQLGetDescRec OVR_UNDEFINED +#define SQLGetDiagField OVR_UNDEFINED +#define SQLGetDiagRec OVR_UNDEFINED +#define SQLGetStmtAttr OVR_UNDEFINED +#define SQLGetTypeInfo OVR_UNDEFINED +#define SQLPrepare OVR_UNDEFINED +#define SQLSetConnectAttr OVR_UNDEFINED +#define SQLSetCursorName OVR_UNDEFINED +#define SQLColumns OVR_UNDEFINED +#define SQLGetConnectOption OVR_UNDEFINED +#define SQLGetInfo OVR_UNDEFINED +#define SQLGetStmtOption OVR_UNDEFINED +#define SQLSetConnectOption OVR_UNDEFINED +#define SQLSetStmtOption OVR_UNDEFINED +#define SQLSpecialColumns OVR_UNDEFINED +#define SQLStatistics OVR_UNDEFINED +#define SQLTables OVR_UNDEFINED +#define SQLDataSources OVR_UNDEFINED +#define SQLDriverConnect OVR_UNDEFINED +#define SQLBrowseConnect OVR_UNDEFINED +#define SQLColumnPrivileges OVR_UNDEFINED +#define SQLDescribeParam OVR_UNDEFINED +#define SQLForeignKeys OVR_UNDEFINED +#define SQLNativeSql OVR_UNDEFINED +#define SQLPrimaryKeys OVR_UNDEFINED +#define SQLProcedureColumns OVR_UNDEFINED +#define SQLProcedures OVR_UNDEFINED +#define SQLTablePrivileges OVR_UNDEFINED +#define SQLDrivers OVR_UNDEFINED +#define SRSetRestorePoint OVR_UNDEFINED +#define AcquireCredentialsHandle OVR_UNDEFINED +#define AddCredentials OVR_UNDEFINED +#define SspiAcquireCredentialsHandleAsync OVR_UNDEFINED +#define SspiInitializeSecurityContextAsync OVR_UNDEFINED +#define ChangeAccountPassword OVR_UNDEFINED +#define InitializeSecurityContext OVR_UNDEFINED +#define QueryContextAttributes OVR_UNDEFINED +#define QueryContextAttributesEx OVR_UNDEFINED +#define SetContextAttributes OVR_UNDEFINED +#define QueryCredentialsAttributes OVR_UNDEFINED +#define QueryCredentialsAttributesEx OVR_UNDEFINED +#define SetCredentialsAttributes OVR_UNDEFINED +#define EnumerateSecurityPackages OVR_UNDEFINED +#define QuerySecurityPackageInfo OVR_UNDEFINED +#define ImportSecurityContext OVR_UNDEFINED +#define InitSecurityInterface OVR_UNDEFINED +#define SaslEnumerateProfiles OVR_UNDEFINED +#define SaslGetProfilePackage OVR_UNDEFINED +#define SaslIdentifyPackage OVR_UNDEFINED +#define SaslInitializeSecurityContext OVR_UNDEFINED +#define SspiPromptForCredentials OVR_UNDEFINED +#define AddSecurityPackage OVR_UNDEFINED +#define DeleteSecurityPackage OVR_UNDEFINED +#define CreateMutex OVR_UNDEFINED +#define CreateEvent OVR_UNDEFINED +#define OpenEvent OVR_UNDEFINED +#define CreateMutexEx OVR_UNDEFINED +#define CreateEventEx OVR_UNDEFINED +#define GetSystemDirectory OVR_UNDEFINED +#define GetWindowsDirectory OVR_UNDEFINED +#define GetSystemWindowsDirectory OVR_UNDEFINED +#define GetComputerNameEx OVR_UNDEFINED +#define GetVersionEx OVR_UNDEFINED +#define SetComputerName OVR_UNDEFINED +#define SetComputerNameEx OVR_UNDEFINED +#define lineAddProvider OVR_UNDEFINED +#define lineBlindTransfer OVR_UNDEFINED +#define lineConfigDialog OVR_UNDEFINED +#define lineConfigDialogEdit OVR_UNDEFINED +#define lineCreateAgent OVR_UNDEFINED +#define lineCreateAgentSession OVR_UNDEFINED +#define lineDial OVR_UNDEFINED +#define lineForward OVR_UNDEFINED +#define lineGatherDigits OVR_UNDEFINED +#define lineGenerateDigits OVR_UNDEFINED +#define lineGetAddressCaps OVR_UNDEFINED +#define lineGetAddressID OVR_UNDEFINED +#define lineGetAddressStatus OVR_UNDEFINED +#define lineGetAgentActivityList OVR_UNDEFINED +#define lineGetAgentCaps OVR_UNDEFINED +#define lineGetAgentGroupList OVR_UNDEFINED +#define lineGetAgentStatus OVR_UNDEFINED +#define lineGetAppPriority OVR_UNDEFINED +#define lineGetCallInfo OVR_UNDEFINED +#define lineGetCountry OVR_UNDEFINED +#define lineGetDevCaps OVR_UNDEFINED +#define lineGetDevConfig OVR_UNDEFINED +#define lineGetGroupList OVR_UNDEFINED +#define lineGetIcon OVR_UNDEFINED +#define lineGetID OVR_UNDEFINED +#define lineGetLineDevStatus OVR_UNDEFINED +#define lineGetProviderList OVR_UNDEFINED +#define lineGetQueueList OVR_UNDEFINED +#define lineGetRequest OVR_UNDEFINED +#define lineGetTranslateCaps OVR_UNDEFINED +#define lineHandoff OVR_UNDEFINED +#define lineInitializeEx OVR_UNDEFINED +#define lineMakeCall OVR_UNDEFINED +#define lineOpen OVR_UNDEFINED +#define linePark OVR_UNDEFINED +#define linePickup OVR_UNDEFINED +#define linePrepareAddToConference OVR_UNDEFINED +#define lineRedirect OVR_UNDEFINED +#define lineSetAppPriority OVR_UNDEFINED +#define lineSetDevConfig OVR_UNDEFINED +#define lineSetTollList OVR_UNDEFINED +#define lineSetupConference OVR_UNDEFINED +#define lineSetupTransfer OVR_UNDEFINED +#define lineTranslateAddress OVR_UNDEFINED +#define lineTranslateDialog OVR_UNDEFINED +#define lineUnpark OVR_UNDEFINED +#define phoneConfigDialog OVR_UNDEFINED +#define phoneGetButtonInfo OVR_UNDEFINED +#define phoneGetDevCaps OVR_UNDEFINED +#define phoneGetIcon OVR_UNDEFINED +#define phoneGetID OVR_UNDEFINED +#define phoneGetStatus OVR_UNDEFINED +#define phoneInitializeEx OVR_UNDEFINED +#define phoneSetButtonInfo OVR_UNDEFINED +#define tapiGetLocationInfo OVR_UNDEFINED +#define tapiRequestMakeCall OVR_UNDEFINED +#define tapiRequestMediaCall OVR_UNDEFINED +#define URLOpenStream OVR_UNDEFINED +#define URLOpenPullStream OVR_UNDEFINED +#define URLDownloadToFile OVR_UNDEFINED +#define URLDownloadToCacheFile OVR_UNDEFINED +#define URLOpenBlockingStream OVR_UNDEFINED +#define IsLoggingEnabled OVR_UNDEFINED +#define LoadUserProfile OVR_UNDEFINED +#define GetProfilesDirectory OVR_UNDEFINED +#define GetDefaultUserProfileDirectory OVR_UNDEFINED +#define GetAllUsersProfileDirectory OVR_UNDEFINED +#define GetUserProfileDirectory OVR_UNDEFINED +#define ExpandEnvironmentStringsForUser OVR_UNDEFINED +#define AVIStreamOpenFromFile OVR_UNDEFINED +#define AVISaveV OVR_UNDEFINED +#define AVIBuildFilter OVR_UNDEFINED +#define EditStreamSetName OVR_UNDEFINED +#define EditStreamSetInfo OVR_UNDEFINED +#define MCIWndCreate OVR_UNDEFINED +#define GetOpenFileNamePreview OVR_UNDEFINED +#define GetSaveFileNamePreview OVR_UNDEFINED +#define ExtMatchPattern OVR_UNDEFINED +#define GetBinaryType OVR_UNDEFINED +#define GetShortPathName OVR_UNDEFINED +#define GetLongPathNameTransacted OVR_UNDEFINED +#define SetEnvironmentStrings OVR_UNDEFINED +#define SetFileShortName OVR_UNDEFINED +//#define FormatMessage OVR_UNDEFINED +#define CreateMailslot OVR_UNDEFINED +#define EncryptFile OVR_UNDEFINED +#define DecryptFile OVR_UNDEFINED +#define FileEncryptionStatus OVR_UNDEFINED +#define OpenEncryptedFileRaw OVR_UNDEFINED +#define lstrcmp OVR_UNDEFINED +#define lstrcmpi OVR_UNDEFINED +#define lstrcpyn OVR_UNDEFINED +#define lstrcpy OVR_UNDEFINED +#define lstrcat OVR_UNDEFINED +#define lstrlen OVR_UNDEFINED +#define OpenMutex OVR_UNDEFINED +#define CreateSemaphore OVR_UNDEFINED +#define OpenSemaphore OVR_UNDEFINED +#define CreateWaitableTimer OVR_UNDEFINED +#define OpenWaitableTimer OVR_UNDEFINED +#define CreateSemaphoreEx OVR_UNDEFINED +#define CreateWaitableTimerEx OVR_UNDEFINED +#define CreateFileMapping OVR_UNDEFINED +#define CreateFileMappingNuma OVR_UNDEFINED +#define OpenFileMapping OVR_UNDEFINED +#define GetLogicalDriveStrings OVR_UNDEFINED +#define QueryFullProcessImageName OVR_UNDEFINED +#define GetStartupInfo OVR_UNDEFINED +#define GetFirmwareEnvironmentVariable OVR_UNDEFINED +#define GetFirmwareEnvironmentVariableEx OVR_UNDEFINED +#define SetFirmwareEnvironmentVariable OVR_UNDEFINED +#define SetFirmwareEnvironmentVariableEx OVR_UNDEFINED +#define FindResource OVR_UNDEFINED +#define FindResourceEx OVR_UNDEFINED +#define EnumResourceTypes OVR_UNDEFINED +#define EnumResourceNames OVR_UNDEFINED +#define EnumResourceLanguages OVR_UNDEFINED +#define BeginUpdateResource OVR_UNDEFINED +#define UpdateResource OVR_UNDEFINED +#define EndUpdateResource OVR_UNDEFINED +#define GlobalAddAtom OVR_UNDEFINED +#define GlobalAddAtomEx OVR_UNDEFINED +#define GlobalFindAtom OVR_UNDEFINED +#define GlobalGetAtomName OVR_UNDEFINED +#define AddAtom OVR_UNDEFINED +#define FindAtom OVR_UNDEFINED +#define GetAtomName OVR_UNDEFINED +#define GetProfileInt OVR_UNDEFINED +#define GetProfileString OVR_UNDEFINED +#define WriteProfileString OVR_UNDEFINED +#define GetProfileSection OVR_UNDEFINED +#define WriteProfileSection OVR_UNDEFINED +#define GetPrivateProfileInt OVR_UNDEFINED +#define GetPrivateProfileString OVR_UNDEFINED +#define WritePrivateProfileString OVR_UNDEFINED +#define GetPrivateProfileSection OVR_UNDEFINED +#define WritePrivateProfileSection OVR_UNDEFINED +#define GetPrivateProfileSectionNames OVR_UNDEFINED +#define GetPrivateProfileStruct OVR_UNDEFINED +#define WritePrivateProfileStruct OVR_UNDEFINED +#define SetDllDirectory OVR_UNDEFINED +#define GetDllDirectory OVR_UNDEFINED +#define CreateDirectoryEx OVR_UNDEFINED +#define CreateDirectoryTransacted OVR_UNDEFINED +#define RemoveDirectoryTransacted OVR_UNDEFINED +#define GetFullPathNameTransacted OVR_UNDEFINED +#define DefineDosDevice OVR_UNDEFINED +#define QueryDosDevice OVR_UNDEFINED +#define CreateFileTransacted OVR_UNDEFINED +#define SetFileAttributesTransacted OVR_UNDEFINED +#define GetFileAttributesTransacted OVR_UNDEFINED +#define GetCompressedFileSizeTransacted OVR_UNDEFINED +#define DeleteFileTransacted OVR_UNDEFINED +#define CheckNameLegalDOS8Dot3 OVR_UNDEFINED +#define FindFirstFileTransacted OVR_UNDEFINED +#define CopyFile OVR_UNDEFINED +#define CopyFileEx OVR_UNDEFINED +#define CopyFileTransacted OVR_UNDEFINED +#define MoveFile OVR_UNDEFINED +#define MoveFileEx OVR_UNDEFINED +#define MoveFileWithProgress OVR_UNDEFINED +#define MoveFileTransacted OVR_UNDEFINED +#define ReplaceFile OVR_UNDEFINED +#define CreateHardLink OVR_UNDEFINED +#define CreateHardLinkTransacted OVR_UNDEFINED +#define CreateNamedPipe OVR_UNDEFINED +#define GetNamedPipeHandleState OVR_UNDEFINED +#define CallNamedPipe OVR_UNDEFINED +#define WaitNamedPipe OVR_UNDEFINED +#define GetNamedPipeClientComputerName OVR_UNDEFINED +#define SetVolumeLabel OVR_UNDEFINED +#define IsBadStringPtr OVR_UNDEFINED +#define LookupAccountSid OVR_UNDEFINED +#define LookupAccountName OVR_UNDEFINED +#define LookupAccountNameLocal OVR_UNDEFINED +#define LookupAccountSidLocal OVR_UNDEFINED +#define LookupPrivilegeValue OVR_UNDEFINED +#define LookupPrivilegeName OVR_UNDEFINED +#define LookupPrivilegeDisplayName OVR_UNDEFINED +#define BuildCommDCB OVR_UNDEFINED +#define BuildCommDCBAndTimeouts OVR_UNDEFINED +#define CommConfigDialog OVR_UNDEFINED +#define GetDefaultCommConfig OVR_UNDEFINED +#define SetDefaultCommConfig OVR_UNDEFINED +#define CreatePrivateNamespace OVR_UNDEFINED +#define OpenPrivateNamespace OVR_UNDEFINED +#define CreateBoundaryDescriptor OVR_UNDEFINED +#define VerifyVersionInfo OVR_UNDEFINED +#define CreateJobObject OVR_UNDEFINED +#define OpenJobObject OVR_UNDEFINED +#define FindFirstVolume OVR_UNDEFINED +#define FindNextVolume OVR_UNDEFINED +#define FindFirstVolumeMountPoint OVR_UNDEFINED +#define FindNextVolumeMountPoint OVR_UNDEFINED +#define SetVolumeMountPoint OVR_UNDEFINED +#define DeleteVolumeMountPoint OVR_UNDEFINED +#define GetVolumeNameForVolumeMountPoint OVR_UNDEFINED +#define GetVolumePathName OVR_UNDEFINED +#define GetVolumePathNamesForVolumeName OVR_UNDEFINED +#define CreateActCtx OVR_UNDEFINED +#define FindActCtxSectionString OVR_UNDEFINED +#define WriteConsoleInput OVR_UNDEFINED +#define ReadConsoleOutput OVR_UNDEFINED +#define WriteConsoleOutput OVR_UNDEFINED +#define ReadConsoleOutputCharacter OVR_UNDEFINED +#define WriteConsoleOutputCharacter OVR_UNDEFINED +#define FillConsoleOutputCharacter OVR_UNDEFINED +#define ScrollConsoleScreenBuffer OVR_UNDEFINED +#define GetConsoleTitle OVR_UNDEFINED +#define GetConsoleOriginalTitle OVR_UNDEFINED +#define SetConsoleTitle OVR_UNDEFINED +#define AddConsoleAlias OVR_UNDEFINED +#define GetConsoleAlias OVR_UNDEFINED +#define GetConsoleAliasesLength OVR_UNDEFINED +#define GetConsoleAliasExesLength OVR_UNDEFINED +#define GetConsoleAliases OVR_UNDEFINED +#define GetConsoleAliasExes OVR_UNDEFINED +#define CredMarshalCredential OVR_UNDEFINED +#define CredUnmarshalCredential OVR_UNDEFINED +#define CredIsMarshaledCredential OVR_UNDEFINED +#define CredUnPackAuthenticationBuffer OVR_UNDEFINED +#define CredPackAuthenticationBuffer OVR_UNDEFINED +#define CredProtect OVR_UNDEFINED +#define CredUnprotect OVR_UNDEFINED +#define CredIsProtected OVR_UNDEFINED +#define CredUIPromptForCredentials OVR_UNDEFINED +#define CredUIPromptForWindowsCredentials OVR_UNDEFINED +#define CredUIParseUserName OVR_UNDEFINED +#define CredUICmdLinePromptForCredentials OVR_UNDEFINED +#define CredUIConfirmCredentials OVR_UNDEFINED +#define CryptAcquireContext OVR_UNDEFINED +#define CryptAcquireContext OVR_UNDEFINED +#define CryptAcquireContext OVR_UNDEFINED +#define CryptSignHash OVR_UNDEFINED +#define CryptSignHash OVR_UNDEFINED +#define CryptSignHash OVR_UNDEFINED +#define CryptVerifySignature OVR_UNDEFINED +#define CryptVerifySignature OVR_UNDEFINED +#define CryptVerifySignature OVR_UNDEFINED +#define CryptSetProvider OVR_UNDEFINED +#define CryptSetProvider OVR_UNDEFINED +#define CryptSetProviderEx OVR_UNDEFINED +#define CryptSetProviderEx OVR_UNDEFINED +#define CryptGetDefaultProvider OVR_UNDEFINED +#define CryptGetDefaultProvider OVR_UNDEFINED +#define CryptEnumProviderTypes OVR_UNDEFINED +#define CryptEnumProviderTypes OVR_UNDEFINED +#define CryptEnumProviderTypes OVR_UNDEFINED +#define CryptEnumProviders OVR_UNDEFINED +#define CryptEnumProviders OVR_UNDEFINED +#define CryptEnumProviders OVR_UNDEFINED +#define CertRDNValueToStr OVR_UNDEFINED +#define CertNameToStr OVR_UNDEFINED +#define CertStrToName OVR_UNDEFINED +#define CertGetNameString OVR_UNDEFINED +#define CertOpenSystemStore OVR_UNDEFINED +#define CertAddEncodedCertificateToSystemStore OVR_UNDEFINED +#define CryptStringToBinary OVR_UNDEFINED +#define CryptBinaryToString OVR_UNDEFINED +#define DnsQuery_ OVR_UNDEFINED +#define DnsAcquireContextHandle_ OVR_UNDEFINED +#define DnsModifyRecordsInSet_ OVR_UNDEFINED +#define DnsReplaceRecordSet OVR_UNDEFINED +#define DnsValidateName_ OVR_UNDEFINED +#define DnsNameCompare_ OVR_UNDEFINED +#define FaxConnectFaxServer OVR_UNDEFINED +#define FaxCompleteJobParams OVR_UNDEFINED +#define FaxSendDocument OVR_UNDEFINED +#define FaxSendDocumentForBroadcast OVR_UNDEFINED +#define FaxEnumJobs OVR_UNDEFINED +#define FaxGetJob OVR_UNDEFINED +#define FaxSetJob OVR_UNDEFINED +#define FaxGetDeviceStatus OVR_UNDEFINED +#define FaxGetConfiguration OVR_UNDEFINED +#define FaxSetConfiguration OVR_UNDEFINED +#define FaxGetLoggingCategories OVR_UNDEFINED +#define FaxSetLoggingCategories OVR_UNDEFINED +#define FaxEnumPorts OVR_UNDEFINED +#define FaxGetPort OVR_UNDEFINED +#define FaxSetPort OVR_UNDEFINED +#define FaxEnumRoutingMethods OVR_UNDEFINED +#define FaxEnableRoutingMethod OVR_UNDEFINED +#define FaxEnumGlobalRoutingInfo OVR_UNDEFINED +#define FaxSetGlobalRoutingInfo OVR_UNDEFINED +#define FaxGetRoutingInfo OVR_UNDEFINED +#define FaxSetRoutingInfo OVR_UNDEFINED +#define FaxStartPrintJob OVR_UNDEFINED +#define FaxPrintCoverPage OVR_UNDEFINED +#define FaxUnregisterRoutingExtension OVR_UNDEFINED +#define AddFontResource OVR_UNDEFINED +#define CopyMetaFile OVR_UNDEFINED +#define CreateDC OVR_UNDEFINED +#define CreateFontIndirect OVR_UNDEFINED +#define CreateFont OVR_UNDEFINED +#define CreateIC OVR_UNDEFINED +#define CreateMetaFile OVR_UNDEFINED +#define CreateScalableFontResource OVR_UNDEFINED +#define DeviceCapabilities OVR_UNDEFINED +#define EnumFontFamiliesEx OVR_UNDEFINED +#define EnumFontFamilies OVR_UNDEFINED +#define EnumFonts OVR_UNDEFINED +#define GetCharWidth OVR_UNDEFINED +#define GetCharWidth32 OVR_UNDEFINED +#define GetCharWidthFloat OVR_UNDEFINED +#define GetCharABCWidths OVR_UNDEFINED +#define GetCharABCWidthsFloat OVR_UNDEFINED +#define GetGlyphOutline OVR_UNDEFINED +#define GetMetaFile OVR_UNDEFINED +#define GetOutlineTextMetrics OVR_UNDEFINED +#define GetTextExtentPoint OVR_UNDEFINED +#define GetTextExtentPoint32 OVR_UNDEFINED +#define GetTextExtentExPoint OVR_UNDEFINED +#define GetCharacterPlacement OVR_UNDEFINED_ +#define GetGlyphIndices OVR_UNDEFINED +#define AddFontResourceEx OVR_UNDEFINED +#define RemoveFontResourceEx OVR_UNDEFINED +#define CreateFontIndirectEx OVR_UNDEFINED +#define LineDD OVR_UNDEFINED +#define ResetDC OVR_UNDEFINED +#define RemoveFontResource OVR_UNDEFINED +#define CopyEnhMetaFile OVR_UNDEFINED +#define CreateEnhMetaFile OVR_UNDEFINED +#define GetEnhMetaFile OVR_UNDEFINED +#define GetEnhMetaFileDescription OVR_UNDEFINED +#define GetTextMetrics OVR_UNDEFINED +#define StartDoc OVR_UNDEFINED +#define GetObject OVR_UNDEFINED +#define TextOut OVR_UNDEFINED +#define ExtTextOut OVR_UNDEFINED +#define PolyTextOut OVR_UNDEFINED +#define GetTextFace OVR_UNDEFINED +#define GetKerningPairs OVR_UNDEFINED +#define GetLogColorSpace OVR_UNDEFINED +#define CreateColorSpace OVR_UNDEFINED +#define GetICMProfile OVR_UNDEFINED +#define SetICMProfile OVR_UNDEFINED +#define EnumICMProfiles OVR_UNDEFINED +#define UpdateICMRegKey OVR_UNDEFINED +#define wglUseFontBitmaps OVR_UNDEFINED +#define wglUseFontOutlines OVR_UNDEFINED +#define InternetTimeFromSystemTime OVR_UNDEFINED +#define InternetTimeToSystemTime OVR_UNDEFINED +#define InternetCrackUrl OVR_UNDEFINED +#define InternetCreateUrl OVR_UNDEFINED +#define InternetCanonicalizeUrl OVR_UNDEFINED +#define InternetCombineUrl OVR_UNDEFINED +#define InternetOpen OVR_UNDEFINED +#define InternetConnect OVR_UNDEFINED +#define InternetOpenUrl OVR_UNDEFINED +#define InternetReadFileEx OVR_UNDEFINED +#define InternetFindNextFile OVR_UNDEFINED +#define InternetQueryOption OVR_UNDEFINED +#define InternetSetOption OVR_UNDEFINED +#define InternetSetOptionEx OVR_UNDEFINED +#define InternetGetLastResponseInfo OVR_UNDEFINED +#define InternetSetStatusCallback OVR_UNDEFINED +#define FtpFindFirstFile OVR_UNDEFINED +#define FtpGetFile OVR_UNDEFINED +#define FtpPutFile OVR_UNDEFINED +#define FtpDeleteFile OVR_UNDEFINED +#define FtpRenameFile OVR_UNDEFINED +#define FtpOpenFile OVR_UNDEFINED +#define FtpCreateDirectory OVR_UNDEFINED +#define FtpRemoveDirectory OVR_UNDEFINED +#define FtpSetCurrentDirectory OVR_UNDEFINED +#define FtpGetCurrentDirectory OVR_UNDEFINED +#define FtpCommand OVR_UNDEFINED +#define GopherCreateLocator OVR_UNDEFINED +#define GopherGetLocatorType OVR_UNDEFINED +#define GopherFindFirstFile OVR_UNDEFINED +#define GopherOpenFile OVR_UNDEFINED +#define GopherGetAttribute OVR_UNDEFINED +#define HttpOpenRequest OVR_UNDEFINED +#define HttpAddRequestHeaders OVR_UNDEFINED +#define HttpSendRequest OVR_UNDEFINED +#define HttpSendRequestEx OVR_UNDEFINED +#define HttpEndRequest OVR_UNDEFINED +#define HttpQueryInfo OVR_UNDEFINED +#define InternetSetCookie OVR_UNDEFINED +#define InternetGetCookie OVR_UNDEFINED +#define InternetSetCookieEx OVR_UNDEFINED +#define InternetGetCookieEx OVR_UNDEFINED +#define InternetCheckConnection OVR_UNDEFINED +#define InternetConfirmZoneCrossing OVR_UNDEFINED +#define CreateUrlCacheEntry OVR_UNDEFINED +#define CommitUrlCacheEntry OVR_UNDEFINED +#define RetrieveUrlCacheEntryFile OVR_UNDEFINED +#define UnlockUrlCacheEntryFile OVR_UNDEFINED +#define RetrieveUrlCacheEntryStream OVR_UNDEFINED +#define GetUrlCacheEntryInfo OVR_UNDEFINED +#define GetUrlCacheGroupAttribute OVR_UNDEFINED +#define SetUrlCacheGroupAttribute OVR_UNDEFINED +#define GetUrlCacheEntryInfoEx OVR_UNDEFINED +#define SetUrlCacheEntryInfo OVR_UNDEFINED +#define SetUrlCacheEntryGroup OVR_UNDEFINED +#define FindFirstUrlCacheEntryEx OVR_UNDEFINED +#define FindNextUrlCacheEntryEx OVR_UNDEFINED +#define FindFirstUrlCacheEntry OVR_UNDEFINED +#define FindNextUrlCacheEntry OVR_UNDEFINED +#define DeleteUrlCacheEntry OVR_UNDEFINED +//#define INTERNETAPI_ OVR_UNDEFINED +#define InternetDial OVR_UNDEFINED +#define InternetGoOnline OVR_UNDEFINED +#define InternetGetConnectedStateEx OVR_UNDEFINED +#define InternetSetDialState OVR_UNDEFINED +#define InternetSetPerSiteCookieDecision OVR_UNDEFINED +#define InternetGetPerSiteCookieDecision OVR_UNDEFINED +#define InternetEnumPerSiteCookieDecision OVR_UNDEFINED +#define InternetAlgIdToString OVR_UNDEFINED +#define InternetSecurityProtocolToString OVR_UNDEFINED +#define InternetGetSecurityInfoByURL OVR_UNDEFINED +#define InternetShowSecurityInfoByURL OVR_UNDEFINED +#define InternetWriteFileEx OVR_UNDEFINED +#define HttpCheckDavCompliance OVR_UNDEFINED +#define IsUrlCacheEntryExpired OVR_UNDEFINED +#define CreateUrlCacheContainer OVR_UNDEFINED +#define DeleteUrlCacheContainer OVR_UNDEFINED +#define FindFirstUrlCacheContainer OVR_UNDEFINED +#define FindNextUrlCacheContainer OVR_UNDEFINED +#define FreeUrlCacheSpace OVR_UNDEFINED +#define GetUrlCacheConfigInfo OVR_UNDEFINED +#define SetUrlCacheConfigInfo OVR_UNDEFINED +#define GetUrlCacheContainerInfo OVR_UNDEFINED +#define InternetGoOnline OVR_UNDEFINED +#define InternetGetConnectedStateEx OVR_UNDEFINED +#define InternetSetDialState OVR_UNDEFINED +#define GetDiskInfo OVR_UNDEFINED +#define PerformOperationOverUrlCache OVR_UNDEFINED +#define ImportCookieFile OVR_UNDEFINED +#define ExportCookieFile OVR_UNDEFINED +#define IsDomainLegalCookieDomain OVR_UNDEFINED +#define InternetEnumPerSiteCookieDecision OVR_UNDEFINED +#define ldap_open OVR_UNDEFINED +#define ldap_init OVR_UNDEFINED +#define ldap_sslinit OVR_UNDEFINED +#define cldap_open OVR_UNDEFINED +#define ldap_simple_bind OVR_UNDEFINED +#define ldap_simple_bind_s OVR_UNDEFINED +#define ldap_bind OVR_UNDEFINED +#define ldap_bind_s OVR_UNDEFINED +#define ldap_sasl_bind OVR_UNDEFINED +#define ldap_sasl_bind_s OVR_UNDEFINED +#define ldap_search OVR_UNDEFINED +#define ldap_search_s OVR_UNDEFINED +#define ldap_search_st OVR_UNDEFINED +#define ldap_search_ext OVR_UNDEFINED +#define ldap_search_ext_s OVR_UNDEFINED +#define ldap_check_filter OVR_UNDEFINED +#define ldap_modify OVR_UNDEFINED +#define ldap_modify_s OVR_UNDEFINED +#define ldap_modify_ext OVR_UNDEFINED +#define ldap_modify_ext_s OVR_UNDEFINED +#define ldap_rename_ext OVR_UNDEFINED +#define ldap_rename_ext_s OVR_UNDEFINED +#define ldap_add OVR_UNDEFINED +#define ldap_add_s OVR_UNDEFINED +#define ldap_add_ext OVR_UNDEFINED +#define ldap_add_ext_s OVR_UNDEFINED +#define ldap_compare OVR_UNDEFINED +#define ldap_compare_s OVR_UNDEFINED +#define ldap_compare_ext OVR_UNDEFINED +#define ldap_compare_ext_s OVR_UNDEFINED +#define ldap_delete OVR_UNDEFINED +#define ldap_delete_s OVR_UNDEFINED +#define ldap_delete_ext OVR_UNDEFINED +#define ldap_delete_ext_s OVR_UNDEFINED +#define ldap_err2string OVR_UNDEFINEDUerr +#define ldap_first_attribute OVR_UNDEFINED +#define ldap_next_attribute OVR_UNDEFINED +#define ldap_get_values OVR_UNDEFINED +#define ldap_count_values OVR_UNDEFINED +#define ldap_value_free OVR_UNDEFINED +#define ldap_get_dn OVR_UNDEFINED +#define ldap_explode_dn OVR_UNDEFINED +#define ldap_dn2ufn OVR_UNDEFINED +#define ldap_memfree OVR_UNDEFINED +#define ldap_create_page_control OVR_UNDEFINED +#define LDAPAPIldap_search_init_page OVR_UNDEFINED +#define ldap_extended_operation OVR_UNDEFINED +#define WNetAddConnection OVR_UNDEFINED +#define WNetAddConnection2 OVR_UNDEFINED +#define WNetAddConnection3 OVR_UNDEFINED +#define WNetCancelConnection OVR_UNDEFINED +#define WNetCancelConnection2 OVR_UNDEFINED +#define WNetGetConnection OVR_UNDEFINED +#define WNetUseConnection OVR_UNDEFINED +#define WNetConnectionDialog1 OVR_UNDEFINED +#define WNetDisconnectDialog1 OVR_UNDEFINED +#define WNetOpenEnum OVR_UNDEFINED +#define WNetEnumResource OVR_UNDEFINED +#define WNetGetResourceParent OVR_UNDEFINED +#define WNetGetResourceInformation OVR_UNDEFINED +#define WNetGetUniversalName OVR_UNDEFINED +#define WNetGetUser OVR_UNDEFINED +#define WNetGetProviderName OVR_UNDEFINED +#define WNetGetNetworkInformation OVR_UNDEFINED +#define WNetGetLastError OVR_UNDEFINED +#define MultinetGetConnectionPerformance OVR_UNDEFINED +#define GetCPInfoEx OVR_UNDEFINED +#define CompareString OVR_UNDEFINED +#define LCMapString OVR_UNDEFINED +#define GetLocaleInfo OVR_UNDEFINED +#define SetLocaleInfo OVR_UNDEFINED +#define GetCalendarInfo OVR_UNDEFINED +#define SetCalendarInfo OVR_UNDEFINED +#define GetNumberFormat OVR_UNDEFINED +#define GetCurrencyFormat OVR_UNDEFINED +#define EnumCalendarInfo OVR_UNDEFINED +#define EnumCalendarInfoEx OVR_UNDEFINED +#define EnumTimeFormats OVR_UNDEFINED +#define EnumDateFormats OVR_UNDEFINED +#define EnumDateFormatsEx OVR_UNDEFINED +#define GetGeoInfo OVR_UNDEFINED +#define GetStringTypeEx OVR_UNDEFINED +#define GetStringType OVR_UNDEFINED +#define FoldString OVR_UNDEFINED +#define EnumSystemLocales OVR_UNDEFINED +#define EnumSystemLanguageGroups OVR_UNDEFINED +#define EnumLanguageGroupLocales OVR_UNDEFINED +#define EnumUILanguages OVR_UNDEFINED +#define EnumSystemCodePages OVR_UNDEFINED +#define IMPGetIME OVR_UNDEFINED +#define IMPQueryIME OVR_UNDEFINED +#define IMPSetIME OVR_UNDEFINED +#define RegCreateKeyEx OVR_UNDEFINED +#define RegDeleteKeyEx OVR_UNDEFINED +#define RegDeleteValue OVR_UNDEFINED +#define RegEnumKeyEx OVR_UNDEFINED +#define RegEnumValue OVR_UNDEFINED +#define RegLoadKey OVR_UNDEFINED +#define RegOpenKeyEx OVR_UNDEFINED +#define RegQueryInfoKey OVR_UNDEFINED +#define RegQueryValueEx OVR_UNDEFINED +#define RegRestoreKey OVR_UNDEFINED +#define RegSetValueEx OVR_UNDEFINED +#define RegUnLoadKey OVR_UNDEFINED +#define RegDeleteKeyValue OVR_UNDEFINED +#define RegSetKeyValue OVR_UNDEFINED +#define RegDeleteTree OVR_UNDEFINED +#define RegGetValue OVR_UNDEFINED +#define RegLoadMUIString OVR_UNDEFINED +#define RegLoadAppKey OVR_UNDEFINED +#define InitiateSystemShutdown OVR_UNDEFINED +#define AbortSystemShutdown OVR_UNDEFINED +#define InitiateSystemShutdownEx OVR_UNDEFINED +#define InitiateShutdown OVR_UNDEFINED +#define RegSaveKeyEx OVR_UNDEFINED +#define SCardListReaderGroups OVR_UNDEFINED +#define SCardListReaders OVR_UNDEFINED +#define SCardListCards OVR_UNDEFINED +#define SCardListInterfaces OVR_UNDEFINED +#define SCardGetProviderId OVR_UNDEFINED +#define SCardGetCardTypeProviderName OVR_UNDEFINED +#define SCardIntroduceReaderGroup OVR_UNDEFINED +#define SCardForgetReaderGroup OVR_UNDEFINED +#define SCardIntroduceReader OVR_UNDEFINED +#define SCardForgetReader OVR_UNDEFINED +#define SCardAddReaderToGroup OVR_UNDEFINED +#define SCardRemoveReaderFromGroup OVR_UNDEFINED +#define SCardIntroduceCardType OVR_UNDEFINED +#define SCardSetCardTypeProviderName OVR_UNDEFINED +#define SCardForgetCardType OVR_UNDEFINED +#define SCardLocateCards OVR_UNDEFINED +#define SCardLocateCardsByATR OVR_UNDEFINED +#define SCardGetStatusChange OVR_UNDEFINED +#define SCardConnect OVR_UNDEFINED +#define SCardStatus OVR_UNDEFINED +#define SCardUIDlgSelectCard OVR_UNDEFINED +#define GetOpenCardName OVR_UNDEFINED +#define SCardReadCache OVR_UNDEFINED +#define SCardWriteCache OVR_UNDEFINED +#define SCardGetReaderIcon OVR_UNDEFINED +#define SCardGetDeviceTypeId OVR_UNDEFINED +#define SCardGetReaderDeviceInstanceId OVR_UNDEFINED +#define SCardListReadersWithDeviceInstanceId OVR_UNDEFINED +#define WSAConnectByName OVR_UNDEFINED +#define WSADuplicateSocket OVR_UNDEFINED +#define WSAEnumProtocols OVR_UNDEFINED +#define WSASocket OVR_UNDEFINED +#define WSAAddressToString OVR_UNDEFINED +#define WSAStringToAddress OVR_UNDEFINED +#define WSALookupServiceBegin OVR_UNDEFINED +#define WSALookupServiceNext OVR_UNDEFINED +#define WSAInstallServiceClass OVR_UNDEFINED +#define WSAGetServiceClassInfo OVR_UNDEFINED +#define WSAEnumNameSpaceProviders OVR_UNDEFINED +#define WSAEnumNameSpaceProvidersEx OVR_UNDEFINED +#define WSAGetServiceClassNameByClassId OVR_UNDEFINED +#define WSASetService OVR_UNDEFINED +#define EnumPrinters OVR_UNDEFINED +#define OpenPrinter OVR_UNDEFINED +#define ResetPrinter OVR_UNDEFINED +#define SetJob OVR_UNDEFINED +#define GetJob OVR_UNDEFINED +#define EnumJobs OVR_UNDEFINED +#define AddPrinter OVR_UNDEFINED +#define SetPrinter OVR_UNDEFINED +#define GetPrinter OVR_UNDEFINED +#define AddPrinterDriver OVR_UNDEFINED +#define AddPrinterDriverEx OVR_UNDEFINED +#define EnumPrinterDrivers OVR_UNDEFINED +#define GetPrinterDriver OVR_UNDEFINED +#define GetPrinterDriverDirectory OVR_UNDEFINED +#define DeletePrinterDriver OVR_UNDEFINED +#define DeletePrinterDriverEx OVR_UNDEFINED +#define AddPrintProcessor OVR_UNDEFINED +#define EnumPrintProcessors OVR_UNDEFINED +#define GetPrintProcessorDirectory OVR_UNDEFINED +#define EnumPrintProcessorDatatypes OVR_UNDEFINED +#define DeletePrintProcessor OVR_UNDEFINED +#define StartDocPrinter OVR_UNDEFINED +#define AddJob OVR_UNDEFINED +#define DocumentProperties OVR_UNDEFINED +#define AdvancedDocumentProperties OVR_UNDEFINED +#define GetPrinterData OVR_UNDEFINED +#define GetPrinterDataEx OVR_UNDEFINED +#define EnumPrinterData OVR_UNDEFINED +#define EnumPrinterDataEx OVR_UNDEFINED +#define EnumPrinterKey OVR_UNDEFINED +#define SetPrinterData OVR_UNDEFINED +#define SetPrinterDataEx OVR_UNDEFINED +#define DeletePrinterData OVR_UNDEFINED +#define DeletePrinterDataEx OVR_UNDEFINED +#define DeletePrinterKey OVR_UNDEFINED +#define PrinterMessageBox OVR_UNDEFINED +#define AddForm OVR_UNDEFINED +#define DeleteForm OVR_UNDEFINED +#define GetForm OVR_UNDEFINED +#define SetForm OVR_UNDEFINED +#define EnumForms OVR_UNDEFINED +#define EnumMonitors OVR_UNDEFINED +#define AddMonitor OVR_UNDEFINED +#define DeleteMonitor OVR_UNDEFINED +#define EnumPorts OVR_UNDEFINED +#define AddPort OVR_UNDEFINED +#define ConfigurePort OVR_UNDEFINED +#define DeletePort OVR_UNDEFINED +#define GetDefaultPrinter OVR_UNDEFINED +#define SetDefaultPrinter OVR_UNDEFINED +#define SetPort OVR_UNDEFINED +#define AddPrinterConnection OVR_UNDEFINED +#define DeletePrinterConnection OVR_UNDEFINED +#define AddPrintProvidor OVR_UNDEFINED +#define DeletePrintProvidor OVR_UNDEFINED +#define IsValidDevmode OVR_UNDEFINED +#define OpenPrinter2 OVR_UNDEFINED +#define AddPrinterConnection2 OVR_UNDEFINED +#define InstallPrinterDriverFromPackage OVR_UNDEFINED +#define UploadPrinterDriverPackage OVR_UNDEFINED +#define GetCorePrinterDrivers OVR_UNDEFINED +#define CorePrinterDriverInstalled OVR_UNDEFINED +#define GetPrinterDriverPackagePath OVR_UNDEFINED +#define DeletePrinterDriverPackage OVR_UNDEFINED +#define GetPrinterDriver2 OVR_UNDEFINED +#define ChangeServiceConfig OVR_UNDEFINED +#define ChangeServiceConfig2 OVR_UNDEFINED +#define CreateService OVR_UNDEFINED +#define EnumDependentServices OVR_UNDEFINED +#define EnumServicesStatus OVR_UNDEFINED +#define EnumServicesStatusEx OVR_UNDEFINED +#define GetServiceKeyName OVR_UNDEFINED +#define GetServiceDisplayName OVR_UNDEFINED +#define OpenSCManager OVR_UNDEFINED +#define OpenService OVR_UNDEFINED +#define QueryServiceConfig OVR_UNDEFINED +#define QueryServiceConfig2 OVR_UNDEFINED +#define QueryServiceLockStatus OVR_UNDEFINED +#define RegisterServiceCtrlHandler OVR_UNDEFINED +#define RegisterServiceCtrlHandlerEx OVR_UNDEFINED +#define StartServiceCtrlDispatcher OVR_UNDEFINED +#define StartService OVR_UNDEFINED +#define ControlServiceEx OVR_UNDEFINED +#define wvsprintf OVR_UNDEFINED +#define wsprintf OVR_UNDEFINED +#define LoadKeyboardLayout OVR_UNDEFINED +#define GetKeyboardLayoutName OVR_UNDEFINED +#define CreateDesktop OVR_UNDEFINED +#define CreateDesktopEx OVR_UNDEFINED +#define OpenDesktop OVR_UNDEFINED +#define EnumDesktops OVR_UNDEFINED +#define CreateWindowStation OVR_UNDEFINED +#define OpenWindowStation OVR_UNDEFINED +#define EnumWindowStations OVR_UNDEFINED +#define GetUserObjectInformation OVR_UNDEFINED +#define SetUserObjectInformation OVR_UNDEFINED +#define RegisterWindowMessage OVR_UNDEFINED +#define GetMessage OVR_UNDEFINED +#define DispatchMessage OVR_UNDEFINED +#define PeekMessage OVR_UNDEFINED +#define SendMessage OVR_UNDEFINED +#define SendMessageTimeout OVR_UNDEFINED +#define SendNotifyMessage OVR_UNDEFINED +#define SendMessageCallback OVR_UNDEFINED +#define BroadcastSystemMessageEx OVR_UNDEFINED +#define BroadcastSystemMessage OVR_UNDEFINED +#define RegisterDeviceNotification OVR_UNDEFINED +#define PostMessage OVR_UNDEFINED +#define PostThreadMessage OVR_UNDEFINED +#define DefWindowProc OVR_UNDEFINED +#define CallWindowProc OVR_UNDEFINED +#define CallWindowProc OVR_UNDEFINED +#define RegisterClass OVR_UNDEFINED +#define UnregisterClass OVR_UNDEFINED +#define GetClassInfo OVR_UNDEFINED +#define RegisterClassEx OVR_UNDEFINED +#define GetClassInfoEx OVR_UNDEFINED +#define CreateWindowEx OVR_UNDEFINED +#define CreateDialogParam OVR_UNDEFINED +#define CreateDialogIndirectParam OVR_UNDEFINED +#define DialogBoxParam OVR_UNDEFINED +#define DialogBoxIndirectParam OVR_UNDEFINED +#define SetDlgItemText OVR_UNDEFINED +#define GetDlgItemText OVR_UNDEFINED +#define SendDlgItemMessage OVR_UNDEFINED +#define DefDlgProc OVR_UNDEFINED +#define CallMsgFilter OVR_UNDEFINED +#define RegisterClipboardFormat OVR_UNDEFINED +#define GetClipboardFormatName OVR_UNDEFINED +#define CharToOem OVR_UNDEFINED +#define OemToChar OVR_UNDEFINED +#define CharToOemBuff OVR_UNDEFINED +#define OemToCharBuff OVR_UNDEFINED +#define CharUpper OVR_UNDEFINED +#define CharUpperBuff OVR_UNDEFINED +#define CharLower OVR_UNDEFINED +#define CharLowerBuff OVR_UNDEFINED +#define CharNext OVR_UNDEFINED +#define CharPrev OVR_UNDEFINED +#define CharNextEx OVR_UNDEFINED +#define CharPrevEx OVR_UNDEFINED +#define IsCharAlpha OVR_UNDEFINED +#define IsCharAlphaNumeric OVR_UNDEFINED +#define IsCharUpper OVR_UNDEFINED +#define IsCharLower OVR_UNDEFINED +#define GetKeyNameText OVR_UNDEFINED +#define VkKeyScan OVR_UNDEFINED +#define VkKeyScanEx OVR_UNDEFINED +#define MapVirtualKey OVR_UNDEFINED +#define MapVirtualKeyEx OVR_UNDEFINED +#define LoadAccelerators OVR_UNDEFINED +#define CreateAcceleratorTable OVR_UNDEFINED +#define CopyAcceleratorTable OVR_UNDEFINED +#define TranslateAccelerator OVR_UNDEFINED +#define LoadMenu OVR_UNDEFINED +#define LoadMenuIndirect OVR_UNDEFINED +#define ChangeMenu OVR_UNDEFINED +#define GetMenuString OVR_UNDEFINED +#define InsertMenu OVR_UNDEFINED +#define AppendMenu OVR_UNDEFINED +#define ModifyMenu OVR_UNDEFINED +#define InsertMenuItem OVR_UNDEFINED +#define GetMenuItemInfo OVR_UNDEFINED +#define SetMenuItemInfo OVR_UNDEFINED +#define DrawText OVR_UNDEFINED +#define DrawTextEx OVR_UNDEFINED +#define GrayString OVR_UNDEFINED +#define DrawState OVR_UNDEFINED +#define TabbedTextOut OVR_UNDEFINED +#define GetTabbedTextExtent OVR_UNDEFINED +#define SetProp OVR_UNDEFINED +#define GetProp OVR_UNDEFINED +#define RemoveProp OVR_UNDEFINED +#define EnumPropsEx OVR_UNDEFINED +#define EnumProps OVR_UNDEFINED +#define SetWindowText OVR_UNDEFINED +#define GetWindowText OVR_UNDEFINED +#define GetWindowTextLength OVR_UNDEFINED +#define MessageBox OVR_UNDEFINED +#define MessageBoxEx OVR_UNDEFINED +#define MessageBoxIndirect OVR_UNDEFINED +#define GetWindowLong OVR_UNDEFINED +#define SetWindowLong OVR_UNDEFINED +#define GetWindowLongPtr OVR_UNDEFINED +#define SetWindowLongPtr OVR_UNDEFINED +#define GetClassLong OVR_UNDEFINED +#define SetClassLong OVR_UNDEFINED +#define GetClassLongPtr OVR_UNDEFINED +#define SetClassLongPtr OVR_UNDEFINED +#define FindWindow OVR_UNDEFINED +#define FindWindowEx OVR_UNDEFINED +#define GetClassName OVR_UNDEFINED +#define SetWindowsHook OVR_UNDEFINED +#define SetWindowsHook OVR_UNDEFINED +#define SetWindowsHookEx OVR_UNDEFINED +#define LoadBitmap OVR_UNDEFINED +#define LoadCursor OVR_UNDEFINED +#define LoadCursorFromFile OVR_UNDEFINED +#define LoadIcon OVR_UNDEFINED +#define PrivateExtractIcons OVR_UNDEFINED +#define LoadImage OVR_UNDEFINED +#define GetIconInfoEx OVR_UNDEFINED +#define LoadString OVR_UNDEFINED +#define IsDialogMessage OVR_UNDEFINED +#define DlgDirList OVR_UNDEFINED +#define DlgDirSelectEx OVR_UNDEFINED +#define DlgDirListComboBox OVR_UNDEFINED +#define DlgDirSelectComboBoxEx OVR_UNDEFINED +#define DefFrameProc OVR_UNDEFINED +#define DefMDIChildProc OVR_UNDEFINED +#define CreateMDIWindow OVR_UNDEFINED +#define WinHelp OVR_UNDEFINED +#define ChangeDisplaySettings OVR_UNDEFINED +#define ChangeDisplaySettingsEx OVR_UNDEFINED +#define EnumDisplaySettings OVR_UNDEFINED +#define EnumDisplaySettingsEx OVR_UNDEFINED +#define EnumDisplayDevices OVR_UNDEFINED +#define SystemParametersInfo OVR_UNDEFINED +#define GetMonitorInfo OVR_UNDEFINED +#define GetWindowModuleFileName OVR_UNDEFINED +#define RealGetWindowClass OVR_UNDEFINED +#define GetAltTabInfo OVR_UNDEFINED +#define GetRawInputDeviceInfo OVR_UNDEFINED +#define VerFindFile OVR_UNDEFINED +#define VerInstallFile OVR_UNDEFINED +#define GetFileVersionInfoSize OVR_UNDEFINED +#define GetFileVersionInfo OVR_UNDEFINED +#define GetFileVersionInfoSizeEx OVR_UNDEFINED +#define GetFileVersionInfoEx OVR_UNDEFINED +#define VerLanguageName OVR_UNDEFINED +#define VerQueryValue OVR_UNDEFINED +#define WmiQueryAllData OVR_UNDEFINED +#define WmiQueryAllDataMultiple OVR_UNDEFINED +#define WmiQuerySingleInstance OVR_UNDEFINED +#define WmiQuerySingleInstanceMultiple OVR_UNDEFINED +#define WmiSetSingleInstance OVR_UNDEFINED +#define WmiSetSingleItem OVR_UNDEFINED +#define WmiExecuteMethod OVR_UNDEFINED +#define WmiNotificationRegistration OVR_UNDEFINED +#define WmiMofEnumerateResources OVR_UNDEFINED +#define WmiFileHandleToInstanceName OVR_UNDEFINED +#define WmiDevInstToInstanceName OVR_UNDEFINED +#define WmiReceiveNotifications OVR_UNDEFINED +#define GetSystemWow64Directory OVR_UNDEFINED +#define GetSystemWow64Directory2 OVR_UNDEFINED +#define GetAddrInfoEx OVR_UNDEFINED +#define SetAddrInfoEx OVR_UNDEFINED +#define gai_strerror OVR_UNDEFINED +#define WTSStartRemoteControlSession OVR_UNDEFINED +#define WTSConnectSession OVR_UNDEFINED +#define WTSEnumerateServers OVR_UNDEFINED +#define WTSOpenServer OVR_UNDEFINED +#define WTSOpenServerEx OVR_UNDEFINED +#define WTSEnumerateSessions OVR_UNDEFINED +#define WTSEnumerateSessionsEx OVR_UNDEFINED +#define WTSEnumerateProcesses OVR_UNDEFINED +#define WTSQuerySessionInformation OVR_UNDEFINED +#define WTSQueryUserConfig OVR_UNDEFINED +#define WTSSetUserConfig OVR_UNDEFINED +#define WTSSendMessage OVR_UNDEFINED +#define WTSFreeMemoryEx OVR_UNDEFINED +#define WTSSetListenerSecurity OVR_UNDEFINED +#define WTSGetListenerSecurity OVR_UNDEFINED +#define DtcGetTransactionManagerEx OVR_UNDEFINED +#define WriteConsoleOutput OVR_UNDEFINED +#define WriteConsoleOutputCharacter OVR_UNDEFINED +#define FillConsoleOutputCharacter OVR_UNDEFINED +#define ScrollConsoleScreenBuffer OVR_UNDEFINED +#define WriteConsoleInput OVR_UNDEFINED +#define ReadConsoleOutput OVR_UNDEFINED +#define ReadConsoleOutputCharacter OVR_UNDEFINED +#define CreateHardLink OVR_UNDEFINED +#define CreateProcessInternal OVR_UNDEFINED +#define DosPathToSessionPath OVR_UNDEFINED diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.h new file mode 100644 index 0000000..c14aaee --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.h @@ -0,0 +1,3327 @@ +//**********************************************************************` +//* This is an include file generated by Message Compiler. *` +//* *` +//* Copyright (c) Microsoft Corporation. All Rights Reserved. *` +//**********************************************************************` +#pragma once +#include +#include +#include "evntprov.h" +// +// Initial Defs +// +#if !defined(ETW_INLINE) +#define ETW_INLINE DECLSPEC_NOINLINE __inline +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +// +// Allow disabling of code generation +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION +#if !defined(McGenDebug) +#define McGenDebug(a, b) +#endif + +#if !defined(MCGEN_TRACE_CONTEXT_DEF) +#define MCGEN_TRACE_CONTEXT_DEF +typedef struct _MCGEN_TRACE_CONTEXT { + TRACEHANDLE RegistrationHandle; + TRACEHANDLE Logger; + ULONGLONG MatchAnyKeyword; + ULONGLONG MatchAllKeyword; + ULONG Flags; + ULONG IsEnabled; + UCHAR Level; + UCHAR Reserve; + USHORT EnableBitsCount; + PULONG EnableBitMask; + const ULONGLONG* EnableKeyWords; + const UCHAR* EnableLevel; +} MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT; +#endif + +#if !defined(MCGEN_LEVEL_KEYWORD_ENABLED_DEF) +#define MCGEN_LEVEL_KEYWORD_ENABLED_DEF +FORCEINLINE +BOOLEAN +McGenLevelKeywordEnabled( + _In_ PMCGEN_TRACE_CONTEXT EnableInfo, + _In_ UCHAR Level, + _In_ ULONGLONG Keyword) { + // + // Check if the event Level is lower than the level at which + // the channel is enabled. + // If the event Level is 0 or the channel is enabled at level 0, + // all levels are enabled. + // + + if ((Level <= EnableInfo->Level) || // This also covers the case of Level == 0. + (EnableInfo->Level == 0)) { + // + // Check if Keyword is enabled + // + + if ((Keyword == (ULONGLONG)0) || + ((Keyword & EnableInfo->MatchAnyKeyword) && + ((Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) { + return TRUE; + } + } + + return FALSE; +} +#endif + +#if !defined(MCGEN_EVENT_ENABLED_DEF) +#define MCGEN_EVENT_ENABLED_DEF +FORCEINLINE +BOOLEAN +McGenEventEnabled(_In_ PMCGEN_TRACE_CONTEXT EnableInfo, _In_ PCEVENT_DESCRIPTOR EventDescriptor) { + return McGenLevelKeywordEnabled(EnableInfo, EventDescriptor->Level, EventDescriptor->Keyword); +} +#endif + +// +// EnableCheckMacro +// +#ifndef MCGEN_ENABLE_CHECK +#define MCGEN_ENABLE_CHECK(Context, Descriptor) \ + (Context.IsEnabled && McGenEventEnabled(&Context, &Descriptor)) +#endif + +#if !defined(MCGEN_CONTROL_CALLBACK) +#define MCGEN_CONTROL_CALLBACK + +DECLSPEC_NOINLINE __inline VOID __stdcall McGenControlCallbackV2( + _In_ LPCGUID SourceId, + _In_ ULONG ControlCode, + _In_ UCHAR Level, + _In_ ULONGLONG MatchAnyKeyword, + _In_ ULONGLONG MatchAllKeyword, + _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, + _Inout_opt_ PVOID CallbackContext) +/*++ + +Routine Description: + + This is the notification callback for Windows Vista and later. + +Arguments: + + SourceId - The GUID that identifies the session that enabled the provider. + + ControlCode - The parameter indicates whether the provider + is being enabled or disabled. + + Level - The level at which the event is enabled. + + MatchAnyKeyword - The bitmask of keywords that the provider uses to + determine the category of events that it writes. + + MatchAllKeyword - This bitmask additionally restricts the category + of events that the provider writes. + + FilterData - The provider-defined data. + + CallbackContext - The context of the callback that is defined when the provider + called EtwRegister to register itself. + +Remarks: + + ETW calls this function to notify provider of enable/disable + +--*/ +{ + PMCGEN_TRACE_CONTEXT Ctx = (PMCGEN_TRACE_CONTEXT)CallbackContext; + ULONG Ix; +#ifndef MCGEN_PRIVATE_ENABLE_CALLBACK_V2 + UNREFERENCED_PARAMETER(SourceId); + UNREFERENCED_PARAMETER(FilterData); +#endif + + if (Ctx == NULL) { + return; + } + + switch (ControlCode) { + case EVENT_CONTROL_CODE_ENABLE_PROVIDER: + Ctx->Level = Level; + Ctx->MatchAnyKeyword = MatchAnyKeyword; + Ctx->MatchAllKeyword = MatchAllKeyword; + Ctx->IsEnabled = EVENT_CONTROL_CODE_ENABLE_PROVIDER; + + for (Ix = 0; Ix < Ctx->EnableBitsCount; Ix += 1) { + if (McGenLevelKeywordEnabled(Ctx, Ctx->EnableLevel[Ix], Ctx->EnableKeyWords[Ix]) != FALSE) { + Ctx->EnableBitMask[Ix >> 5] |= (1 << (Ix % 32)); + } else { + Ctx->EnableBitMask[Ix >> 5] &= ~(1 << (Ix % 32)); + } + } + break; + + case EVENT_CONTROL_CODE_DISABLE_PROVIDER: + Ctx->IsEnabled = EVENT_CONTROL_CODE_DISABLE_PROVIDER; + Ctx->Level = 0; + Ctx->MatchAnyKeyword = 0; + Ctx->MatchAllKeyword = 0; + if (Ctx->EnableBitsCount > 0) { + RtlZeroMemory(Ctx->EnableBitMask, (((Ctx->EnableBitsCount - 1) / 32) + 1) * sizeof(ULONG)); + } + break; + + default: + break; + } + +#ifdef MCGEN_PRIVATE_ENABLE_CALLBACK_V2 + // + // Call user defined callback + // + MCGEN_PRIVATE_ENABLE_CALLBACK_V2( + SourceId, ControlCode, Level, MatchAnyKeyword, MatchAllKeyword, FilterData, CallbackContext); +#endif + + return; +} + +#endif +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION +//+ +// Provider OVR-SDK-LibOVR Event Count 61 +//+ +EXTERN_C __declspec(selectany) const GUID + LibOVRProvider = {0x553787fc, 0xd3d7, 0x4f5e, {0xac, 0xb2, 0x15, 0x97, 0xc7, 0x20, 0x9b, 0x3c}}; + +// +// Channel +// +#define DEBUG_CHANNEL 0x10 +#define ANALYTIC_CHANNEL 0x11 +#define ERROR_CHANNEL 0x12 + +// +// Opcodes +// +#define FN_CALL 0xa +#define FN_RETURN 0xb +#define FN_WAYPOINT 0xc +#define DIS_BEGIN 0xd +#define DIS_WAITGPU 0xe +#define DIS_PRESENT 0xf +#define DIS_END 0x10 +#define HMD_DESC 0x11 +#define CAM_RECEIVE 0x12 +#define CAM_REQUEST 0x13 + +// +// Tasks +// +#define FN_TRACE 0x1 +#define DIS_TRACE 0x2 +#define HMD_TRACE 0x3 +#define CAMERA_TRACE 0x4 +#define LOG_TRACE 0x5 +#define SUBMITFRAME_TRACE 0x6 +#define PHASESYNC_TRACE 0x7 +#define SENSOR_TRACE 0x8 +#define VIRTUALDISPLAY_TRACE 0x9 +#define COMPOSITOR_RUNLOOP_TRACE 0xa +#define NOTIFICATION_TRACE 0xb + +// +// Event Descriptors +// +EXTERN_C __declspec(selectany) const + EVENT_DESCRIPTOR Call = {0x0, 0x0, 0x11, 0x4, 0xa, 0x1, 0x4000000000000000}; +#define Call_value 0x0 +EXTERN_C __declspec(selectany) const + EVENT_DESCRIPTOR Return = {0x1, 0x0, 0x11, 0x4, 0xb, 0x1, 0x4000000000000000}; +#define Return_value 0x1 +EXTERN_C __declspec(selectany) const + EVENT_DESCRIPTOR Waypoint = {0x2, 0x0, 0x10, 0x4, 0xc, 0x1, 0x8000000000000000}; +#define Waypoint_value 0x2 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + DistortionBegin = {0x4, 0x0, 0x11, 0x4, 0xd, 0x2, 0x4000000000000000}; +#define DistortionBegin_value 0x4 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + DistortionWaitGPU = {0x5, 0x0, 0x11, 0x4, 0xe, 0x2, 0x4000000000000000}; +#define DistortionWaitGPU_value 0x5 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + DistortionPresent = {0x6, 0x0, 0x11, 0x4, 0xf, 0x2, 0x4000000000000000}; +#define DistortionPresent_value 0x6 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + DistortionEnd = {0x7, 0x0, 0x11, 0x4, 0x10, 0x2, 0x4000000000000000}; +#define DistortionEnd_value 0x7 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + HmdDesc_v0 = {0x8, 0x0, 0x11, 0x4, 0x11, 0x3, 0x4000000000000000}; +#define HmdDesc_v0_value 0x8 +EXTERN_C __declspec(selectany) const + EVENT_DESCRIPTOR HmdDesc = {0x8, 0x1, 0x11, 0x4, 0x11, 0x3, 0x4000000000000000}; +#define HmdDesc_value 0x8 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraFrameReceived_v0 = {0x9, 0x0, 0x11, 0x4, 0x12, 0x4, 0x4000000000000000}; +#define CameraFrameReceived_v0_value 0x9 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraFrameReceived = {0x9, 0x1, 0x11, 0x4, 0x12, 0x4, 0x4000000000000000}; +#define CameraFrameReceived_value 0x9 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraBeginProcessing_v0 = {0xa, 0x0, 0x11, 0x4, 0xd, 0x4, 0x4000000000000000}; +#define CameraBeginProcessing_v0_value 0xa +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraBeginProcessing = {0xa, 0x1, 0x11, 0x4, 0xd, 0x4, 0x4000000000000000}; +#define CameraBeginProcessing_value 0xa +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraFrameRequest = {0xb, 0x0, 0x11, 0x4, 0x13, 0x4, 0x4000000000000000}; +#define CameraFrameRequest_value 0xb +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraEndProcessing_v0 = {0xc, 0x0, 0x11, 0x4, 0x10, 0x4, 0x4000000000000000}; +#define CameraEndProcessing_v0_value 0xc +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraEndProcessing = {0xc, 0x1, 0x11, 0x4, 0x10, 0x4, 0x4000000000000000}; +#define CameraEndProcessing_value 0xc +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraSkippedFrames_v0 = {0xd, 0x0, 0x11, 0x4, 0xc, 0x4, 0x4000000000000000}; +#define CameraSkippedFrames_v0_value 0xd +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraSkippedFrames = {0xd, 0x1, 0x11, 0x4, 0xc, 0x4, 0x4000000000000000}; +#define CameraSkippedFrames_value 0xd +EXTERN_C __declspec(selectany) const + EVENT_DESCRIPTOR JSONChunk = {0xe, 0x0, 0x11, 0x4, 0xc, 0x3, 0x4000000000000000}; +#define JSONChunk_value 0xe +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + LogDebugMessage = {0xf, 0x0, 0x10, 0x5, 0xc, 0x5, 0x8000000000000000}; +#define LogDebugMessage_value 0xf +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + LogInfoMessage = {0x10, 0x0, 0x11, 0x4, 0xc, 0x5, 0x4000000000000000}; +#define LogInfoMessage_value 0x10 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + LogErrorMessage = {0x11, 0x0, 0x12, 0x2, 0xc, 0x5, 0x2000000000000000}; +#define LogErrorMessage_value 0x11 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + HmdTrackingState = {0x12, 0x0, 0x11, 0x4, 0xc, 0x3, 0x4000000000000000}; +#define HmdTrackingState_value 0x12 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraBlobs_v0 = {0x13, 0x0, 0x11, 0x4, 0xc, 0x4, 0x4000000000000000}; +#define CameraBlobs_v0_value 0x13 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CameraBlobs = {0x13, 0x1, 0x11, 0x4, 0xc, 0x4, 0x4000000000000000}; +#define CameraBlobs_value 0x13 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + PoseLatchCPUWrite = {0x1e, 0x0, 0x11, 0x4, 0xd, 0x2, 0x4000000000000000}; +#define PoseLatchCPUWrite_value 0x1e +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + PoseLatchGPULatchReadback = {0x1f, 0x0, 0x11, 0x4, 0x10, 0x2, 0x4000000000000000}; +#define PoseLatchGPULatchReadback_value 0x1f +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + QueueAheadDelayBegin = {0x20, 0x0, 0x11, 0x4, 0xd, 0x6, 0x4000000000000000}; +#define QueueAheadDelayBegin_value 0x20 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + QueueAheadDelayEnd = {0x21, 0x0, 0x11, 0x4, 0x10, 0x6, 0x4000000000000000}; +#define QueueAheadDelayEnd_value 0x21 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + HmdDisplay = {0x22, 0x0, 0x11, 0x4, 0x11, 0x3, 0x4000000000000000}; +#define HmdDisplay_value 0x22 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + PhaseSyncBegin = {0x23, 0x0, 0x11, 0x4, 0xd, 0x7, 0x4000000000000000}; +#define PhaseSyncBegin_value 0x23 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + PhaseSyncEnd = {0x24, 0x0, 0x11, 0x4, 0x10, 0x7, 0x4000000000000000}; +#define PhaseSyncEnd_value 0x24 +EXTERN_C __declspec(selectany) const + EVENT_DESCRIPTOR VSync = {0x25, 0x0, 0x11, 0x4, 0xf, 0x2, 0x4000000000000000}; +#define VSync_value 0x25 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + AppCompositorFocus = {0x26, 0x0, 0x11, 0x4, 0xc, 0x5, 0x4000000000000000}; +#define AppCompositorFocus_value 0x26 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + AppConnect = {0x27, 0x0, 0x11, 0x4, 0xc, 0x5, 0x4000000000000000}; +#define AppConnect_value 0x27 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + AppDisconnect = {0x28, 0x0, 0x11, 0x4, 0xc, 0x5, 0x4000000000000000}; +#define AppDisconnect_value 0x28 +EXTERN_C __declspec(selectany) const + EVENT_DESCRIPTOR AppNoOp = {0x29, 0x0, 0x11, 0x4, 0xc, 0x5, 0x4000000000000000}; +#define AppNoOp_value 0x29 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + PosePrediction = {0x2a, 0x0, 0x11, 0x4, 0xd, 0x8, 0x4000000000000000}; +#define PosePrediction_value 0x2a +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + LatencyTiming = {0x2b, 0x0, 0x11, 0x4, 0xc, 0x5, 0x4000000000000000}; +#define LatencyTiming_value 0x2b +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + EndFrameAppTiming = {0x2c, 0x0, 0x11, 0x4, 0xc, 0x5, 0x4000000000000000}; +#define EndFrameAppTiming_value 0x2c +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + HardwareInfo = {0x2d, 0x0, 0x11, 0x4, 0xc, 0x3, 0x4000000000000000}; +#define HardwareInfo_value 0x2d +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + VirtualDisplayPacketTrace = {0x2e, 0x0, 0x11, 0x4, 0xc, 0x9, 0x4000000000000000}; +#define VirtualDisplayPacketTrace_value 0x2e +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + ClientFrameMissed = {0x2f, 0x0, 0x11, 0x4, 0xc, 0x9, 0x4000000000000000}; +#define ClientFrameMissed_value 0x2f +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CompositionBegin = {0x30, 0x0, 0x11, 0x4, 0xd, 0xa, 0x4000000000000000}; +#define CompositionBegin_value 0x30 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CompositionEnd = {0x31, 0x0, 0x11, 0x4, 0x10, 0xa, 0x4000000000000000}; +#define CompositionEnd_value 0x31 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + RenderPacketTrace = {0x32, 0x0, 0x11, 0x4, 0xc, 0x9, 0x4000000000000000}; +#define RenderPacketTrace_value 0x32 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + EndFrameOrigAppTiming = {0x33, 0x0, 0x11, 0x4, 0xd, 0x5, 0x4000000000000000}; +#define EndFrameOrigAppTiming_value 0x33 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + DistortionEndToEndTiming = {0x34, 0x0, 0x11, 0x0, 0xa, 0xa, 0x4000000000000000}; +#define DistortionEndToEndTiming_value 0x34 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CompositionEndSpinWait = {0x35, 0x0, 0x11, 0x4, 0x10, 0xa, 0x4000000000000000}; +#define CompositionEndSpinWait_value 0x35 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CompositionFlushingToGPU = {0x36, 0x0, 0x11, 0x4, 0xc, 0xa, 0x4000000000000000}; +#define CompositionFlushingToGPU_value 0x36 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + PhaseSyncGPUCompleted = {0x37, 0x0, 0x11, 0x4, 0xc, 0x7, 0x4000000000000000}; +#define PhaseSyncGPUCompleted_value 0x37 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CompositionMissedCompositorFrame = {0x38, 0x0, 0x11, 0x4, 0xc, 0xa, 0x4000000000000000}; +#define CompositionMissedCompositorFrame_value 0x38 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + CompositionGPUStartTime = {0x39, 0x0, 0x11, 0x4, 0xc, 0xa, 0x4000000000000000}; +#define CompositionGPUStartTime_value 0x39 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + NotificationBegin = {0x3a, 0x0, 0x11, 0x4, 0xc, 0xb, 0x4000000000000000}; +#define NotificationBegin_value 0x3a +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + NotificationEnd = {0x3b, 0x0, 0x11, 0x4, 0xc, 0xb, 0x4000000000000000}; +#define NotificationEnd_value 0x3b +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + NotificationCompSubmit = {0x3c, 0x0, 0x11, 0x4, 0xc, 0xb, 0x4000000000000000}; +#define NotificationCompSubmit_value 0x3c +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + MotionEstimationCostStats = {0x3d, 0x0, 0x11, 0x4, 0xc, 0xa, 0x4000000000000000}; +#define MotionEstimationCostStats_value 0x3d +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + PhaseSyncWaitToBeginFrame = {0x3e, 0x0, 0x11, 0x4, 0xc, 0x7, 0x4000000000000000}; +#define PhaseSyncWaitToBeginFrame_value 0x3e +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + PhaseSyncBeginFrame = {0x3f, 0x0, 0x11, 0x4, 0xc, 0x7, 0x4000000000000000}; +#define PhaseSyncBeginFrame_value 0x3f +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + PhaseSyncEndFrame = {0x40, 0x0, 0x11, 0x4, 0xc, 0x7, 0x4000000000000000}; +#define PhaseSyncEndFrame_value 0x40 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR + PhaseSyncCompleteFrame = {0x41, 0x0, 0x11, 0x4, 0xc, 0x7, 0x4000000000000000}; +#define PhaseSyncCompleteFrame_value 0x41 + +// +// Note on Generate Code from Manifest for Windows Vista and above +// +// Structures : are handled as a size and pointer pairs. The macro for the event will have an extra +// parameter for the size in bytes of the structure. Make sure that your structures have no extra +// padding. +// +// Strings: There are several cases that can be described in the manifest. For array of variable +// length strings, the generated code will take the count of characters for the whole array as an +// input parameter. +// +// SID No support for array of SIDs, the macro will take a pointer to the SID and use appropriate +// GetLengthSid function to get the length. +// + +// +// Allow disabling of code generation +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// Globals +// + +// +// Event Enablement Bits +// + +EXTERN_C __declspec(selectany) DECLSPEC_CACHEALIGN ULONG OVR_SDK_LibOVREnableBits[1]; +EXTERN_C __declspec(selectany) const ULONGLONG OVR_SDK_LibOVRKeywords[5] = {0x4000000000000000, + 0x8000000000000000, + 0x8000000000000000, + 0x2000000000000000, + 0x4000000000000000}; +EXTERN_C __declspec(selectany) const UCHAR OVR_SDK_LibOVRLevels[5] = {4, 4, 5, 2, 0}; +EXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT LibOVRProvider_Context = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + OVR_SDK_LibOVREnableBits, + OVR_SDK_LibOVRKeywords, + OVR_SDK_LibOVRLevels}; + +EXTERN_C __declspec(selectany) REGHANDLE OVR_SDK_LibOVRHandle = (REGHANDLE)0; + +#if !defined(McGenEventRegisterUnregister) +#define McGenEventRegisterUnregister +#pragma warning(push) +#pragma warning(disable : 6103) +DECLSPEC_NOINLINE __inline ULONG __stdcall McGenEventRegister( + _In_ LPCGUID ProviderId, + _In_opt_ PENABLECALLBACK EnableCallback, + _In_opt_ PVOID CallbackContext, + _Inout_ PREGHANDLE RegHandle) +/*++ + +Routine Description: + + This function registers the provider with ETW USER mode. + +Arguments: + ProviderId - Provider ID to be register with ETW. + + EnableCallback - Callback to be used. + + CallbackContext - Context for this provider. + + RegHandle - Pointer to registration handle. + +Remarks: + + If the handle != NULL will return ERROR_SUCCESS + +--*/ +{ + ULONG Error; + + if (*RegHandle) { + // + // already registered + // + return ERROR_SUCCESS; + } + + Error = EventRegister(ProviderId, EnableCallback, CallbackContext, RegHandle); + + return Error; +} +#pragma warning(pop) + +DECLSPEC_NOINLINE __inline ULONG __stdcall McGenEventUnregister(_Inout_ PREGHANDLE RegHandle) +/*++ + +Routine Description: + + Unregister from ETW USER mode + +Arguments: + RegHandle this is the pointer to the provider context +Remarks: + If provider has not been registered, RegHandle == NULL, + return ERROR_SUCCESS +--*/ +{ + ULONG Error; + + if (!(*RegHandle)) { + // + // Provider has not registerd + // + return ERROR_SUCCESS; + } + + Error = EventUnregister(*RegHandle); + *RegHandle = (REGHANDLE)0; + + return Error; +} +#endif +// +// Register with ETW Vista + +// +#ifndef EventRegisterOVR_SDK_LibOVR +#define EventRegisterOVR_SDK_LibOVR() \ + McGenEventRegister( \ + &LibOVRProvider, McGenControlCallbackV2, &LibOVRProvider_Context, &OVR_SDK_LibOVRHandle) +#endif + +// +// UnRegister with ETW +// +#ifndef EventUnregisterOVR_SDK_LibOVR +#define EventUnregisterOVR_SDK_LibOVR() McGenEventUnregister(&OVR_SDK_LibOVRHandle) +#endif + +// +// Enablement check macro for Call +// + +#define EventEnabledCall() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for Call +// +#define EventWriteCall(Name, Line, FrameID) \ + EventEnabledCall() ? Template_zdq(OVR_SDK_LibOVRHandle, &Call, Name, Line, FrameID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for Return +// + +#define EventEnabledReturn() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for Return +// +#define EventWriteReturn(Name, Line, FrameID) \ + EventEnabledReturn() ? Template_zdq(OVR_SDK_LibOVRHandle, &Return, Name, Line, FrameID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for Waypoint +// + +#define EventEnabledWaypoint() ((OVR_SDK_LibOVREnableBits[0] & 0x00000002) != 0) + +// +// Event Macro for Waypoint +// +#define EventWriteWaypoint(Name, Line, FrameID) \ + EventEnabledWaypoint() ? Template_zdq(OVR_SDK_LibOVRHandle, &Waypoint, Name, Line, FrameID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for DistortionBegin +// + +#define EventEnabledDistortionBegin() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for DistortionBegin +// +#define EventWriteDistortionBegin(VidPnTargetId, FrameID) \ + EventEnabledDistortionBegin() \ + ? Template_qq(OVR_SDK_LibOVRHandle, &DistortionBegin, VidPnTargetId, FrameID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for DistortionWaitGPU +// + +#define EventEnabledDistortionWaitGPU() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for DistortionWaitGPU +// +#define EventWriteDistortionWaitGPU(VidPnTargetId, FrameID) \ + EventEnabledDistortionWaitGPU() \ + ? Template_qq(OVR_SDK_LibOVRHandle, &DistortionWaitGPU, VidPnTargetId, FrameID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for DistortionPresent +// + +#define EventEnabledDistortionPresent() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for DistortionPresent +// +#define EventWriteDistortionPresent(VidPnTargetId, FrameID) \ + EventEnabledDistortionPresent() \ + ? Template_qq(OVR_SDK_LibOVRHandle, &DistortionPresent, VidPnTargetId, FrameID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for DistortionEnd +// + +#define EventEnabledDistortionEnd() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for DistortionEnd +// +#define EventWriteDistortionEnd(VidPnTargetId, FrameID) \ + EventEnabledDistortionEnd() \ + ? Template_qq(OVR_SDK_LibOVRHandle, &DistortionEnd, VidPnTargetId, FrameID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for HmdDesc_v0 +// + +#define EventEnabledHmdDesc_v0() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for HmdDesc_v0 +// +#define EventWriteHmdDesc_v0( \ + Type, \ + VendorId, \ + ProductId, \ + SerialNumber, \ + FirmwareMajor, \ + FirmwareMinor, \ + HmdCaps, \ + TrackingCaps, \ + DistortionCaps, \ + ResolutionWidth, \ + ResolutionHeight) \ + EventEnabledHmdDesc_v0() ? Template_qlls24llqqqdd( \ + OVR_SDK_LibOVRHandle, \ + &HmdDesc_v0, \ + Type, \ + VendorId, \ + ProductId, \ + SerialNumber, \ + FirmwareMajor, \ + FirmwareMinor, \ + HmdCaps, \ + TrackingCaps, \ + DistortionCaps, \ + ResolutionWidth, \ + ResolutionHeight) \ + : ERROR_SUCCESS + +// +// Enablement check macro for HmdDesc +// + +#define EventEnabledHmdDesc() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for HmdDesc +// +#define EventWriteHmdDesc( \ + Type, \ + VendorId, \ + ProductId, \ + SerialNumber, \ + FirmwareMajor, \ + FirmwareMinor, \ + HmdCaps, \ + TrackingCaps, \ + ResolutionWidth, \ + ResolutionHeight) \ + EventEnabledHmdDesc() ? Template_qlls24llqqdd( \ + OVR_SDK_LibOVRHandle, \ + &HmdDesc, \ + Type, \ + VendorId, \ + ProductId, \ + SerialNumber, \ + FirmwareMajor, \ + FirmwareMinor, \ + HmdCaps, \ + TrackingCaps, \ + ResolutionWidth, \ + ResolutionHeight) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraFrameReceived_v0 +// + +#define EventEnabledCameraFrameReceived_v0() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraFrameReceived_v0 +// +#define EventWriteCameraFrameReceived_v0( \ + FrameRate, FrameNumber, ArrivalTimeSeconds, CaptureTime, LostFrames) \ + EventEnabledCameraFrameReceived_v0() ? Template_fqggq( \ + OVR_SDK_LibOVRHandle, \ + &CameraFrameReceived_v0, \ + FrameRate, \ + FrameNumber, \ + ArrivalTimeSeconds, \ + CaptureTime, \ + LostFrames) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraFrameReceived +// + +#define EventEnabledCameraFrameReceived() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraFrameReceived +// +#define EventWriteCameraFrameReceived( \ + Camera, FrameNumber, HmdFrameNumber, ArrivalTime, CaptureTime) \ + EventEnabledCameraFrameReceived() ? Template_qddgg( \ + OVR_SDK_LibOVRHandle, \ + &CameraFrameReceived, \ + Camera, \ + FrameNumber, \ + HmdFrameNumber, \ + ArrivalTime, \ + CaptureTime) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraBeginProcessing_v0 +// + +#define EventEnabledCameraBeginProcessing_v0() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraBeginProcessing_v0 +// +#define EventWriteCameraBeginProcessing_v0( \ + FrameRate, FrameNumber, ArrivalTimeSeconds, CaptureTime, LostFrames) \ + EventEnabledCameraBeginProcessing_v0() ? Template_fqggq( \ + OVR_SDK_LibOVRHandle, \ + &CameraBeginProcessing_v0, \ + FrameRate, \ + FrameNumber, \ + ArrivalTimeSeconds, \ + CaptureTime, \ + LostFrames) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraBeginProcessing +// + +#define EventEnabledCameraBeginProcessing() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraBeginProcessing +// +#define EventWriteCameraBeginProcessing( \ + Camera, FrameNumber, HmdFrameNumber, ArrivalTime, CaptureTime) \ + EventEnabledCameraBeginProcessing() ? Template_qddgg( \ + OVR_SDK_LibOVRHandle, \ + &CameraBeginProcessing, \ + Camera, \ + FrameNumber, \ + HmdFrameNumber, \ + ArrivalTime, \ + CaptureTime) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraFrameRequest +// + +#define EventEnabledCameraFrameRequest() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraFrameRequest +// +#define EventWriteCameraFrameRequest(RequestNumber, FrameCounter, LastFrameNumber) \ + EventEnabledCameraFrameRequest() ? Template_xxq( \ + OVR_SDK_LibOVRHandle, \ + &CameraFrameRequest, \ + RequestNumber, \ + FrameCounter, \ + LastFrameNumber) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraEndProcessing_v0 +// + +#define EventEnabledCameraEndProcessing_v0() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraEndProcessing_v0 +// +#define EventWriteCameraEndProcessing_v0( \ + FrameRate, FrameNumber, ArrivalTimeSeconds, CaptureTime, LostFrames) \ + EventEnabledCameraEndProcessing_v0() ? Template_fqggq( \ + OVR_SDK_LibOVRHandle, \ + &CameraEndProcessing_v0, \ + FrameRate, \ + FrameNumber, \ + ArrivalTimeSeconds, \ + CaptureTime, \ + LostFrames) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraEndProcessing +// + +#define EventEnabledCameraEndProcessing() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraEndProcessing +// +#define EventWriteCameraEndProcessing( \ + Camera, FrameNumber, HmdFrameNumber, ArrivalTime, CaptureTime) \ + EventEnabledCameraEndProcessing() ? Template_qddgg( \ + OVR_SDK_LibOVRHandle, \ + &CameraEndProcessing, \ + Camera, \ + FrameNumber, \ + HmdFrameNumber, \ + ArrivalTime, \ + CaptureTime) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraSkippedFrames_v0 +// + +#define EventEnabledCameraSkippedFrames_v0() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraSkippedFrames_v0 +// +#define EventWriteCameraSkippedFrames_v0(RequestNumber, FrameCounter, LastFrameNumber) \ + EventEnabledCameraSkippedFrames_v0() ? Template_xxq( \ + OVR_SDK_LibOVRHandle, \ + &CameraSkippedFrames_v0, \ + RequestNumber, \ + FrameCounter, \ + LastFrameNumber) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraSkippedFrames +// + +#define EventEnabledCameraSkippedFrames() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraSkippedFrames +// +#define EventWriteCameraSkippedFrames(Camera, LastFrameNumber) \ + EventEnabledCameraSkippedFrames() \ + ? Template_qq(OVR_SDK_LibOVRHandle, &CameraSkippedFrames, Camera, LastFrameNumber) \ + : ERROR_SUCCESS + +// +// Enablement check macro for JSONChunk +// + +#define EventEnabledJSONChunk() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for JSONChunk +// +#define EventWriteJSONChunk( \ + Name, TotalChunks, ChunkSequence, TotalSize, ChunkSize, ChunkOffset, Chunk) \ + EventEnabledJSONChunk() ? Template_zqqqqqb( \ + OVR_SDK_LibOVRHandle, \ + &JSONChunk, \ + Name, \ + TotalChunks, \ + ChunkSequence, \ + TotalSize, \ + ChunkSize, \ + ChunkOffset, \ + Chunk) \ + : ERROR_SUCCESS + +// +// Enablement check macro for LogDebugMessage +// + +#define EventEnabledLogDebugMessage() ((OVR_SDK_LibOVREnableBits[0] & 0x00000004) != 0) + +// +// Event Macro for LogDebugMessage +// +#define EventWriteLogDebugMessage(Message) \ + EventEnabledLogDebugMessage() ? Template_s(OVR_SDK_LibOVRHandle, &LogDebugMessage, Message) \ + : ERROR_SUCCESS + +// +// Enablement check macro for LogInfoMessage +// + +#define EventEnabledLogInfoMessage() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for LogInfoMessage +// +#define EventWriteLogInfoMessage(Message) \ + EventEnabledLogInfoMessage() ? Template_s(OVR_SDK_LibOVRHandle, &LogInfoMessage, Message) \ + : ERROR_SUCCESS + +// +// Enablement check macro for LogErrorMessage +// + +#define EventEnabledLogErrorMessage() ((OVR_SDK_LibOVREnableBits[0] & 0x00000008) != 0) + +// +// Event Macro for LogErrorMessage +// +#define EventWriteLogErrorMessage(Message) \ + EventEnabledLogErrorMessage() ? Template_s(OVR_SDK_LibOVRHandle, &LogErrorMessage, Message) \ + : ERROR_SUCCESS + +// +// Enablement check macro for HmdTrackingState +// + +#define EventEnabledHmdTrackingState() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for HmdTrackingState +// +#define EventWriteHmdTrackingState( \ + TimeInSeconds, \ + HeadPoseQuat, \ + HeadPoseTranslation, \ + HeadAngularVelocity, \ + HeadLinearVelocity, \ + CameraPoseQuat, \ + CameraPoseTranslation, \ + StatusFlags) \ + EventEnabledHmdTrackingState() ? Template_gF4F3F3F3F4F3q( \ + OVR_SDK_LibOVRHandle, \ + &HmdTrackingState, \ + TimeInSeconds, \ + HeadPoseQuat, \ + HeadPoseTranslation, \ + HeadAngularVelocity, \ + HeadLinearVelocity, \ + CameraPoseQuat, \ + CameraPoseTranslation, \ + StatusFlags) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraBlobs_v0 +// + +#define EventEnabledCameraBlobs_v0() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraBlobs_v0 +// +#define EventWriteCameraBlobs_v0(BlobCount, PositionX, PositionY, Size) \ + EventEnabledCameraBlobs_v0() \ + ? Template_qGR0GR0DR0( \ + OVR_SDK_LibOVRHandle, &CameraBlobs_v0, BlobCount, PositionX, PositionY, Size) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CameraBlobs +// + +#define EventEnabledCameraBlobs() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraBlobs +// +#define EventWriteCameraBlobs( \ + Camera, FrameNumber, ArrivalTime, Width, Height, BlobCount, PositionX, PositionY, Size) \ + EventEnabledCameraBlobs() ? Template_qdgddqGR5GR5DR5( \ + OVR_SDK_LibOVRHandle, \ + &CameraBlobs, \ + Camera, \ + FrameNumber, \ + ArrivalTime, \ + Width, \ + Height, \ + BlobCount, \ + PositionX, \ + PositionY, \ + Size) \ + : ERROR_SUCCESS + +// +// Enablement check macro for PoseLatchCPUWrite +// + +#define EventEnabledPoseLatchCPUWrite() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for PoseLatchCPUWrite +// +#define EventWritePoseLatchCPUWrite( \ + Sequence, \ + Layer, \ + MotionSensorTime, \ + PredictedScanlineFirst, \ + PredictedScanlineLast, \ + TimeToScanlineFirst, \ + TimeToScanlineLast, \ + StartPosition, \ + EndPosition, \ + StartQuat, \ + EndQuat) \ + EventEnabledPoseLatchCPUWrite() ? Template_qdfffffF3F3F4F4( \ + OVR_SDK_LibOVRHandle, \ + &PoseLatchCPUWrite, \ + Sequence, \ + Layer, \ + MotionSensorTime, \ + PredictedScanlineFirst, \ + PredictedScanlineLast, \ + TimeToScanlineFirst, \ + TimeToScanlineLast, \ + StartPosition, \ + EndPosition, \ + StartQuat, \ + EndQuat) \ + : ERROR_SUCCESS + +// +// Enablement check macro for PoseLatchGPULatchReadback +// + +#define EventEnabledPoseLatchGPULatchReadback() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for PoseLatchGPULatchReadback +// +#define EventWritePoseLatchGPULatchReadback( \ + Sequence, \ + Layer, \ + MotionSensorTime, \ + PredictedScanlineFirst, \ + PredictedScanlineLast, \ + TimeToScanlineFirst, \ + TimeToScanlineLast) \ + EventEnabledPoseLatchGPULatchReadback() ? Template_qdfffff( \ + OVR_SDK_LibOVRHandle, \ + &PoseLatchGPULatchReadback, \ + Sequence, \ + Layer, \ + MotionSensorTime, \ + PredictedScanlineFirst, \ + PredictedScanlineLast, \ + TimeToScanlineFirst, \ + TimeToScanlineLast) \ + : ERROR_SUCCESS + +// +// Enablement check macro for QueueAheadDelayBegin +// + +#define EventEnabledQueueAheadDelayBegin() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for QueueAheadDelayBegin +// +#define EventWriteQueueAheadDelayBegin(QueueAheadSeconds) \ + EventEnabledQueueAheadDelayBegin() \ + ? Template_f(OVR_SDK_LibOVRHandle, &QueueAheadDelayBegin, QueueAheadSeconds) \ + : ERROR_SUCCESS + +// +// Enablement check macro for QueueAheadDelayEnd +// + +#define EventEnabledQueueAheadDelayEnd() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for QueueAheadDelayEnd +// +#define EventWriteQueueAheadDelayEnd(QueueAheadSeconds) \ + EventEnabledQueueAheadDelayEnd() \ + ? Template_f(OVR_SDK_LibOVRHandle, &QueueAheadDelayEnd, QueueAheadSeconds) \ + : ERROR_SUCCESS + +// +// Enablement check macro for HmdDisplay +// + +#define EventEnabledHmdDisplay() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for HmdDisplay +// +#define EventWriteHmdDisplay( \ + Extended, \ + DeviceTypeGuess, \ + EdidVendorId, \ + EdidModelNumber, \ + DisplayID, \ + ModelName, \ + EdidSerialNumber, \ + LogicalResolutionInPixels_w, \ + LogicalResolutionInPixels_h, \ + NativeResolutionInPixels_w, \ + NativeResolutionInPixels_h, \ + DesktopDisplayOffset_x, \ + DesktopDisplayOffset_y, \ + DeviceNumber, \ + Rotation, \ + ApplicationExclusive) \ + EventEnabledHmdDisplay() ? Template_tqhhsssddddddxqt( \ + OVR_SDK_LibOVRHandle, \ + &HmdDisplay, \ + Extended, \ + DeviceTypeGuess, \ + EdidVendorId, \ + EdidModelNumber, \ + DisplayID, \ + ModelName, \ + EdidSerialNumber, \ + LogicalResolutionInPixels_w, \ + LogicalResolutionInPixels_h, \ + NativeResolutionInPixels_w, \ + NativeResolutionInPixels_h, \ + DesktopDisplayOffset_x, \ + DesktopDisplayOffset_y, \ + DeviceNumber, \ + Rotation, \ + ApplicationExclusive) \ + : ERROR_SUCCESS + +// +// Enablement check macro for PhaseSyncBegin +// + +#define EventEnabledPhaseSyncBegin() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for PhaseSyncBegin +// +#define EventWritePhaseSyncBegin( \ + LastCompositeTime, \ + LastVSyncTime, \ + FrameIntervalMS, \ + SemaphoreMS, \ + SleepMS, \ + SpinMS, \ + PhaseSyncMS, \ + BeginFrameTime, \ + TargetCompletionTime, \ + TargetCompositeTime, \ + TargetVSyncTime) \ + EventEnabledPhaseSyncBegin() ? Template_ggfffffgggg( \ + OVR_SDK_LibOVRHandle, \ + &PhaseSyncBegin, \ + LastCompositeTime, \ + LastVSyncTime, \ + FrameIntervalMS, \ + SemaphoreMS, \ + SleepMS, \ + SpinMS, \ + PhaseSyncMS, \ + BeginFrameTime, \ + TargetCompletionTime, \ + TargetCompositeTime, \ + TargetVSyncTime) \ + : ERROR_SUCCESS + +// +// Enablement check macro for PhaseSyncEnd +// + +#define EventEnabledPhaseSyncEnd() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for PhaseSyncEnd +// +#define EventWritePhaseSyncEnd( \ + BeginFrameTime, \ + EndFrameTime, \ + CompletionTime, \ + CompositeTime, \ + VSyncTime, \ + FrameTimeMS, \ + FrameTimeCpuMS, \ + FrameTimeVarianceMS, \ + QueueAhead, \ + FramesMissed, \ + AvgFrameTimeMS, \ + AvgFrameTimeCpuMS, \ + AvgFrameTimeVarianceMS, \ + AvgQueueAhead, \ + SyncFrameTimeMS, \ + SyncQueueAhead, \ + SyncFramesMissed, \ + PhaseSyncMS) \ + EventEnabledPhaseSyncEnd() ? Template_gggggffffqffffffqf( \ + OVR_SDK_LibOVRHandle, \ + &PhaseSyncEnd, \ + BeginFrameTime, \ + EndFrameTime, \ + CompletionTime, \ + CompositeTime, \ + VSyncTime, \ + FrameTimeMS, \ + FrameTimeCpuMS, \ + FrameTimeVarianceMS, \ + QueueAhead, \ + FramesMissed, \ + AvgFrameTimeMS, \ + AvgFrameTimeCpuMS, \ + AvgFrameTimeVarianceMS, \ + AvgQueueAhead, \ + SyncFrameTimeMS, \ + SyncQueueAhead, \ + SyncFramesMissed, \ + PhaseSyncMS) \ + : ERROR_SUCCESS + +// +// Enablement check macro for VSync +// + +#define EventEnabledVSync() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for VSync +// +#define EventWriteVSync(Time, FrameIndex, TwGpuEndTime) \ + EventEnabledVSync() ? Template_gqg(OVR_SDK_LibOVRHandle, &VSync, Time, FrameIndex, TwGpuEndTime) \ + : ERROR_SUCCESS + +// +// Enablement check macro for AppCompositorFocus +// + +#define EventEnabledAppCompositorFocus() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for AppCompositorFocus +// +#define EventWriteAppCompositorFocus(ProcessID) \ + EventEnabledAppCompositorFocus() \ + ? Template_x(OVR_SDK_LibOVRHandle, &AppCompositorFocus, ProcessID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for AppConnect +// + +#define EventEnabledAppConnect() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for AppConnect +// +#define EventWriteAppConnect(ProcessID) \ + EventEnabledAppConnect() ? Template_x(OVR_SDK_LibOVRHandle, &AppConnect, ProcessID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for AppDisconnect +// + +#define EventEnabledAppDisconnect() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for AppDisconnect +// +#define EventWriteAppDisconnect(ProcessID) \ + EventEnabledAppDisconnect() ? Template_x(OVR_SDK_LibOVRHandle, &AppDisconnect, ProcessID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for AppNoOp +// + +#define EventEnabledAppNoOp() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for AppNoOp +// +#define EventWriteAppNoOp(ProcessID) \ + EventEnabledAppNoOp() ? Template_x(OVR_SDK_LibOVRHandle, &AppNoOp, ProcessID) : ERROR_SUCCESS + +// +// Enablement check macro for PosePrediction +// + +#define EventEnabledPosePrediction() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for PosePrediction +// +#define EventWritePosePrediction( \ + OriginalPosition, \ + OriginalOrientation, \ + PredictedPosition, \ + PredictedOrientation, \ + PredictionTimeDeltaSeconds, \ + TimeInSeconds, \ + id) \ + EventEnabledPosePrediction() ? Template_G3G4G3G4ggs( \ + OVR_SDK_LibOVRHandle, \ + &PosePrediction, \ + OriginalPosition, \ + OriginalOrientation, \ + PredictedPosition, \ + PredictedOrientation, \ + PredictionTimeDeltaSeconds, \ + TimeInSeconds, \ + id) \ + : ERROR_SUCCESS + +// +// Enablement check macro for LatencyTiming +// + +#define EventEnabledLatencyTiming() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for LatencyTiming +// +#define EventWriteLatencyTiming( \ + RenderCpuBegin, \ + RenderCpuEnd, \ + RenderImu, \ + TimewarpCpu, \ + TimewarpLatched, \ + TimewarpGpuEnd, \ + PostPresent, \ + ErrorRender, \ + ErrorTimewarp) \ + EventEnabledLatencyTiming() ? Template_ggggggggg( \ + OVR_SDK_LibOVRHandle, \ + &LatencyTiming, \ + RenderCpuBegin, \ + RenderCpuEnd, \ + RenderImu, \ + TimewarpCpu, \ + TimewarpLatched, \ + TimewarpGpuEnd, \ + PostPresent, \ + ErrorRender, \ + ErrorTimewarp) \ + : ERROR_SUCCESS + +// +// Enablement check macro for EndFrameAppTiming +// + +#define EventEnabledEndFrameAppTiming() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for EndFrameAppTiming +// +#define EventWriteEndFrameAppTiming( \ + FrameIndex, \ + RenderImuTime, \ + ScanoutStartTime, \ + GpuRenderDuration, \ + BeginRenderingTime, \ + EndRenderingTime, \ + QueueAheadSeconds, \ + RenderCount) \ + EventEnabledEndFrameAppTiming() ? Template_qggggggd( \ + OVR_SDK_LibOVRHandle, \ + &EndFrameAppTiming, \ + FrameIndex, \ + RenderImuTime, \ + ScanoutStartTime, \ + GpuRenderDuration, \ + BeginRenderingTime, \ + EndRenderingTime, \ + QueueAheadSeconds, \ + RenderCount) \ + : ERROR_SUCCESS + +// +// Enablement check macro for HardwareInfo +// + +#define EventEnabledHardwareInfo() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for HardwareInfo +// +#define EventWriteHardwareInfo( \ + RequestedBits, \ + CollectedBits, \ + ImuTemp, \ + StmTemp, \ + NrfTemp, \ + VBusVoltage, \ + IAD, \ + Proximity, \ + PanelOnTime, \ + UseRolling, \ + HighBrightness, \ + DP, \ + SelfRefresh, \ + Persistence, \ + LightingOffset, \ + PixelSettle, \ + TotalRows) \ + EventEnabledHardwareInfo() ? Template_qqhhhhhhqtttthhhh( \ + OVR_SDK_LibOVRHandle, \ + &HardwareInfo, \ + RequestedBits, \ + CollectedBits, \ + ImuTemp, \ + StmTemp, \ + NrfTemp, \ + VBusVoltage, \ + IAD, \ + Proximity, \ + PanelOnTime, \ + UseRolling, \ + HighBrightness, \ + DP, \ + SelfRefresh, \ + Persistence, \ + LightingOffset, \ + PixelSettle, \ + TotalRows) \ + : ERROR_SUCCESS + +// +// Enablement check macro for VirtualDisplayPacketTrace +// + +#define EventEnabledVirtualDisplayPacketTrace() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for VirtualDisplayPacketTrace +// +#define EventWriteVirtualDisplayPacketTrace( \ + PacketType, Stage, SubmittingProcessID, ActiveProcessID) \ + EventEnabledVirtualDisplayPacketTrace() ? Template_xdxx( \ + OVR_SDK_LibOVRHandle, \ + &VirtualDisplayPacketTrace, \ + PacketType, \ + Stage, \ + SubmittingProcessID, \ + ActiveProcessID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for ClientFrameMissed +// + +#define EventEnabledClientFrameMissed() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for ClientFrameMissed +// +#define EventWriteClientFrameMissed(FrameIndex, ProcessID) \ + EventEnabledClientFrameMissed() \ + ? Template_xx(OVR_SDK_LibOVRHandle, &ClientFrameMissed, FrameIndex, ProcessID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CompositionBegin +// + +#define EventEnabledCompositionBegin() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CompositionBegin +// +#define EventWriteCompositionBegin(ExpectedCPUStartTimeInSeconds, ActualCPUStartTimeInSeconds) \ + EventEnabledCompositionBegin() ? Template_gg( \ + OVR_SDK_LibOVRHandle, \ + &CompositionBegin, \ + ExpectedCPUStartTimeInSeconds, \ + ActualCPUStartTimeInSeconds) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CompositionEnd +// + +#define EventEnabledCompositionEnd() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CompositionEnd +// +#define EventWriteCompositionEnd() \ + EventEnabledCompositionEnd() ? TemplateEventDescriptor(OVR_SDK_LibOVRHandle, &CompositionEnd) \ + : ERROR_SUCCESS + +// +// Enablement check macro for RenderPacketTrace +// + +#define EventEnabledRenderPacketTrace() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for RenderPacketTrace +// +#define EventWriteRenderPacketTrace(Stage, ClientPID) \ + EventEnabledRenderPacketTrace() \ + ? Template_qx(OVR_SDK_LibOVRHandle, &RenderPacketTrace, Stage, ClientPID) \ + : ERROR_SUCCESS + +// +// Enablement check macro for EndFrameOrigAppTiming +// + +#define EventEnabledEndFrameOrigAppTiming() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for EndFrameOrigAppTiming +// +#define EventWriteEndFrameOrigAppTiming( \ + FrameIndex, \ + RenderImuTime, \ + ScanoutStartTime, \ + GpuRenderDuration, \ + BeginRenderingTime, \ + EndRenderingTime, \ + QueueAheadSeconds, \ + RenderCount) \ + EventEnabledEndFrameOrigAppTiming() ? Template_qggggggd( \ + OVR_SDK_LibOVRHandle, \ + &EndFrameOrigAppTiming, \ + FrameIndex, \ + RenderImuTime, \ + ScanoutStartTime, \ + GpuRenderDuration, \ + BeginRenderingTime, \ + EndRenderingTime, \ + QueueAheadSeconds, \ + RenderCount) \ + : ERROR_SUCCESS + +// +// Enablement check macro for DistortionEndToEndTiming +// + +#define EventEnabledDistortionEndToEndTiming() ((OVR_SDK_LibOVREnableBits[0] & 0x00000010) != 0) + +// +// Event Macro for DistortionEndToEndTiming +// +#define EventWriteDistortionEndToEndTiming(ElapsedMs) \ + EventEnabledDistortionEndToEndTiming() \ + ? Template_g(OVR_SDK_LibOVRHandle, &DistortionEndToEndTiming, ElapsedMs) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CompositionEndSpinWait +// + +#define EventEnabledCompositionEndSpinWait() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CompositionEndSpinWait +// +#define EventWriteCompositionEndSpinWait() \ + EventEnabledCompositionEndSpinWait() \ + ? TemplateEventDescriptor(OVR_SDK_LibOVRHandle, &CompositionEndSpinWait) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CompositionFlushingToGPU +// + +#define EventEnabledCompositionFlushingToGPU() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CompositionFlushingToGPU +// +#define EventWriteCompositionFlushingToGPU() \ + EventEnabledCompositionFlushingToGPU() \ + ? TemplateEventDescriptor(OVR_SDK_LibOVRHandle, &CompositionFlushingToGPU) \ + : ERROR_SUCCESS + +// +// Enablement check macro for PhaseSyncGPUCompleted +// + +#define EventEnabledPhaseSyncGPUCompleted() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for PhaseSyncGPUCompleted +// +#define EventWritePhaseSyncGPUCompleted(AppGPUEndTimeSeconds) \ + EventEnabledPhaseSyncGPUCompleted() \ + ? Template_g(OVR_SDK_LibOVRHandle, &PhaseSyncGPUCompleted, AppGPUEndTimeSeconds) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CompositionMissedCompositorFrame +// + +#define EventEnabledCompositionMissedCompositorFrame() \ + ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CompositionMissedCompositorFrame +// +#define EventWriteCompositionMissedCompositorFrame() \ + EventEnabledCompositionMissedCompositorFrame() \ + ? TemplateEventDescriptor(OVR_SDK_LibOVRHandle, &CompositionMissedCompositorFrame) \ + : ERROR_SUCCESS + +// +// Enablement check macro for CompositionGPUStartTime +// + +#define EventEnabledCompositionGPUStartTime() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CompositionGPUStartTime +// +#define EventWriteCompositionGPUStartTime(DistortionBeginTimeInSeconds) \ + EventEnabledCompositionGPUStartTime() \ + ? Template_g(OVR_SDK_LibOVRHandle, &CompositionGPUStartTime, DistortionBeginTimeInSeconds) \ + : ERROR_SUCCESS + +// +// Enablement check macro for NotificationBegin +// + +#define EventEnabledNotificationBegin() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for NotificationBegin +// +#define EventWriteNotificationBegin( \ + AppFrameIndex, \ + CpuBeginToGpuEndSeconds, \ + CompositeTimeSeconds, \ + VSyncTimeSeconds, \ + CompositeDeltaSeconds, \ + VSyncDeltaSeconds) \ + EventEnabledNotificationBegin() ? Template_xggggg( \ + OVR_SDK_LibOVRHandle, \ + &NotificationBegin, \ + AppFrameIndex, \ + CpuBeginToGpuEndSeconds, \ + CompositeTimeSeconds, \ + VSyncTimeSeconds, \ + CompositeDeltaSeconds, \ + VSyncDeltaSeconds) \ + : ERROR_SUCCESS + +// +// Enablement check macro for NotificationEnd +// + +#define EventEnabledNotificationEnd() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for NotificationEnd +// +#define EventWriteNotificationEnd( \ + AppFrameIndex, CpuBeginToGpuEndSeconds, CpuBeginSeconds, GpuEndSeconds, SleepTimeMilliseconds) \ + EventEnabledNotificationEnd() ? Template_xgggq( \ + OVR_SDK_LibOVRHandle, \ + &NotificationEnd, \ + AppFrameIndex, \ + CpuBeginToGpuEndSeconds, \ + CpuBeginSeconds, \ + GpuEndSeconds, \ + SleepTimeMilliseconds) \ + : ERROR_SUCCESS + +// +// Enablement check macro for NotificationCompSubmit +// + +#define EventEnabledNotificationCompSubmit() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for NotificationCompSubmit +// +#define EventWriteNotificationCompSubmit(ShouldBeVisible, DisabledLayer, FrameIndex) \ + EventEnabledNotificationCompSubmit() ? Template_ttx( \ + OVR_SDK_LibOVRHandle, \ + &NotificationCompSubmit, \ + ShouldBeVisible, \ + DisabledLayer, \ + FrameIndex) \ + : ERROR_SUCCESS + +// +// Enablement check macro for MotionEstimationCostStats +// + +#define EventEnabledMotionEstimationCostStats() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for MotionEstimationCostStats +// +#define EventWriteMotionEstimationCostStats(Count, Average, Log2Histogram) \ + EventEnabledMotionEstimationCostStats() \ + ? Template_qqQ33( \ + OVR_SDK_LibOVRHandle, &MotionEstimationCostStats, Count, Average, Log2Histogram) \ + : ERROR_SUCCESS + +// +// Enablement check macro for PhaseSyncWaitToBeginFrame +// + +#define EventEnabledPhaseSyncWaitToBeginFrame() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for PhaseSyncWaitToBeginFrame +// +#define EventWritePhaseSyncWaitToBeginFrame( \ + Frame, \ + BeginWaitTime, \ + SemaphoreMS, \ + SleepMS, \ + SpinMS, \ + EndWaitTime, \ + TargetCompletionTime, \ + TargetCompositeTime, \ + TargetVSyncTime) \ + EventEnabledPhaseSyncWaitToBeginFrame() ? Template_xgfffgggg( \ + OVR_SDK_LibOVRHandle, \ + &PhaseSyncWaitToBeginFrame, \ + Frame, \ + BeginWaitTime, \ + SemaphoreMS, \ + SleepMS, \ + SpinMS, \ + EndWaitTime, \ + TargetCompletionTime, \ + TargetCompositeTime, \ + TargetVSyncTime) \ + : ERROR_SUCCESS + +// +// Enablement check macro for PhaseSyncBeginFrame +// + +#define EventEnabledPhaseSyncBeginFrame() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for PhaseSyncBeginFrame +// +#define EventWritePhaseSyncBeginFrame(Frame, BeginFrameTime) \ + EventEnabledPhaseSyncBeginFrame() \ + ? Template_xg(OVR_SDK_LibOVRHandle, &PhaseSyncBeginFrame, Frame, BeginFrameTime) \ + : ERROR_SUCCESS + +// +// Enablement check macro for PhaseSyncEndFrame +// + +#define EventEnabledPhaseSyncEndFrame() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for PhaseSyncEndFrame +// +#define EventWritePhaseSyncEndFrame(Frame, EndFrameTime) \ + EventEnabledPhaseSyncEndFrame() \ + ? Template_xg(OVR_SDK_LibOVRHandle, &PhaseSyncEndFrame, Frame, EndFrameTime) \ + : ERROR_SUCCESS + +// +// Enablement check macro for PhaseSyncCompleteFrame +// + +#define EventEnabledPhaseSyncCompleteFrame() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for PhaseSyncCompleteFrame +// +#define EventWritePhaseSyncCompleteFrame( \ + Frame, \ + CompletionTime, \ + CompositeTime, \ + VSyncTime, \ + FrameTimeMS, \ + AvgFrameTimeMS, \ + FrameTimeCpuMS, \ + AvgFrameTimeCpuMS, \ + FrameTimeGpuMS, \ + AvgFrameTimeGpuMS, \ + FrameVarianceMS, \ + AvgFrameVarianceMS, \ + QueueAheadMS, \ + AvgQueueAheadMS, \ + AdaptiveGpuPerformanceScale, \ + AvgAdaptiveGpuPerformanceScale, \ + PhaseSyncDelayMS) \ + EventEnabledPhaseSyncCompleteFrame() ? Template_xgggfffffffffffff( \ + OVR_SDK_LibOVRHandle, \ + &PhaseSyncCompleteFrame, \ + Frame, \ + CompletionTime, \ + CompositeTime, \ + VSyncTime, \ + FrameTimeMS, \ + AvgFrameTimeMS, \ + FrameTimeCpuMS, \ + AvgFrameTimeCpuMS, \ + FrameTimeGpuMS, \ + AvgFrameTimeGpuMS, \ + FrameVarianceMS, \ + AvgFrameVarianceMS, \ + QueueAheadMS, \ + AvgQueueAheadMS, \ + AdaptiveGpuPerformanceScale, \ + AvgAdaptiveGpuPerformanceScale, \ + PhaseSyncDelayMS) \ + : ERROR_SUCCESS + +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// Allow Diasabling of code generation +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// Template Functions +// +// +// Template from manifest : FunctionWaypoint +// +#ifndef Template_zdq_def +#define Template_zdq_def +ETW_INLINE +ULONG +Template_zdq( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_opt_ PCWSTR _Arg0, + _In_ const signed int _Arg1, + _In_ const unsigned int _Arg2) { +#define ARGUMENT_COUNT_zdq 3 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zdq]; + + EventDataDescCreate( + &EventData[0], + (_Arg0 != NULL) ? _Arg0 : L"NULL", + (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const signed int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const unsigned int)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zdq, EventData); +} +#endif + +// +// Template from manifest : Distortion +// +#ifndef Template_qq_def +#define Template_qq_def +ETW_INLINE +ULONG +Template_qq( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const unsigned int _Arg1) { +#define ARGUMENT_COUNT_qq 2 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qq]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const unsigned int)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qq, EventData); +} +#endif + +// +// Template from manifest : HmdDesc_v0 +// +#ifndef Template_qlls24llqqqdd_def +#define Template_qlls24llqqqdd_def +ETW_INLINE +ULONG +Template_qlls24llqqqdd( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const signed short _Arg1, + _In_ const signed short _Arg2, + _In_reads_(24) LPCCH _Arg3, + _In_ const signed short _Arg4, + _In_ const signed short _Arg5, + _In_ const unsigned int _Arg6, + _In_ const unsigned int _Arg7, + _In_ const unsigned int _Arg8, + _In_ const signed int _Arg9, + _In_ const signed int _Arg10) { +#define ARGUMENT_COUNT_qlls24llqqqdd 11 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qlls24llqqqdd]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const signed short)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const signed short)); + + EventDataDescCreate(&EventData[3], _Arg3, (ULONG)(sizeof(CHAR) * 24)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const signed short)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const signed short)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[8], &_Arg8, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[9], &_Arg9, sizeof(const signed int)); + + EventDataDescCreate(&EventData[10], &_Arg10, sizeof(const signed int)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qlls24llqqqdd, EventData); +} +#endif + +// +// Template from manifest : HmdDesc +// +#ifndef Template_qlls24llqqdd_def +#define Template_qlls24llqqdd_def +ETW_INLINE +ULONG +Template_qlls24llqqdd( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const signed short _Arg1, + _In_ const signed short _Arg2, + _In_reads_(24) LPCCH _Arg3, + _In_ const signed short _Arg4, + _In_ const signed short _Arg5, + _In_ const unsigned int _Arg6, + _In_ const unsigned int _Arg7, + _In_ const signed int _Arg8, + _In_ const signed int _Arg9) { +#define ARGUMENT_COUNT_qlls24llqqdd 10 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qlls24llqqdd]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const signed short)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const signed short)); + + EventDataDescCreate(&EventData[3], _Arg3, (ULONG)(sizeof(CHAR) * 24)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const signed short)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const signed short)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[8], &_Arg8, sizeof(const signed int)); + + EventDataDescCreate(&EventData[9], &_Arg9, sizeof(const signed int)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qlls24llqqdd, EventData); +} +#endif + +// +// Template from manifest : CameraFrameData_v0 +// +#ifndef Template_fqggq_def +#define Template_fqggq_def +ETW_INLINE +ULONG +Template_fqggq( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const float _Arg0, + _In_ const unsigned int _Arg1, + _In_ const double _Arg2, + _In_ const double _Arg3, + _In_ const unsigned int _Arg4) { +#define ARGUMENT_COUNT_fqggq 5 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_fqggq]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const float)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const double)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const double)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const unsigned int)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_fqggq, EventData); +} +#endif + +// +// Template from manifest : CameraFrameData +// +#ifndef Template_qddgg_def +#define Template_qddgg_def +ETW_INLINE +ULONG +Template_qddgg( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const signed int _Arg1, + _In_ const signed int _Arg2, + _In_ const double _Arg3, + _In_ const double _Arg4) { +#define ARGUMENT_COUNT_qddgg 5 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qddgg]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const signed int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const signed int)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const double)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const double)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qddgg, EventData); +} +#endif + +// +// Template from manifest : CameraFrameRequest +// +#ifndef Template_xxq_def +#define Template_xxq_def +ETW_INLINE +ULONG +Template_xxq( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0, + _In_ unsigned __int64 _Arg1, + _In_ const unsigned int _Arg2) { +#define ARGUMENT_COUNT_xxq 3 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_xxq]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const unsigned int)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_xxq, EventData); +} +#endif + +// +// Template from manifest : JSONChunk +// +#ifndef Template_zqqqqqb_def +#define Template_zqqqqqb_def +ETW_INLINE +ULONG +Template_zqqqqqb( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_opt_ PCWSTR _Arg0, + _In_ const unsigned int _Arg1, + _In_ const unsigned int _Arg2, + _In_ const unsigned int _Arg3, + _In_ const unsigned int _Arg4, + _In_ const unsigned int _Arg5, + _In_reads_(_Arg4) const BYTE* _Arg6) { +#define ARGUMENT_COUNT_zqqqqqb 7 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zqqqqqb]; + + EventDataDescCreate( + &EventData[0], + (_Arg0 != NULL) ? _Arg0 : L"NULL", + (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[6], _Arg6, (ULONG)sizeof(char) * _Arg4); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zqqqqqb, EventData); +} +#endif + +// +// Template from manifest : Log +// +#ifndef Template_s_def +#define Template_s_def +ETW_INLINE +ULONG +Template_s(_In_ REGHANDLE RegHandle, _In_ PCEVENT_DESCRIPTOR Descriptor, _In_opt_ LPCSTR _Arg0) { +#define ARGUMENT_COUNT_s 1 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_s]; + + EventDataDescCreate( + &EventData[0], + (_Arg0 != NULL) ? _Arg0 : "NULL", + (_Arg0 != NULL) ? (ULONG)((strlen(_Arg0) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_s, EventData); +} +#endif + +// +// Template from manifest : HmdTrackingState +// +#ifndef Template_gF4F3F3F3F4F3q_def +#define Template_gF4F3F3F3F4F3q_def +ETW_INLINE +ULONG +Template_gF4F3F3F3F4F3q( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const double _Arg0, + _In_reads_(4) const float* _Arg1, + _In_reads_(3) const float* _Arg2, + _In_reads_(3) const float* _Arg3, + _In_reads_(3) const float* _Arg4, + _In_reads_(4) const float* _Arg5, + _In_reads_(3) const float* _Arg6, + _In_ const unsigned int _Arg7) { +#define ARGUMENT_COUNT_gF4F3F3F3F4F3q 8 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_gF4F3F3F3F4F3q]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const double)); + + EventDataDescCreate(&EventData[1], _Arg1, sizeof(const float) * 4); + + EventDataDescCreate(&EventData[2], _Arg2, sizeof(const float) * 3); + + EventDataDescCreate(&EventData[3], _Arg3, sizeof(const float) * 3); + + EventDataDescCreate(&EventData[4], _Arg4, sizeof(const float) * 3); + + EventDataDescCreate(&EventData[5], _Arg5, sizeof(const float) * 4); + + EventDataDescCreate(&EventData[6], _Arg6, sizeof(const float) * 3); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const unsigned int)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_gF4F3F3F3F4F3q, EventData); +} +#endif + +// +// Template from manifest : CameraBlobs_v0 +// +#ifndef Template_qGR0GR0DR0_def +#define Template_qGR0GR0DR0_def +ETW_INLINE +ULONG +Template_qGR0GR0DR0( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_reads_(_Arg0) const double* _Arg1, + _In_reads_(_Arg0) const double* _Arg2, + _In_reads_(_Arg0) const signed int* _Arg3) { +#define ARGUMENT_COUNT_qGR0GR0DR0 4 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qGR0GR0DR0]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], _Arg1, sizeof(const double) * _Arg0); + + EventDataDescCreate(&EventData[2], _Arg2, sizeof(const double) * _Arg0); + + EventDataDescCreate(&EventData[3], _Arg3, sizeof(const signed int) * _Arg0); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qGR0GR0DR0, EventData); +} +#endif + +// +// Template from manifest : CameraBlobs +// +#ifndef Template_qdgddqGR5GR5DR5_def +#define Template_qdgddqGR5GR5DR5_def +ETW_INLINE +ULONG +Template_qdgddqGR5GR5DR5( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const signed int _Arg1, + _In_ const double _Arg2, + _In_ const signed int _Arg3, + _In_ const signed int _Arg4, + _In_ const unsigned int _Arg5, + _In_reads_(_Arg5) const double* _Arg6, + _In_reads_(_Arg5) const double* _Arg7, + _In_reads_(_Arg5) const signed int* _Arg8) { +#define ARGUMENT_COUNT_qdgddqGR5GR5DR5 9 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qdgddqGR5GR5DR5]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const signed int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const double)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const signed int)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const signed int)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[6], _Arg6, sizeof(const double) * _Arg5); + + EventDataDescCreate(&EventData[7], _Arg7, sizeof(const double) * _Arg5); + + EventDataDescCreate(&EventData[8], _Arg8, sizeof(const signed int) * _Arg5); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qdgddqGR5GR5DR5, EventData); +} +#endif + +// +// Template from manifest : PoseLLCPUWrite +// +#ifndef Template_qdfffffF3F3F4F4_def +#define Template_qdfffffF3F3F4F4_def +ETW_INLINE +ULONG +Template_qdfffffF3F3F4F4( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const signed int _Arg1, + _In_ const float _Arg2, + _In_ const float _Arg3, + _In_ const float _Arg4, + _In_ const float _Arg5, + _In_ const float _Arg6, + _In_reads_(3) const float* _Arg7, + _In_reads_(3) const float* _Arg8, + _In_reads_(4) const float* _Arg9, + _In_reads_(4) const float* _Arg10) { +#define ARGUMENT_COUNT_qdfffffF3F3F4F4 11 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qdfffffF3F3F4F4]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const signed int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const float)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const float)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const float)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const float)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const float)); + + EventDataDescCreate(&EventData[7], _Arg7, sizeof(const float) * 3); + + EventDataDescCreate(&EventData[8], _Arg8, sizeof(const float) * 3); + + EventDataDescCreate(&EventData[9], _Arg9, sizeof(const float) * 4); + + EventDataDescCreate(&EventData[10], _Arg10, sizeof(const float) * 4); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qdfffffF3F3F4F4, EventData); +} +#endif + +// +// Template from manifest : PoseLLGPUReadback +// +#ifndef Template_qdfffff_def +#define Template_qdfffff_def +ETW_INLINE +ULONG +Template_qdfffff( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const signed int _Arg1, + _In_ const float _Arg2, + _In_ const float _Arg3, + _In_ const float _Arg4, + _In_ const float _Arg5, + _In_ const float _Arg6) { +#define ARGUMENT_COUNT_qdfffff 7 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qdfffff]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const signed int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const float)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const float)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const float)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const float)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const float)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qdfffff, EventData); +} +#endif + +// +// Template from manifest : QueueAhead +// +#ifndef Template_f_def +#define Template_f_def +ETW_INLINE +ULONG +Template_f(_In_ REGHANDLE RegHandle, _In_ PCEVENT_DESCRIPTOR Descriptor, _In_ const float _Arg0) { +#define ARGUMENT_COUNT_f 1 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_f]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const float)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_f, EventData); +} +#endif + +// +// Template from manifest : HmdDisplay +// +#ifndef Template_tqhhsssddddddxqt_def +#define Template_tqhhsssddddddxqt_def +ETW_INLINE +ULONG +Template_tqhhsssddddddxqt( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const BOOL _Arg0, + _In_ const unsigned int _Arg1, + _In_ const unsigned short _Arg2, + _In_ const unsigned short _Arg3, + _In_opt_ LPCSTR _Arg4, + _In_opt_ LPCSTR _Arg5, + _In_opt_ LPCSTR _Arg6, + _In_ const signed int _Arg7, + _In_ const signed int _Arg8, + _In_ const signed int _Arg9, + _In_ const signed int _Arg10, + _In_ const signed int _Arg11, + _In_ const signed int _Arg12, + _In_ unsigned __int64 _Arg13, + _In_ const unsigned int _Arg14, + _In_ const BOOL _Arg15) { +#define ARGUMENT_COUNT_tqhhsssddddddxqt 16 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_tqhhsssddddddxqt]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const BOOL)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const unsigned short)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const unsigned short)); + + EventDataDescCreate( + &EventData[4], + (_Arg4 != NULL) ? _Arg4 : "NULL", + (_Arg4 != NULL) ? (ULONG)((strlen(_Arg4) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); + + EventDataDescCreate( + &EventData[5], + (_Arg5 != NULL) ? _Arg5 : "NULL", + (_Arg5 != NULL) ? (ULONG)((strlen(_Arg5) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); + + EventDataDescCreate( + &EventData[6], + (_Arg6 != NULL) ? _Arg6 : "NULL", + (_Arg6 != NULL) ? (ULONG)((strlen(_Arg6) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const signed int)); + + EventDataDescCreate(&EventData[8], &_Arg8, sizeof(const signed int)); + + EventDataDescCreate(&EventData[9], &_Arg9, sizeof(const signed int)); + + EventDataDescCreate(&EventData[10], &_Arg10, sizeof(const signed int)); + + EventDataDescCreate(&EventData[11], &_Arg11, sizeof(const signed int)); + + EventDataDescCreate(&EventData[12], &_Arg12, sizeof(const signed int)); + + EventDataDescCreate(&EventData[13], &_Arg13, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[14], &_Arg14, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[15], &_Arg15, sizeof(const BOOL)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_tqhhsssddddddxqt, EventData); +} +#endif + +// +// Template from manifest : PhaseSyncBegin +// +#ifndef Template_ggfffffgggg_def +#define Template_ggfffffgggg_def +ETW_INLINE +ULONG +Template_ggfffffgggg( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const double _Arg0, + _In_ const double _Arg1, + _In_ const float _Arg2, + _In_ const float _Arg3, + _In_ const float _Arg4, + _In_ const float _Arg5, + _In_ const float _Arg6, + _In_ const double _Arg7, + _In_ const double _Arg8, + _In_ const double _Arg9, + _In_ const double _Arg10) { +#define ARGUMENT_COUNT_ggfffffgggg 11 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_ggfffffgggg]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const double)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const double)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const float)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const float)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const float)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const float)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const float)); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const double)); + + EventDataDescCreate(&EventData[8], &_Arg8, sizeof(const double)); + + EventDataDescCreate(&EventData[9], &_Arg9, sizeof(const double)); + + EventDataDescCreate(&EventData[10], &_Arg10, sizeof(const double)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_ggfffffgggg, EventData); +} +#endif + +// +// Template from manifest : PhaseSyncEnd +// +#ifndef Template_gggggffffqffffffqf_def +#define Template_gggggffffqffffffqf_def +ETW_INLINE +ULONG +Template_gggggffffqffffffqf( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const double _Arg0, + _In_ const double _Arg1, + _In_ const double _Arg2, + _In_ const double _Arg3, + _In_ const double _Arg4, + _In_ const float _Arg5, + _In_ const float _Arg6, + _In_ const float _Arg7, + _In_ const float _Arg8, + _In_ const unsigned int _Arg9, + _In_ const float _Arg10, + _In_ const float _Arg11, + _In_ const float _Arg12, + _In_ const float _Arg13, + _In_ const float _Arg14, + _In_ const float _Arg15, + _In_ const unsigned int _Arg16, + _In_ const float _Arg17) { +#define ARGUMENT_COUNT_gggggffffqffffffqf 18 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_gggggffffqffffffqf]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const double)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const double)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const double)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const double)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const double)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const float)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const float)); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const float)); + + EventDataDescCreate(&EventData[8], &_Arg8, sizeof(const float)); + + EventDataDescCreate(&EventData[9], &_Arg9, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[10], &_Arg10, sizeof(const float)); + + EventDataDescCreate(&EventData[11], &_Arg11, sizeof(const float)); + + EventDataDescCreate(&EventData[12], &_Arg12, sizeof(const float)); + + EventDataDescCreate(&EventData[13], &_Arg13, sizeof(const float)); + + EventDataDescCreate(&EventData[14], &_Arg14, sizeof(const float)); + + EventDataDescCreate(&EventData[15], &_Arg15, sizeof(const float)); + + EventDataDescCreate(&EventData[16], &_Arg16, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[17], &_Arg17, sizeof(const float)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_gggggffffqffffffqf, EventData); +} +#endif + +// +// Template from manifest : RecordedVSync +// +#ifndef Template_gqg_def +#define Template_gqg_def +ETW_INLINE +ULONG +Template_gqg( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const double _Arg0, + _In_ const unsigned int _Arg1, + _In_ const double _Arg2) { +#define ARGUMENT_COUNT_gqg 3 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_gqg]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const double)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const double)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_gqg, EventData); +} +#endif + +// +// Template from manifest : AppEvent +// +#ifndef Template_x_def +#define Template_x_def +ETW_INLINE +ULONG +Template_x( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0) { +#define ARGUMENT_COUNT_x 1 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_x]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_x, EventData); +} +#endif + +// +// Template from manifest : PosePrediction +// +#ifndef Template_G3G4G3G4ggs_def +#define Template_G3G4G3G4ggs_def +ETW_INLINE +ULONG +Template_G3G4G3G4ggs( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_reads_(3) const double* _Arg0, + _In_reads_(4) const double* _Arg1, + _In_reads_(3) const double* _Arg2, + _In_reads_(4) const double* _Arg3, + _In_ const double _Arg4, + _In_ const double _Arg5, + _In_opt_ LPCSTR _Arg6) { +#define ARGUMENT_COUNT_G3G4G3G4ggs 7 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_G3G4G3G4ggs]; + + EventDataDescCreate(&EventData[0], _Arg0, sizeof(const double) * 3); + + EventDataDescCreate(&EventData[1], _Arg1, sizeof(const double) * 4); + + EventDataDescCreate(&EventData[2], _Arg2, sizeof(const double) * 3); + + EventDataDescCreate(&EventData[3], _Arg3, sizeof(const double) * 4); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const double)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const double)); + + EventDataDescCreate( + &EventData[6], + (_Arg6 != NULL) ? _Arg6 : "NULL", + (_Arg6 != NULL) ? (ULONG)((strlen(_Arg6) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_G3G4G3G4ggs, EventData); +} +#endif + +// +// Template from manifest : LatencyTiming +// +#ifndef Template_ggggggggg_def +#define Template_ggggggggg_def +ETW_INLINE +ULONG +Template_ggggggggg( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const double _Arg0, + _In_ const double _Arg1, + _In_ const double _Arg2, + _In_ const double _Arg3, + _In_ const double _Arg4, + _In_ const double _Arg5, + _In_ const double _Arg6, + _In_ const double _Arg7, + _In_ const double _Arg8) { +#define ARGUMENT_COUNT_ggggggggg 9 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_ggggggggg]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const double)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const double)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const double)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const double)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const double)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const double)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const double)); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const double)); + + EventDataDescCreate(&EventData[8], &_Arg8, sizeof(const double)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_ggggggggg, EventData); +} +#endif + +// +// Template from manifest : EndFrameAppTiming +// +#ifndef Template_qggggggd_def +#define Template_qggggggd_def +ETW_INLINE +ULONG +Template_qggggggd( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const double _Arg1, + _In_ const double _Arg2, + _In_ const double _Arg3, + _In_ const double _Arg4, + _In_ const double _Arg5, + _In_ const double _Arg6, + _In_ const signed int _Arg7) { +#define ARGUMENT_COUNT_qggggggd 8 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qggggggd]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const double)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const double)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const double)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const double)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const double)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const double)); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const signed int)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qggggggd, EventData); +} +#endif + +// +// Template from manifest : HardwareInfoTemplate +// +#ifndef Template_qqhhhhhhqtttthhhh_def +#define Template_qqhhhhhhqtttthhhh_def +ETW_INLINE +ULONG +Template_qqhhhhhhqtttthhhh( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const unsigned int _Arg1, + _In_ const unsigned short _Arg2, + _In_ const unsigned short _Arg3, + _In_ const unsigned short _Arg4, + _In_ const unsigned short _Arg5, + _In_ const unsigned short _Arg6, + _In_ const unsigned short _Arg7, + _In_ const unsigned int _Arg8, + _In_ const BOOL _Arg9, + _In_ const BOOL _Arg10, + _In_ const BOOL _Arg11, + _In_ const BOOL _Arg12, + _In_ const unsigned short _Arg13, + _In_ const unsigned short _Arg14, + _In_ const unsigned short _Arg15, + _In_ const unsigned short _Arg16) { +#define ARGUMENT_COUNT_qqhhhhhhqtttthhhh 17 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qqhhhhhhqtttthhhh]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const unsigned short)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const unsigned short)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const unsigned short)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const unsigned short)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const unsigned short)); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const unsigned short)); + + EventDataDescCreate(&EventData[8], &_Arg8, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[9], &_Arg9, sizeof(const BOOL)); + + EventDataDescCreate(&EventData[10], &_Arg10, sizeof(const BOOL)); + + EventDataDescCreate(&EventData[11], &_Arg11, sizeof(const BOOL)); + + EventDataDescCreate(&EventData[12], &_Arg12, sizeof(const BOOL)); + + EventDataDescCreate(&EventData[13], &_Arg13, sizeof(const unsigned short)); + + EventDataDescCreate(&EventData[14], &_Arg14, sizeof(const unsigned short)); + + EventDataDescCreate(&EventData[15], &_Arg15, sizeof(const unsigned short)); + + EventDataDescCreate(&EventData[16], &_Arg16, sizeof(const unsigned short)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qqhhhhhhqtttthhhh, EventData); +} +#endif + +// +// Template from manifest : VirtualDisplayPacketTemplate +// +#ifndef Template_xdxx_def +#define Template_xdxx_def +ETW_INLINE +ULONG +Template_xdxx( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0, + _In_ const signed int _Arg1, + _In_ unsigned __int64 _Arg2, + _In_ unsigned __int64 _Arg3) { +#define ARGUMENT_COUNT_xdxx 4 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_xdxx]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const signed int)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(unsigned __int64)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_xdxx, EventData); +} +#endif + +// +// Template from manifest : ClientMissedFrame +// +#ifndef Template_xx_def +#define Template_xx_def +ETW_INLINE +ULONG +Template_xx( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0, + _In_ unsigned __int64 _Arg1) { +#define ARGUMENT_COUNT_xx 2 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_xx]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(unsigned __int64)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_xx, EventData); +} +#endif + +// +// Template from manifest : CompositionBegin +// +#ifndef Template_gg_def +#define Template_gg_def +ETW_INLINE +ULONG +Template_gg( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const double _Arg0, + _In_ const double _Arg1) { +#define ARGUMENT_COUNT_gg 2 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_gg]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const double)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const double)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_gg, EventData); +} +#endif + +// +// Template from manifest : (null) +// +#ifndef TemplateEventDescriptor_def +#define TemplateEventDescriptor_def + +ETW_INLINE +ULONG +TemplateEventDescriptor(_In_ REGHANDLE RegHandle, _In_ PCEVENT_DESCRIPTOR Descriptor) { + return EventWrite(RegHandle, Descriptor, 0, NULL); +} +#endif + +// +// Template from manifest : RenderPacketTemplate +// +#ifndef Template_qx_def +#define Template_qx_def +ETW_INLINE +ULONG +Template_qx( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ unsigned __int64 _Arg1) { +#define ARGUMENT_COUNT_qx 2 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qx]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(unsigned __int64)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qx, EventData); +} +#endif + +// +// Template from manifest : DistortionEndToEndTiming +// +#ifndef Template_g_def +#define Template_g_def +ETW_INLINE +ULONG +Template_g(_In_ REGHANDLE RegHandle, _In_ PCEVENT_DESCRIPTOR Descriptor, _In_ const double _Arg0) { +#define ARGUMENT_COUNT_g 1 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_g]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const double)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_g, EventData); +} +#endif + +// +// Template from manifest : NotificationBegin +// +#ifndef Template_xggggg_def +#define Template_xggggg_def +ETW_INLINE +ULONG +Template_xggggg( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0, + _In_ const double _Arg1, + _In_ const double _Arg2, + _In_ const double _Arg3, + _In_ const double _Arg4, + _In_ const double _Arg5) { +#define ARGUMENT_COUNT_xggggg 6 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_xggggg]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const double)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const double)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const double)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const double)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const double)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_xggggg, EventData); +} +#endif + +// +// Template from manifest : NotificationEnd +// +#ifndef Template_xgggq_def +#define Template_xgggq_def +ETW_INLINE +ULONG +Template_xgggq( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0, + _In_ const double _Arg1, + _In_ const double _Arg2, + _In_ const double _Arg3, + _In_ const unsigned int _Arg4) { +#define ARGUMENT_COUNT_xgggq 5 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_xgggq]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const double)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const double)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const double)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const unsigned int)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_xgggq, EventData); +} +#endif + +// +// Template from manifest : NotificationCompSubmit +// +#ifndef Template_ttx_def +#define Template_ttx_def +ETW_INLINE +ULONG +Template_ttx( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const BOOL _Arg0, + _In_ const BOOL _Arg1, + _In_ unsigned __int64 _Arg2) { +#define ARGUMENT_COUNT_ttx 3 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_ttx]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const BOOL)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const BOOL)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(unsigned __int64)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_ttx, EventData); +} +#endif + +// +// Template from manifest : MotionEstimationCostStats +// +#ifndef Template_qqQ33_def +#define Template_qqQ33_def +ETW_INLINE +ULONG +Template_qqQ33( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const unsigned int _Arg1, + _In_reads_(33) const unsigned int* _Arg2) { +#define ARGUMENT_COUNT_qqQ33 3 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qqQ33]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const unsigned int)); + + EventDataDescCreate(&EventData[2], _Arg2, sizeof(const unsigned int) * 33); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qqQ33, EventData); +} +#endif + +// +// Template from manifest : PhaseSyncWaitToBeginFrame +// +#ifndef Template_xgfffgggg_def +#define Template_xgfffgggg_def +ETW_INLINE +ULONG +Template_xgfffgggg( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0, + _In_ const double _Arg1, + _In_ const float _Arg2, + _In_ const float _Arg3, + _In_ const float _Arg4, + _In_ const double _Arg5, + _In_ const double _Arg6, + _In_ const double _Arg7, + _In_ const double _Arg8) { +#define ARGUMENT_COUNT_xgfffgggg 9 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_xgfffgggg]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const double)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const float)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const float)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const float)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const double)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const double)); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const double)); + + EventDataDescCreate(&EventData[8], &_Arg8, sizeof(const double)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_xgfffgggg, EventData); +} +#endif + +// +// Template from manifest : PhaseSyncBeginFrame +// +#ifndef Template_xg_def +#define Template_xg_def +ETW_INLINE +ULONG +Template_xg( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0, + _In_ const double _Arg1) { +#define ARGUMENT_COUNT_xg 2 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_xg]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const double)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_xg, EventData); +} +#endif + +// +// Template from manifest : PhaseSyncCompleteFrame +// +#ifndef Template_xgggfffffffffffff_def +#define Template_xgggfffffffffffff_def +ETW_INLINE +ULONG +Template_xgggfffffffffffff( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0, + _In_ const double _Arg1, + _In_ const double _Arg2, + _In_ const double _Arg3, + _In_ const float _Arg4, + _In_ const float _Arg5, + _In_ const float _Arg6, + _In_ const float _Arg7, + _In_ const float _Arg8, + _In_ const float _Arg9, + _In_ const float _Arg10, + _In_ const float _Arg11, + _In_ const float _Arg12, + _In_ const float _Arg13, + _In_ const float _Arg14, + _In_ const float _Arg15, + _In_ const float _Arg16) { +#define ARGUMENT_COUNT_xgggfffffffffffff 17 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_xgggfffffffffffff]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64)); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const double)); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const double)); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const double)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const float)); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const float)); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const float)); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const float)); + + EventDataDescCreate(&EventData[8], &_Arg8, sizeof(const float)); + + EventDataDescCreate(&EventData[9], &_Arg9, sizeof(const float)); + + EventDataDescCreate(&EventData[10], &_Arg10, sizeof(const float)); + + EventDataDescCreate(&EventData[11], &_Arg11, sizeof(const float)); + + EventDataDescCreate(&EventData[12], &_Arg12, sizeof(const float)); + + EventDataDescCreate(&EventData[13], &_Arg13, sizeof(const float)); + + EventDataDescCreate(&EventData[14], &_Arg14, sizeof(const float)); + + EventDataDescCreate(&EventData[15], &_Arg15, sizeof(const float)); + + EventDataDescCreate(&EventData[16], &_Arg16, sizeof(const float)); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_xgggfffffffffffff, EventData); +} +#endif + +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +#if defined(__cplusplus) +}; +#endif + +#define MSG_OVR_SDK_LibOVR_opcode_FN_CALL_message 0x3000000AL +#define MSG_OVR_SDK_LibOVR_opcode_FN_RETURN_message 0x3000000BL +#define MSG_OVR_SDK_LibOVR_opcode_FN_WAYPOINT_message 0x3000000CL +#define MSG_OVR_SDK_LibOVR_opcode_DIS_BEGIN_message 0x3000000DL +#define MSG_OVR_SDK_LibOVR_opcode_DIS_WAITGPU_message 0x3000000EL +#define MSG_OVR_SDK_LibOVR_opcode_DIS_PRESENT_message 0x3000000FL +#define MSG_OVR_SDK_LibOVR_opcode_DIS_END_message 0x30000010L +#define MSG_OVR_SDK_LibOVR_opcode_HMD_DESC_message 0x30000011L +#define MSG_OVR_SDK_LibOVR_opcode_CAM_RECEIVE_message 0x30000012L +#define MSG_OVR_SDK_LibOVR_opcode_CAM_REQUEST_message 0x30000013L +#define MSG_level_LogAlways 0x50000000L +#define MSG_level_Error 0x50000002L +#define MSG_level_Informational 0x50000004L +#define MSG_level_Verbose 0x50000005L +#define MSG_OVR_SDK_LibOVR_task_FN_TRACE_message 0x70000001L +#define MSG_OVR_SDK_LibOVR_task_DIS_TRACE_message 0x70000002L +#define MSG_OVR_SDK_LibOVR_task_HMD_TRACE_message 0x70000003L +#define MSG_OVR_SDK_LibOVR_task_CAMERA_TRACE_message 0x70000004L +#define MSG_OVR_SDK_LibOVR_task_LOG_TRACE_message 0x70000005L +#define MSG_OVR_SDK_LibOVR_task_SUBMITFRAME_TRACE_message 0x70000006L +#define MSG_OVR_SDK_LibOVR_task_PHASESYNC_TRACE_message 0x70000007L +#define MSG_OVR_SDK_LibOVR_task_SENSOR_TRACE_message 0x70000008L +#define MSG_OVR_SDK_LibOVR_task_VIRTUALDISPLAY_TRACE_message 0x70000009L +#define MSG_OVR_SDK_LibOVR_task_Compositor_RunLoop_message 0x7000000AL +#define MSG_OVR_SDK_LibOVR_task_NOTIFICATION_TRACE_message 0x7000000BL +#define MSG_OVR_SDK_LibOVR_event_0_message 0xB0000000L +#define MSG_OVR_SDK_LibOVR_event_1_message 0xB0000001L +#define MSG_OVR_SDK_LibOVR_event_2_message 0xB0000002L +#define MSG_OVR_SDK_LibOVR_event_4_message 0xB0000004L +#define MSG_OVR_SDK_LibOVR_event_5_message 0xB0000005L +#define MSG_OVR_SDK_LibOVR_event_6_message 0xB0000006L +#define MSG_OVR_SDK_LibOVR_event_7_message 0xB0000007L +#define MSG_OVR_SDK_LibOVR_event_8_message 0xB0000008L +#define MSG_OVR_SDK_LibOVR_event_9_message 0xB0000009L +#define MSG_OVR_SDK_LibOVR_event_10_message 0xB000000AL +#define MSG_OVR_SDK_LibOVR_event_11_message 0xB000000BL +#define MSG_OVR_SDK_LibOVR_event_12_message 0xB000000CL +#define MSG_OVR_SDK_LibOVR_event_13_message 0xB000000DL +#define MSG_OVR_SDK_LibOVR_event_14_message 0xB000000EL +#define MSG_OVR_SDK_LibOVR_event_15_message 0xB000000FL +#define MSG_OVR_SDK_LibOVR_event_16_message 0xB0000010L +#define MSG_OVR_SDK_LibOVR_event_17_message 0xB0000011L +#define MSG_OVR_SDK_LibOVR_event_18_message 0xB0000012L +#define MSG_OVR_SDK_LibOVR_event_19_message 0xB0000013L +#define MSG_OVR_SDK_LibOVR_event_30_message 0xB000001EL +#define MSG_OVR_SDK_LibOVR_event_31_message 0xB000001FL +#define MSG_OVR_SDK_LibOVR_event_32_message 0xB0000020L +#define MSG_OVR_SDK_LibOVR_event_33_message 0xB0000021L +#define MSG_OVR_SDK_LibOVR_event_34_message 0xB0000022L +#define MSG_OVR_SDK_LibOVR_event_35_message 0xB0000023L +#define MSG_OVR_SDK_LibOVR_event_36_message 0xB0000024L +#define MSG_OVR_SDK_LibOVR_event_37_message 0xB0000025L +#define MSG_OVR_SDK_LibOVR_event_38_message 0xB0000026L +#define MSG_OVR_SDK_LibOVR_event_39_message 0xB0000027L +#define MSG_OVR_SDK_LibOVR_event_40_message 0xB0000028L +#define MSG_OVR_SDK_LibOVR_event_41_message 0xB0000029L +#define MSG_OVR_SDK_LibOVR_event_42_message 0xB000002AL +#define MSG_OVR_SDK_LibOVR_event_43_message 0xB000002BL +#define MSG_OVR_SDK_LibOVR_event_44_message 0xB000002CL +#define MSG_OVR_SDK_LibOVR_event_45_message 0xB000002DL +#define MSG_OVR_SDK_LibOVR_event_46_message 0xB000002EL +#define MSG_OVR_SDK_LibOVR_event_47_message 0xB000002FL +#define MSG_OVR_SDK_LibOVR_event_48_message 0xB0000030L +#define MSG_OVR_SDK_LibOVR_event_49_message 0xB0000031L +#define MSG_OVR_SDK_LibOVR_event_50_message 0xB0000032L +#define MSG_OVR_SDK_LibOVR_event_51_message 0xB0000033L +#define MSG_OVR_SDK_LibOVR_event_52_message 0xB0000034L +#define MSG_OVR_SDK_LibOVR_event_53_message 0xB0000035L +#define MSG_OVR_SDK_LibOVR_event_54_message 0xB0000036L +#define MSG_OVR_SDK_LibOVR_event_55_message 0xB0000037L +#define MSG_OVR_SDK_LibOVR_event_56_message 0xB0000038L +#define MSG_OVR_SDK_LibOVR_event_57_message 0xB0000039L +#define MSG_OVR_SDK_LibOVR_event_58_message 0xB000003AL +#define MSG_OVR_SDK_LibOVR_event_59_message 0xB000003BL +#define MSG_OVR_SDK_LibOVR_event_60_message 0xB000003CL +#define MSG_OVR_SDK_LibOVR_event_61_message 0xB000003DL +#define MSG_OVR_SDK_LibOVR_event_63_message 0xB000003EL +#define MSG_OVR_SDK_LibOVR_event_64_message 0xB000003FL +#define MSG_OVR_SDK_LibOVR_event_65_message 0xB0000040L +#define MSG_OVR_SDK_LibOVR_event_66_message 0xB0000041L diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.man b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.man new file mode 100644 index 0000000..034cd00 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.man @@ -0,0 +1,523 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.rc b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.rc new file mode 100644 index 0000000..6b83988 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents.rc @@ -0,0 +1,3 @@ +LANGUAGE 0x9,0x1 +1 11 "LibOVREvents_MSG00001.bin" +1 WEVT_TEMPLATE "LibOVREventsTEMP.BIN" diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN new file mode 100644 index 0000000..bbac1a8 Binary files /dev/null and b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN differ diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents_MSG00001.bin b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents_MSG00001.bin new file mode 100644 index 0000000..b7c8301 Binary files /dev/null and b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents_MSG00001.bin differ diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/README.md b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/README.md new file mode 100644 index 0000000..6fcdfd9 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/README.md @@ -0,0 +1,55 @@ +#Setup + +If you want stack walking to work on x64: + + > reg add "HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management" -v DisablePagingExecutive -d 0x1 -t REG_DWORD -f + +Add USERS Read & Execute privileges to the folder (or one of its parents) containing the LibOVREvents.man file: + + > icacls . /grant BUILTIN\Users:(OI)(CI)(RX) + +To install or reinstall the ETW manifest after building LibOVR run `install.cmd` as Administrator: + + > install + +Note: the install script will also attempt to install the manifests for the driver and runtime. Also note that the install +script installs the manifest from the newest version of LibOVR.dll, which might not be the version you are debugging in +Visual Studio (this will only matter if the two versions have specified different events). To be safe make sure your build +is up-to-date. + +#Adding trace points + +See [./Tracing.h] and the examples in [../OVR_CAPI.cpp]. + +The following macros can be used to trace call/return and progress through a function: + + TraceCall(frameIndex) + TraceReturn(frameIndex) + TraceWaypoint(frameIndex) + +Try to place the Call/Return instrumentation as close as possible to the function entry/exit points, and don't forget +to instrument all return paths. + +Supply a frame index of 0 if a frame index is not applicable/available. + +#Adding new trace events + +Use the `ECManGen.exe` utility from the Windows 8.1 SDK to edit the `LibOVREvents.man` manifest. + +See [http://msdn.microsoft.com/en-us/library/windows/desktop/dd996930%28v=vs.85%29.aspx] +The `F1` help is also useful. + +#Rebuilding the ETW headers and resources + +Use the `build.cmd` script to regenerate the `LibOVREvents.h`, `LibOVREvents.rc` and `LibOVREvents*.bin` files. +`clean.cmd` will remove all generated files. + +Note that the outputs are checked into the repository so you'll need to `p4 edit` them first. + +#Capturing ETW traces + +See [../../../Tools/XPerf/README.md] + +#Viewing ETW traces with GPUView + +See [http://msdn.microsoft.com/en-us/library/windows/desktop/jj585574(v=vs.85).aspx] diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/Tracing.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/Tracing.h new file mode 100644 index 0000000..059c232 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/Tracing.h @@ -0,0 +1,437 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : Tracing.h +Content : Performance tracing +Created : December 4, 2014 +Author : Ed Hutchins + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Tracing_h +#define OVR_Tracing_h + +//----------------------------------------------------------------------------------- +// ***** OVR_ENABLE_ETW_TRACING definition (XXX default to on for windows builds?) +// + +#ifdef OVR_OS_WIN32 +#define OVR_ENABLE_ETW_TRACING +#endif + +//----------------------------------------------------------------------------------- +// ***** Trace* definitions +// + +#ifdef OVR_ENABLE_ETW_TRACING + +#define TracingIsEnabled() (OVR_SDK_LibOVREnableBits[0] != 0) + +#ifdef TRACE_STATE_CAPTURE_FUNC +// hook in our own state capture callback to record the state of all opened HMDs (supress unused +// parameter warnings with void() casts) +#define MCGEN_PRIVATE_ENABLE_CALLBACK_V2( \ + SourceId, ControlCode, Level, MatchAnyKeyword, MatchAllKeywords, FilterData, CallbackContext) \ + (void(SourceId), \ + void(Level), \ + void(MatchAnyKeyword), \ + void(MatchAllKeywords), \ + void(FilterData), \ + void(CallbackContext), \ + (((ControlCode) == EVENT_CONTROL_CODE_CAPTURE_STATE) ? (void)(TRACE_STATE_CAPTURE_FUNC) \ + : (void)0)) +#endif + +#if !defined(_In_reads_) +// get VS2010 working +#define _In_reads_(x) +#endif + +#include "LibOVREvents.h" + +// Register/Unregister the OVR_SDK_LibOVR provider with ETW +// (MCGEN_PRIVATE_ENABLE_CALLBACK_V2 hooks in our state capture) +#define TraceInit(_Logger) \ + do { \ + ULONG status = EventRegisterOVR_SDK_LibOVR(); \ + if (ERROR_SUCCESS != status) { \ + _Logger.LogError("Failed to register ETW provider (%ul)", status); \ + } \ + } while (0) +#define TraceFini() EventUnregisterOVR_SDK_LibOVR() + +// Trace function call and return for perf, and waypoints for debug +#define TraceCall(frameIndex) EventWriteCall(__FUNCTIONW__, __LINE__, (frameIndex)) +#define TraceReturn(frameIndex) EventWriteReturn(__FUNCTIONW__, __LINE__, (frameIndex)) +#define TraceWaypoint(frameIndex) EventWriteWaypoint(__FUNCTIONW__, __LINE__, (frameIndex)) + +// DistortionRenderer events +#define TraceDistortionBegin(id, frameIndex) EventWriteDistortionBegin((id), (frameIndex)) +#define TraceDistortionWaitGPU(id, frameIndex) EventWriteDistortionWaitGPU((id), (frameIndex)) +#define TraceDistortionPresent(id, frameIndex) EventWriteDistortionPresent((id), (frameIndex)) +#define TraceDistortionEnd(id, frameIndex) EventWriteDistortionEnd((id), (frameIndex)) +#define TraceDistortionEndToEndTiming(elapsedMs) EventWriteDistortionEndToEndTiming((elapsedMs)) + +// Tracking Camera events +#define _TraceCameraFrameData(fn, camIdx, img) \ + fn((camIdx), \ + (uint32_t)(img).FrameNumber, \ + (img).HmdFrameNumber, \ + (img).ArrivalTime, \ + (img).CaptureTime) +#define TraceCameraFrameReceived(img) _TraceCameraFrameData(EventWriteCameraFrameReceived, 0, (img)) +#define TraceCameraBeginProcessing(camIdx, img) \ + _TraceCameraFrameData(EventWriteCameraBeginProcessing, (camIdx), (img)) +#define TraceCameraEndProcessing(camIdx, img) \ + _TraceCameraFrameData(EventWriteCameraEndProcessing, (camIdx), (img)) +#define TraceCameraFrameRequest(requestNumber, frameCount, lastFrameNumber) \ + EventWriteCameraFrameRequest(requestNumber, frameCount, lastFrameNumber) +#define TraceCameraSkippedFrames(camIdx, skippedFrameCount) \ + EventWriteCameraSkippedFrames(camIdx, skippedFrameCount) + +// Trace the interesting parts of an ovrHmdDesc structure +#define TraceHmdDesc(desc) \ + EventWriteHmdDesc( \ + (desc).Type, \ + (desc).VendorId, \ + (desc).ProductId, \ + (desc).SerialNumber, \ + (desc).FirmwareMajor, \ + (desc).FirmwareMinor, \ + (desc).AvailableHmdCaps, \ + (desc).AvailableTrackingCaps, \ + (desc).Resolution.w, \ + (desc).Resolution.h) +#define TraceHmdDisplay(dpy) \ + EventWriteHmdDisplay( \ + (0), \ + (0), \ + (dpy).Edid.VendorID, \ + (dpy).Edid.ModelNumber, \ + (dpy).DisplayIdentifier.ToCStr(), \ + (dpy).ModelName.ToCStr(), \ + (dpy).EdidSerialNumber.ToCStr(), \ + (dpy).LogicalResolutionInPixels.w, \ + (dpy).LogicalResolutionInPixels.h, \ + (dpy).NativeResolutionInPixels.w, \ + (dpy).NativeResolutionInPixels.h, \ + 0, \ + 0, \ + (dpy).DeviceNumber, \ + (dpy).Rotation, \ + (dpy).ApplicationExclusive) + +// Trace part of a JSON string (events have a 64k limit) +#define TraceJSONChunk(Name, TotalChunks, ChunkSequence, TotalSize, ChunkSize, ChunkOffset, Chunk) \ + EventWriteJSONChunk(Name, TotalChunks, ChunkSequence, TotalSize, ChunkSize, ChunkOffset, Chunk) + +// Trace messages from the public ovr_Trace API and our internal logger +#define TraceLogDebug(message) EventWriteLogDebugMessage(message) +#define TraceLogInfo(message) EventWriteLogInfoMessage(message) +#define TraceLogError(message) EventWriteLogErrorMessage(message) + +// Trace an ovrTrackingState +#define TraceTrackingState(ts) \ + EventWriteHmdTrackingState( \ + (ts).HeadPose.TimeInSeconds, \ + &(ts).HeadPose.ThePose.Orientation.x, \ + &(ts).HeadPose.ThePose.Position.x, \ + &(ts).HeadPose.AngularVelocity.x, \ + &(ts).HeadPose.LinearVelocity.x, \ + 0, \ + 0, \ + (ts).StatusFlags) + +#define TraceCameraBlobs(camIdx, frame) \ + if (EventEnabledCameraBlobs()) { \ + const int max_blobs = 80; \ + int count = (frame).Blobs.GetSizeI(); \ + double x[max_blobs]; \ + double y[max_blobs]; \ + int size[max_blobs]; \ + if (count > max_blobs) \ + count = max_blobs; \ + for (int i = 0; i < count; ++i) { \ + x[i] = (frame).Blobs[i].DistortedPosition.x; \ + y[i] = (frame).Blobs[i].DistortedPosition.y; \ + size[i] = (frame).Blobs[i].BlobSize; \ + } \ + EventWriteCameraBlobs( \ + camIdx, \ + (uint32_t)(frame).Frame->FrameNumber, \ + (frame).Frame->ArrivalTime, \ + (frame).Frame->Width, \ + (frame).Frame->Height, \ + count, \ + x, \ + y, \ + size); \ + } else \ + ((void)0) + +#define TracePosePrediction( \ + OriginalPose, PredictedPose, PredictionTimeDeltaSeconds, CurrentTimeInSeconds, id) \ + EventWritePosePrediction( \ + &(OriginalPose).Translation.x, \ + &(OriginalPose).Rotation.x, \ + &(PredictedPose).Translation.x, \ + &(PredictedPose).Rotation.x, \ + (PredictionTimeDeltaSeconds), \ + (CurrentTimeInSeconds), \ + (id)) + +// Trace PoseLatching CPU pinned memory write +#define TracePoseLatchCPUWrite( \ + Sequence, \ + Layer, \ + MotionSensorTime, \ + PredictedScanlineFirst, \ + PredictedScanlineLast, \ + TimeToScanlineFirst, \ + TimeToScanlineLast, \ + StartPosition, \ + EndPosition, \ + StartQuat, \ + EndQuat) \ + EventWritePoseLatchCPUWrite( \ + Sequence, \ + Layer, \ + MotionSensorTime, \ + PredictedScanlineFirst, \ + PredictedScanlineLast, \ + TimeToScanlineFirst, \ + TimeToScanlineLast, \ + StartPosition, \ + EndPosition, \ + StartQuat, \ + EndQuat) + +// Trace PoseLatching GPU latch +#define TracePoseLatchGPULatchReadback( \ + Sequence, \ + Layer, \ + MotionSensorTime, \ + PredictedScanlineFirst, \ + PredictedScanlineLast, \ + TimeToScanlineFirst, \ + TimeToScanlineLast) \ + EventWritePoseLatchGPULatchReadback( \ + Sequence, \ + Layer, \ + MotionSensorTime, \ + PredictedScanlineFirst, \ + PredictedScanlineLast, \ + TimeToScanlineFirst, \ + TimeToScanlineLast) + +#define TraceVSync(VSyncTime, FrameIndex, TWGpuEndTime) \ + EventWriteVSync(VSyncTime, FrameIndex, TWGpuEndTime) + +#define TraceAppCompositorFocus(Pid) EventWriteAppCompositorFocus(Pid) +#define TraceAppConnect(Pid) EventWriteAppConnect(Pid) +#define TraceAppDisconnect(Pid) EventWriteAppDisconnect(Pid) +#define TraceAppNoOp(Pid) EventWriteAppNoOp(Pid) + +#define TraceLatencyTiming(LatencyTiming) \ + EventWriteLatencyTiming( \ + LatencyTiming.LatencyRenderCpuBegin, \ + LatencyTiming.LatencyRenderCpuEnd, \ + LatencyTiming.LatencyRenderIMU, \ + LatencyTiming.LatencyTimewarpCpu, \ + LatencyTiming.LatencyTimewarpLatched, \ + LatencyTiming.LatencyTimewarpGpuEnd, \ + LatencyTiming.LatencyPostPresent, \ + LatencyTiming.ErrorRender, \ + LatencyTiming.ErrorTimewarp) + +#define TraceEndFrameAppTiming(AppTiming, RenderCount) \ + EventWriteEndFrameAppTiming( \ + AppTiming.AppFrameIndex, \ + AppTiming.AppRenderIMUTime, \ + AppTiming.AppVisibleMidpointTime, \ + AppTiming.AppGpuRenderDuration, \ + AppTiming.AppBeginRenderingTime, \ + AppTiming.AppEndRenderingTime, \ + AppTiming.QueueAheadSeconds, \ + RenderCount) +#define TraceEndFrameOrigAppTiming(AppTiming, RenderCount) \ + EventWriteEndFrameOrigAppTiming( \ + AppTiming.AppFrameIndex, \ + AppTiming.AppRenderIMUTime, \ + AppTiming.AppVisibleMidpointTime, \ + AppTiming.AppGpuRenderDuration, \ + AppTiming.AppBeginRenderingTime, \ + AppTiming.AppEndRenderingTime, \ + AppTiming.QueueAheadSeconds, \ + RenderCount) + +// XXX for future reference this could have been done with events with different opcodes and +// identical templates +#define VirtualDisplayPacketTrace_Begin 0 +#define VirtualDisplayPacketTrace_End 1 +#define VirtualDisplayPacketTrace_Queue 2 +#define VirtualDisplayPacketTrace_QueueRelease 3 +#define VirtualDisplayPacketTrace_Result 5 + +#define TraceVirtualDisplayPacket(PacketType, Stage, SubmittingProcessID, ActiveProcessID) \ + EventWriteVirtualDisplayPacketTrace(PacketType, Stage, SubmittingProcessID, ActiveProcessID) +#define TraceClientFrameMissed(FrameIndex, ProcessID) \ + EventWriteClientFrameMissed(FrameIndex, ProcessID) +#define TraceCompositionBegin(ExpectedCPUStartTimeInSeconds, ActualCPUStartTimeInSeconds) \ + EventWriteCompositionBegin(ExpectedCPUStartTimeInSeconds, ActualCPUStartTimeInSeconds) +#define TraceCompositionEnd() EventWriteCompositionEnd() +#define TraceCompositionEndSpinWait() EventWriteCompositionEndSpinWait() +#define TraceCompositionFlushingToGPU() EventWriteCompositionFlushingToGPU() +#define TraceRenderPacket(Stage, ClientPID) EventWriteRenderPacketTrace(Stage, ClientPID) +#define TraceHardwareInfo(data) \ + EventWriteHardwareInfo( \ + data.RequestedBits, \ + data.CollectedBits, \ + data.ImuTemp, \ + data.StmTemp, \ + data.NrfTemp, \ + data.VBusVoltage, \ + data.IAD, \ + data.Proximity, \ + data.PanelOnTime, \ + data.UseRolling, \ + data.HighBrightness, \ + data.DP, \ + data.SelfRefresh, \ + data.Persistence, \ + data.LightingOffset, \ + data.PixelSettle, \ + data.TotalRows) + +#define TraceCompositionMissedCompositorFrame() EventWriteCompositionMissedCompositorFrame() +#define TraceCompositionGPUStartTime(Seconds) EventWriteCompositionGPUStartTime(Seconds) + +#define TraceNotificationEnd( \ + AppFrameIndex, CpuBeginToGpuEndSeconds, CpuBeginSeconds, GpuEndSeconds, SleepMs) \ + EventWriteNotificationEnd( \ + AppFrameIndex, CpuBeginToGpuEndSeconds, CpuBeginSeconds, GpuEndSeconds, SleepMs) +#define TraceNotificationBegin( \ + AppFrameIndex, \ + CpuBeginToGpuEndSeconds, \ + CompositeTimeSeconds, \ + VSyncTimeSeconds, \ + CompositeDeltaSeconds, \ + VSyncDeltaSeconds) \ + EventWriteNotificationBegin( \ + AppFrameIndex, \ + CpuBeginToGpuEndSeconds, \ + CompositeTimeSeconds, \ + VSyncTimeSeconds, \ + CompositeDeltaSeconds, \ + VSyncDeltaSeconds) +#define TraceNotificationCompSubmit(IsEnabled, IsDisabled, FrameIndex) \ + EventWriteNotificationCompSubmit(IsEnabled, IsDisabled, FrameIndex) + +#define TraceMotionEstimationCostStats(Count, Average, Log2Histogram) \ + EventWriteMotionEstimationCostStats(Count, Average, Log2Histogram) + +#else // OVR_ENABLE_ETW_TRACING + +// Eventually other platforms could support their form of performance tracing +#define TracingIsEnabled() (false) +#define TraceInit() ((void)0) +#define TraceFini() ((void)0) +#define TraceCall(frameIndex) ((void)0) +#define TraceReturn(frameIndex) ((void)0) +#define TraceWaypoint(frameIndex) ((void)0) +#define TraceDistortionBegin(id, frameIndex) ((void)0) +#define TraceDistortionWaitGPU(id, frameIndex) ((void)0) +#define TraceDistortionPresent(id, frameIndex) ((void)0) +#define TraceDistortionEnd(id, frameIndex) ((void)0) +#define TraceDistortionEndToEndTiming(elapsedMs) ((void)0) +#define TraceCameraFrameReceived(cfd) ((void)0) +#define TraceCameraBeginProcessing(camIdx, img) ((void)0) +#define TraceCameraFrameRequest(requestNumber, frameCount, lastFrameNumber) ((void)0) +#define TraceCameraEndProcessing(camIdx, img) ((void)0) +#define TraceCameraSkippedFrames(camIdx, skippedFrameCount) ((void)0) +#define TraceHmdDesc(desc) ((void)0) +#define TraceHmdDisplay(dpy) ((void)0) +#define TraceJSONChunk(Name, TotalChunks, ChunkSequence, TotalSize, ChunkSize, ChunkOffset, Chunk) \ + ((void)0) +#define TraceLogDebug(message) ((void)0) +#define TraceLogInfo(message) ((void)0) +#define TraceLogError(message) ((void)0) +#define TraceTrackingState(ts) ((void)0) +#define TraceCameraBlobs(camIdx, frame) ((void)0) +#define TracePoseLatchCPUWrite( \ + Sequence, \ + Layer, \ + MotionSensorTime, \ + PredictedScanlineFirst, \ + PredictedScanlineLast, \ + TimeToScanlineFirst, \ + TimeToScanlineLast, \ + StartPosition, \ + EndPosition, \ + StartQuat, \ + EndQuat) \ + ((void)0) +#define TracePoseLatchGPULatchReadback( \ + Sequence, \ + Layer, \ + MotionSensorTime, \ + PredictedScanlineFirst, \ + PredictedScanlineLast, \ + TimeToScanlineFirst, \ + TimeToScanlineLast) \ + ((void)0) +#define TraceVSync(VSyncTime, FrameIndex, TWGpuEndTime) ((void)0) +#define TracePosePrediction( \ + OriginalPose, PredictedPose, PredictionTimeDeltaSeconds, CurrentTimeInSeconds, id) \ + ((void)0) +#define TraceAppCompositorFocus(Pid) ((void)0) +#define TraceAppConnect(Pid) ((void)0) +#define TraceAppDisconnect(Pid) ((void)0) +#define TraceAppNoOp(Pid) ((void)0) +#define TraceLatencyTiming(LatencyTiming) ((void)0) +#define TraceEndFrameAppTiming(AppTiming, RenderCount) ((void)0) +#define TraceEndFrameOrigAppTiming(AppTiming, RenderCount) ((void)0) +#define TraceVirtualDisplayPacket(PacketType, Stage, SubmittingProcessID, ActiveProcessID) ((void)0) +#define TraceClientFrameMissed(FrameIndex, ProcessID) ((void)0) +#define TraceCompositionBegin(ExpectedCPUStartTimeInSeconds, ActualCPUStartTimeInSeconds) ((void)0) +#define TraceCompositionEnd() ((void)0) +#define TraceCompositionEndSpinWait() ((void)0) +#define TraceCompositionFlushingToGPU() ((void)0) +#define TraceRenderPacket(Stage, ClientPID) ((void)0) +#define TraceHardwareInfo(data) ((void)0) +#define TraceCompositionMissedCompositorFrame() ((void)0) +#define TraceCompositionGPUStartTime(Seconds) ((void)0) +#define TraceNotificationEnd( \ + AppFrameIndex, CpuBeginToGpuEndSeconds, CpuBeginSeconds, GpuEndSeconds, SleepMs) \ + ((void)0) +#define TraceNotificationBegin( \ + AppFrameIndex, \ + CpuBeginToGpuEndSeconds, \ + CompositeTimeSeconds, \ + VSyncTimeSeconds, \ + CompositeDeltaSeconds, \ + VSyncDeltaSeconds) \ + ((void)0) +#define TraceNotificationCompSubmit(IsEnabled, IsDisabled, FrameIndex) ((void)0) +#define TraceMotionEstimationCostStats(Count, Average, Log2Histogram) ((void)0) + +#endif // OVR_ENABLE_ETW_TRACING + +#endif // OVR_Tracing_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/build.cmd b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/build.cmd new file mode 100644 index 0000000..9aad7af --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/build.cmd @@ -0,0 +1,16 @@ +@echo off +REM +REM build.cmd - rebuild generated ETW tracing files from LibOVREvents.man +REM + +REM assume mc.exe is in a path relative to xperf.exe +for /f "delims=" %%a in ('where /F Xperf') do set XPERF_PATH=%%~dpa + +set OSTYPE=x86 +if not "%PROCESSOR_ARCHITECTURE%"=="x86" set OSTYPE=x64 +if not "%PROCESSOR_ARCHITEW6432%"=="" set OSTYPE=x64 + +set MC="%XPERF_PATH%..\bin\%OSTYPE%\mc.exe" +echo Using Manifest Compiler: %MC% + +%MC% -v -a -A -n -um .\LibOVREvents.man -h . -z LibOVREvents diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/clean.cmd b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/clean.cmd new file mode 100644 index 0000000..7fcf44f --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/clean.cmd @@ -0,0 +1,6 @@ +@echo off +REM +REM clean.cmd - remove generated ETW tracing files +REM + +del LibOVREvents.h LibOVREvents.rc LibOVREvents*.bin *LibOVRRT*.dll diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/install.cmd b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/install.cmd new file mode 100644 index 0000000..83e0fe3 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/install.cmd @@ -0,0 +1,105 @@ +@echo off +setlocal +REM run this script from an Admin shell to set up ETW tracing + +set SCRIPTDIR=%~dp0 + +REM set SDK_MANIFEST_PATH to the SDK install path (e.g. C:\Program Files (x86)\Oculus) +for /f "delims=" %%a in ('reg query "HKLM\SOFTWARE\Wow6432Node\Oculus VR, LLC\Oculus" -v "Base"') do set SDK_INSTALL_PATH=%%a +set SDK_INSTALL_PATH=%SDK_INSTALL_PATH: Base REG_SZ =% +set SDK_MANIFEST_PATH=%SDK_INSTALL_PATH%\oculus-tools\etw + +REM Add USERS Read & Execute privileges to the folder +icacls . /grant BUILTIN\Users:(OI)(CI)(RX) >nul +if %errorlevel% equ 0 goto CaclsOk + +echo Failed to set cacls, installation may fail + +:CaclsOk + +for /f "delims=" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -v "ProductName"') do set PRODUCT_NAME=%%a +set PRODUCT_NAME=%PRODUCT_NAME: =% +set PRODUCT_NAME=%PRODUCT_NAME:ProductNameREG_SZ=% +set PRODUCT_NAME=%PRODUCT_NAME:dows=% +set PRODUCT_NAME=%PRODUCT_NAME:Enterprise=% +set PRODUCT_NAME=%PRODUCT_NAME:Professional=% +set SHORT_PRODUCT_NAME=%PRODUCT_NAME:.1=% +echo Installing %PRODUCT_NAME% manifests: + +rem we only support x64 oses these days +set OSTYPE=x64 +set OCUSBVID_SYS=%windir%\System32\drivers\ocusbvid111.sys +if "%SHORT_PRODUCT_NAME%"=="Win7" set OCUSBVID_SYS=%windir%\System32\drivers\ocusbvid109.sys +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto GotOSTYPE +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto GotOSTYPE + +echo 32-bit OS not supported +exit /b 1 + +:GotOSTYPE + +REM disable paging on x64 systems if stack walks are desired +if %OSTYPE% neq x64 goto SkipRegCheck +for /f "delims=" %%a in ('reg query "HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management" -v "DisablePagingExecutive"') do set REG_DPA=%%a + +if %REG_DPA:~-3% equ 0x1 goto SkipRegCheck +echo ************************ +echo DisablePagingExecutive should be set if you want stack tracing to work on %OSTYPE% +echo To disable paging run the following as Administrator: +echo reg add "HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management" -v DisablePagingExecutive -d 0x1 -t REG_DWORD -f +echo and reboot +echo ************************ + +:SkipRegCheck + +set RIFTCAMERADRIVER_DIR=%SCRIPTDIR%..\..\..\RiftPTDriver + +set USBVID_EVENTS_MAN=%SDK_MANIFEST_PATH%\OVRUSBVidEvents.man +if exist "%RIFTCAMERADRIVER_DIR%\OCUSBVID\OVRUSBVidEvents.man" set USBVID_EVENTS_MAN=%RIFTCAMERADRIVER_DIR%\OCUSBVID\OVRUSBVidEvents.man +if exist "%SCRIPTDIR%OVRUSBVidEvents.man" set USBVID_EVENTS_MAN=%SCRIPTDIR%OVRUSBVidEvents.man + +echo Installing %OCUSBVID_SYS% manifest... +REM uninstall any existing manifest first +wevtutil.exe uninstall-manifest "%USBVID_EVENTS_MAN%" +if %errorlevel% neq 0 echo WARNING: This step failed. +wevtutil.exe install-manifest "%USBVID_EVENTS_MAN%" /rf:"%OCUSBVID_SYS%" /mf:"%OCUSBVID_SYS%" +REM make sure it worked +wevtutil get-publisher OVR-USBVid > nul +if %errorlevel% neq 0 echo WARNING: This step failed. +echo Installed %USBVID_EVENTS_MAN% + +set LIBOVR_EVENTS_MAN=%SDK_MANIFEST_PATH%\LibOVREvents.man +if exist "%SCRIPTDIR%LibOVREvents.man" set LIBOVR_EVENTS_MAN=%SCRIPTDIR%LibOVREvents.man + +REM get rid of stale dll's +del /f /q "%SCRIPTDIR%LibOVRRT*.dll" +set LIBOVR_PATTERN=LibOVRRT*_1.dll +echo Looking for %LIBOVR_PATTERN% dll's +REM this nightmare command copies the newest version of %LIBOVR_PATTERN% into the current directory without prompting... +forfiles /p:"%SDK_INSTALL_PATH%Support\oculus-runtime" /m:%LIBOVR_PATTERN% /c "cmd /c xcopy /y /f /d @path \"%SCRIPTDIR%.\" >nul" >nul 2>nul +if not exist "%SCRIPTDIR%..\..\..\LibOVR\Lib\Windows" goto NoLibOVRSource +forfiles /s /p:"%SCRIPTDIR%..\..\..\LibOVR\Lib\Windows" /m:%LIBOVR_PATTERN% /c "cmd /c xcopy /y /f /d @path \"%SCRIPTDIR%.\" >nul" >nul 2>nul +:NoLibOVRSource +for /f "delims=" %%a in ('dir /b /o:d "%SCRIPTDIR%%LIBOVR_PATTERN%"') do set LIBOVR_DLL=%%a +echo Installing %LIBOVR_DLL% manifest... +REM uninstall any existing manifest first +wevtutil uninstall-manifest "%LIBOVR_EVENTS_MAN%" +if %errorlevel% neq 0 exit /b 1 + +REM use absolute paths to the RT .dll, otherwise we risk picking up the wrong (e.g. installed) version from %PATH% +echo wevtutil install-manifest "%LIBOVR_EVENTS_MAN%" /rf:"%SCRIPTDIR%%LIBOVR_DLL%" /mf:"%SCRIPTDIR%%LIBOVR_DLL%" +wevtutil install-manifest "%LIBOVR_EVENTS_MAN%" /rf:"%SCRIPTDIR%%LIBOVR_DLL%" /mf:"%SCRIPTDIR%%LIBOVR_DLL%" +REM note we can't do del /f /q "%SCRIPTDIR%%LIBOVR_PATTERN%" here because the binary has to be present for ETW enumeration to work +REM make sure it worked +wevtutil get-publisher OVR-SDK-LibOVR > nul +if %errorlevel% neq 0 exit /b 1 +echo Installed %LIBOVR_EVENTS_MAN% + +if not exist "%SCRIPTDIR%..\..\..\Tools" exit /b 0 + +echo You can now start/stop traces with the GUI: +echo cd %SCRIPTDIR%..\..\..\Tools\TraceScript\ovrtap +echo .\startovrtap.cmd +echo or (command-line): +echo cd %SCRIPTDIR%..\..\..\Tools\Xperf +echo ovrlog diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_ps.hlsl b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_ps.hlsl new file mode 100644 index 0000000..f54c610 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_ps.hlsl @@ -0,0 +1,8 @@ +Texture2D Input; +sampler Sampler; + +float4 main(float4 pos : SV_POSITION, + float2 tex : TEXCOORD) : SV_TARGET +{ + return Input.Sample(Sampler, tex); +} \ No newline at end of file diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_ps_ms2.hlsl b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_ps_ms2.hlsl new file mode 100644 index 0000000..21f2b6e --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_ps_ms2.hlsl @@ -0,0 +1,14 @@ +Texture2DMS Input; +sampler Sampler; + +float4 main(float4 pos : SV_POSITION, + float2 tex : TEXCOORD) : SV_TARGET +{ + uint width, height, sampleCount; + Input.GetDimensions(width, height, sampleCount); + int2 coord = int2(width * tex.x, height * tex.y); + + // This is a terrible resolve and shouldn't be used for anything + // where we care to maintain the result + return Input.Load(coord, sampleCount / 2); +} \ No newline at end of file diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_vs.hlsl b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_vs.hlsl new file mode 100644 index 0000000..25e592f --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/Blt_vs.hlsl @@ -0,0 +1,8 @@ +void main(float2 pos : POSITION, + float2 tex : TEXCOORD, + out float4 oPos : SV_POSITION, + out float2 oTex : TEXCOORD) +{ + oPos = float4(pos, 0, 1); + oTex = tex; +} \ No newline at end of file diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/GrayBlt_ps.hlsl b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/GrayBlt_ps.hlsl new file mode 100644 index 0000000..ad81b51 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Shaders/GrayBlt_ps.hlsl @@ -0,0 +1,9 @@ +Texture2D Input; +sampler Sampler; + +float4 main(float4 pos : SV_POSITION, + float2 tex : TEXCOORD) : SV_TARGET +{ + float4 temp = Input.Sample(Sampler, tex); + return float4(temp.rrr, 1.0f); +} \ No newline at end of file diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_D3D11_Blitter.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_D3D11_Blitter.cpp new file mode 100644 index 0000000..4ee32a6 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_D3D11_Blitter.cpp @@ -0,0 +1,687 @@ +/************************************************************************************ + +Filename : Util_D3D11_Blitter.cpp +Content : D3D11 implementation for blitting, supporting scaling & rotation +Created : February 24, 2015 +Authors : Reza Nourai + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Util_D3D11_Blitter.h" + +#ifdef OVR_OS_MS + +#include +#include "Logging/Logging_Library.h" +#include "Shaders/Blt_ps.h" +#include "Shaders/Blt_ps_ms2.h" +#include "Shaders/Blt_vs.h" +#include "Shaders/GrayBlt_ps.h" +#include "Util_Direct3D.h" + +struct MSAAShader { + const BYTE* Data; + SIZE_T Size; +}; + +static MSAAShader PixelShaderList[] = {{Blt_ps, sizeof(Blt_ps)}, + {Blt_ps_ms2, sizeof(Blt_ps_ms2)}, + {GrayBlt_ps, sizeof(GrayBlt_ps)}}; + +namespace OVR { +namespace D3DUtil { + +static ovrlog::Channel Log("Blitter"); + +//------------------------------------------------------------------------------------- +// ***** CAPI::Blitter + +Blitter::Blitter(const Ptr& device) + : Device(), + Context1(), + BltState(), + IL(), + VB(), + VS(), + PS(), + Sampler(), + DepthState(), + AlreadyInitialized(false), + SingleChannel(false) { + device->QueryInterface(IID_PPV_ARGS(&Device.GetRawRef())); + OVR_ASSERT(Device); + + Device->GetImmediateContext1(&Context1.GetRawRef()); + OVR_ASSERT(Context1); +} + +Blitter::~Blitter() {} + +bool Blitter::Initialize(bool single_channel) { + SingleChannel = single_channel; + if (!Device) { + OVR_ASSERT(false); + return false; + } + + OVR_ASSERT(!AlreadyInitialized); + if (AlreadyInitialized) { + return false; + } + + OVR_ASSERT(_countof(PixelShaderList) == PixelShaders::ShaderCount); + + UINT deviceFlags = Device->GetCreationFlags(); + D3D_FEATURE_LEVEL featureLevel = Device->GetFeatureLevel(); + + // If the device is single threaded, the context state must be too + UINT stateFlags = 0; + if (deviceFlags & D3D11_CREATE_DEVICE_SINGLETHREADED) { + stateFlags |= D3D11_1_CREATE_DEVICE_CONTEXT_STATE_SINGLETHREADED; + } + + // TODO: Clean this up with OVR_D3D_CREATE() when we move OVRError to kernel. + + OVR_ASSERT(!BltState); // Expected to be null on the way in. + BltState = nullptr; // Prevents a potential leak on the next line. + HRESULT hr = Device->CreateDeviceContextState( + stateFlags, + &featureLevel, + 1, + D3D11_SDK_VERSION, + __uuidof(ID3D11Device1), + nullptr, + &BltState.GetRawRef()); + OVR_D3D_CHECK_RET_FALSE(hr); + OVR_D3D_TAG_OBJECT(BltState); + + OVR_ASSERT(!VS); // Expected to be null on the way in. + VS = nullptr; // Prevents a potential leak on the next line. + hr = Device->CreateVertexShader(Blt_vs, sizeof(Blt_vs), nullptr, &VS.GetRawRef()); + OVR_D3D_CHECK_RET_FALSE(hr); + OVR_D3D_TAG_OBJECT(VS); + + for (int i = 0; i < ShaderCount; ++i) { + Ptr ps; + hr = Device->CreatePixelShader( + PixelShaderList[i].Data, PixelShaderList[i].Size, nullptr, &ps.GetRawRef()); + OVR_D3D_CHECK_RET_FALSE(hr); + OVR_D3D_TAG_OBJECT(ps); + PS[i] = ps; + } + + D3D11_INPUT_ELEMENT_DESC elems[2] = {}; + elems[0].Format = DXGI_FORMAT_R32G32_FLOAT; + elems[0].SemanticName = "POSITION"; + elems[1].AlignedByteOffset = sizeof(float) * 2; + elems[1].Format = DXGI_FORMAT_R32G32_FLOAT; + elems[1].SemanticName = "TEXCOORD"; + + OVR_ASSERT(!IL); // Expected to be null on the way in. + IL = nullptr; // Prevents a potential leak on the next line. + hr = Device->CreateInputLayout(elems, _countof(elems), Blt_vs, sizeof(Blt_vs), &IL.GetRawRef()); + OVR_D3D_CHECK_RET_FALSE(hr); + OVR_D3D_TAG_OBJECT(IL); + + // Quad with texcoords designed to rotate the source 90deg clockwise + BltVertex vertices[] = { + {-1, 1, 0, 0}, {1, 1, 1, 0}, {1, -1, 1, 1}, {-1, 1, 0, 0}, {1, -1, 1, 1}, {-1, -1, 0, 1}}; + + D3D11_BUFFER_DESC bd = {}; + bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bd.ByteWidth = sizeof(vertices); + bd.StructureByteStride = sizeof(BltVertex); + bd.Usage = D3D11_USAGE_DEFAULT; + + D3D11_SUBRESOURCE_DATA init = {}; + init.pSysMem = vertices; + init.SysMemPitch = sizeof(vertices); + init.SysMemSlicePitch = init.SysMemPitch; + + OVR_ASSERT(!VB); // Expected to be null on the way in. + VB = nullptr; // Prevents a potential leak on the next line. + hr = Device->CreateBuffer(&bd, &init, &VB.GetRawRef()); + OVR_D3D_CHECK_RET_FALSE(hr); + OVR_D3D_TAG_OBJECT(VB); + + D3D11_SAMPLER_DESC ss = {}; + ss.AddressU = ss.AddressV = ss.AddressW = D3D11_TEXTURE_ADDRESS_BORDER; + ss.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + ss.MaxLOD = 15; + + OVR_ASSERT(!Sampler); // Expected to be null on the way in. + Sampler = nullptr; // Prevents a potential leak on the next line. + hr = Device->CreateSamplerState(&ss, &Sampler.GetRawRef()); + OVR_D3D_CHECK_RET_FALSE(hr); + // OVR_D3D_TAG_OBJECT(); Seems to already have a name. + + D3D11_DEPTH_STENCIL_DESC depthDesc{}; + + OVR_ASSERT(!DepthState); // Expected to be null on the way in. + DepthState = nullptr; // Prevents a potential leak on the next line. + hr = Device->CreateDepthStencilState(&depthDesc, &DepthState.GetRawRef()); + OVR_D3D_CHECK_RET_FALSE(hr); + + // Swap to our blt state to set it up + Ptr existingState; + Context1->SwapDeviceContextState(BltState, &existingState.GetRawRef()); + + Context1->IASetInputLayout(IL); + Context1->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + Context1->VSSetShader(VS, nullptr, 0); + Context1->PSSetSamplers(0, 1, &Sampler.GetRawRef()); + Context1->OMSetDepthStencilState(DepthState, 0); + + // Swap back + Context1->SwapDeviceContextState(existingState, nullptr); + + AlreadyInitialized = true; + return true; +} + +bool Blitter::Blt(ID3D11RenderTargetView* dest, ID3D11ShaderResourceView* source) { + Ptr resource; + dest->GetResource(&resource.GetRawRef()); + Ptr texture; + HRESULT hr = resource->QueryInterface(IID_PPV_ARGS(&texture.GetRawRef())); + OVR_D3D_CHECK_RET_FALSE(hr); + + D3D11_TEXTURE2D_DESC desc = {}; + texture->GetDesc(&desc); + + return Blt(dest, source, 0, 0, desc.Width, desc.Height); +} + +bool Blitter::Blt( + ID3D11RenderTargetView* dest, + ID3D11ShaderResourceView* source, + uint32_t topLeftX, + uint32_t topLeftY, + uint32_t width, + uint32_t height) { + OVR_ASSERT(AlreadyInitialized); + if (!AlreadyInitialized) { + return false; + } + + // Switch to our state + Ptr existingState; + Context1->SwapDeviceContextState(BltState, &existingState.GetRawRef()); + + ID3D11RenderTargetView* nullRTVs[] = {nullptr, nullptr, nullptr, nullptr}; + ID3D11ShaderResourceView* nullSRVs[] = {nullptr, nullptr, nullptr, nullptr}; + + Context1->OMSetRenderTargets(_countof(nullRTVs), nullRTVs, nullptr); + Context1->PSSetShaderResources(0, _countof(nullSRVs), nullSRVs); + + // Set the mirror as the render target + Context1->OMSetRenderTargets(1, &dest, nullptr); + + D3D11_VIEWPORT vp = {}; + vp.TopLeftX = (float)topLeftX; + vp.TopLeftY = (float)topLeftY; + vp.Width = (float)width; + vp.Height = (float)height; + vp.MaxDepth = 1.0f; + Context1->RSSetViewports(1, &vp); + + Context1->PSSetShaderResources(0, 1, &source); + + Ptr resource; + source->GetResource(&resource.GetRawRef()); + + Ptr tmpTexture; + HRESULT hr = resource->QueryInterface(IID_PPV_ARGS(&tmpTexture.GetRawRef())); + if (FAILED(hr)) { + OVR_ASSERT(false); + return false; + } + + D3D11_TEXTURE2D_DESC texDesc; + tmpTexture->GetDesc(&texDesc); + + if (SingleChannel) { + Context1->PSSetShader(PS[PixelShaders::Grayscale], nullptr, 0); + } else if (texDesc.SampleDesc.Count == 1) { + Context1->PSSetShader(PS[PixelShaders::OneMSAA], nullptr, 0); + } else { + Context1->PSSetShader(PS[PixelShaders::TwoOrMoreMSAA], nullptr, 0); + } + + static const uint32_t stride = sizeof(BltVertex); + static const uint32_t offset = 0; + Context1->IASetVertexBuffers(0, 1, &VB.GetRawRef(), &stride, &offset); + + Context1->Draw(6, 0); + + Context1->OMSetRenderTargets(_countof(nullRTVs), nullRTVs, nullptr); + Context1->PSSetShaderResources(0, _countof(nullSRVs), nullSRVs); + + // Switch back to app state + Context1->SwapDeviceContextState(existingState, nullptr); + + return true; +} + +static bool operator!=(const DXGI_SAMPLE_DESC& s1, const DXGI_SAMPLE_DESC& s2) { + return (s1.Count != s2.Count) || (s1.Quality != s2.Quality); +} + +static bool operator!=(const D3D11_TEXTURE2D_DESC& d1, const D3D11_TEXTURE2D_DESC& d2) { + return (d1.Width != d2.Width) || (d1.Height != d2.Height) || (d1.MipLevels != d2.MipLevels) || + (d1.ArraySize != d2.ArraySize) || (d1.Format != d2.Format) || + (d1.SampleDesc != d2.SampleDesc) || (d1.Usage != d2.Usage) || + (d1.BindFlags != d2.BindFlags) || (d1.CPUAccessFlags != d2.CPUAccessFlags) || + (d1.MiscFlags != d2.MiscFlags); +} + +D3DTextureWriter::D3DTextureWriter(ID3D11Device* deviceNew) + : device(deviceNew), textureCopy(), pixels() { + memset(&textureCopyDesc, 0, sizeof(textureCopyDesc)); // We use memset instead of ={} because the + // former zeroes filler memory between + // variables, allowing comparison via + // memcmp. +} + +void D3DTextureWriter::Shutdown() { + device.Clear(); + textureCopy.Clear(); + textureCopyDesc = {}; + pixels.reset(); +} + +void D3DTextureWriter::SetDevice(ID3D11Device* deviceNew) { + if (device != deviceNew) { + textureCopy.Clear(); + textureCopyDesc = {}; + // No need to clear the pixels. + + device = deviceNew; + } +} + +D3DTextureWriter::Result D3DTextureWriter::SavePixelsToBMP(const wchar_t* path) { + // Create & write the file + ScopedFileHANDLE bmpFile(CreateFileW( + path, FILE_GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr)); + + if (!bmpFile.IsValid()) { + return Result::FILE_CREATION_FAILURE; + } + + const int BytesPerPixel = 4; + const auto PixelsWidth = pixelsDimentions.first; + const auto PixelsHeight = pixelsDimentions.second; + const auto ImageSize = PixelsWidth * PixelsHeight * BytesPerPixel; + + BITMAPFILEHEADER bfh{}; + bfh.bfType = 0x4d42; + bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + ImageSize; + bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + + BITMAPINFOHEADER bih{}; + bih.biSize = sizeof(bih); + bih.biBitCount = 8 * (WORD)BytesPerPixel; + bih.biPlanes = 1; + bih.biWidth = PixelsWidth; + bih.biHeight = PixelsHeight; + bih.biSizeImage = ImageSize; + + DWORD bytesWritten = 0; + WriteFile(bmpFile.Get(), &bfh, sizeof(bfh), &bytesWritten, nullptr); + WriteFile(bmpFile.Get(), &bih, sizeof(bih), &bytesWritten, nullptr); + + size_t offset = PixelsWidth * (PixelsHeight - 1); + for (uint32_t y = 0; y < PixelsHeight; ++y) { + WriteFile( + bmpFile.Get(), pixels.get() + offset, PixelsWidth * BytesPerPixel, &bytesWritten, nullptr); + offset -= PixelsWidth; + } + + return Result::SUCCESS; +} + +D3DTextureWriter::Result D3DTextureWriter::GrabPixels( + ID3D11Texture2D* texture, + UINT subresource, + bool copyTexture, + const ovrTimewarpProjectionDesc* depthProj, + const float* linearDepthScale) { + if (texture == nullptr) + return Result::NULL_SURFACE; + + if (device == nullptr) + return Result::NULL_DEVICE; + + Ptr deviceContext; + device->GetImmediateContext(&deviceContext.GetRawRef()); // Always succeeds. + + Ptr + textureSource; // This will point to either the input texture or to our textureCopy. + + // Create textureCopy surface to copy back to CPU. + D3D11_TEXTURE2D_DESC textureDesc{}; + texture->GetDesc(&textureDesc); + + if (copyTexture) { + textureDesc.BindFlags = 0; + textureDesc.Usage = D3D11_USAGE_STAGING; + textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + textureDesc.MiscFlags = 0; + + // We try to use our existing cached textureCopy as an intermediate texture, which will often + // be possible because a typical usage of this class is to keep copying the same texture. + if (textureDesc != textureCopyDesc) // If not equal... + { + textureCopyDesc = textureDesc; + textureCopy.Clear(); + + HRESULT hr = device->CreateTexture2D(&textureCopyDesc, nullptr, &textureCopy.GetRawRef()); + + if (FAILED(hr)) { + textureCopy.Clear(); + textureCopyDesc = {}; + return Result::TEXTURE_CREATION_FAILURE; + } + } + + // Copy texture to textureCopy. + deviceContext->CopyResource(textureCopy, texture); // Always succeeds. + + textureSource = textureCopy; + } else { + textureSource = texture; + } + + // At this point we have a valid D3D device, source texture, and intermediate texture. + // We will write the source texture to the intermediate texture and then copy the intermediate + // texture to a memory buffer while converting to BGRA, then write the memory buffer to disk. + // We don't copy the source texture directly to the memory buffer because that will block for some + // time. + + // Map textureSource so we can read its pixels. + D3D11_MAPPED_SUBRESOURCE mapped{}; + HRESULT hr = deviceContext->Map(textureSource, subresource, D3D11_MAP_READ, 0, &mapped); + + if (FAILED(hr)) { + return Result::TEXTURE_MAP_FAILURE; + } + + // Now copy textureSource to pixels, converting textureSource's format as-needed to make pixels be + // BGRA. + if (pixelsDimentions.first != textureDesc.Width || + pixelsDimentions.second != textureDesc.Height) { + pixels.reset(new uint32_t[textureDesc.Width * textureDesc.Height]); + pixelsDimentions = {textureDesc.Width, textureDesc.Height}; + } + + if (textureDesc.Format == DXGI_FORMAT_R11G11B10_FLOAT) { + // Convert from R11G11B10_FLOAT to R8G8B8 + uint32_t inputPitchInPixels = (mapped.RowPitch / 4); + + for (uint32_t y = 0; y < textureDesc.Height; ++y) { + for (uint32_t x = 0; x < textureDesc.Width; ++x) { +#pragma warning(disable : 4201) // nonstandard extension used: nameless struct/union + union XMFLOAT3PK { + union { + uint32_t v; + struct { + uint32_t xm : 6; + uint32_t xe : 5; + uint32_t ym : 6; + uint32_t ye : 5; + uint32_t zm : 5; + uint32_t ze : 5; + }; + }; + }; + + XMFLOAT3PK packedFloat{((uint32_t*)mapped.pData)[y * inputPitchInPixels + x]}; + float rFloat, gFloat, bFloat; + + uint32_t* floatRef = (uint32_t*)&rFloat; + *floatRef = ((packedFloat.xe - 15 + 127) << 23U) | (packedFloat.xm << 17); + + floatRef = (uint32_t*)&gFloat; + *floatRef = ((packedFloat.ye - 15 + 127) << 23U) | (packedFloat.ym << 17); + + floatRef = (uint32_t*)&bFloat; + *floatRef = ((packedFloat.ze - 15 + 127) << 23U) | (packedFloat.zm << 18); + + // This is back-asswards but we're converting out of linear so all + // the other images stored directly match in brightness for comparison. + uint32_t r = (uint32_t)(powf(rFloat, 1.0f / 2.2f) * 255.0f); + uint32_t g = (uint32_t)(powf(gFloat, 1.0f / 2.2f) * 255.0f); + uint32_t b = (uint32_t)(powf(bFloat, 1.0f / 2.2f) * 255.0f); + + uint32_t bgra = (255 << 24) | (r << 16) | (g << 8) | b; + + pixels[(y * textureDesc.Width) + x] = bgra; + } + } + } else if (textureDesc.Format == DXGI_FORMAT_R10G10B10A2_UNORM) { + // Convert from R10G10B10 to R8G8B8 + uint32_t inputPitchInPixels = mapped.RowPitch / 4; + + for (uint32_t y = 0; y < textureDesc.Height; ++y) { + for (uint32_t x = 0; x < textureDesc.Width; ++x) { + uint32_t wideRGBA = ((uint32_t*)mapped.pData)[(y * inputPitchInPixels) + x]; + uint32_t r = (wideRGBA >> 00) & 0x3ff; + uint32_t g = (wideRGBA >> 10) & 0x3ff; + uint32_t b = (wideRGBA >> 20) & 0x3ff; + uint32_t a = (wideRGBA >> 30) & 0x003; + + // This is back-asswards but we're converting out of linear so all + // the other images stored directly match in brightness for comparison. + r = (uint32_t)(powf((float)r / 1024.0f, 1.0f / 2.2f) * 255.0f); + g = (uint32_t)(powf((float)g / 1024.0f, 1.0f / 2.2f) * 255.0f); + b = (uint32_t)(powf((float)b / 1024.0f, 1.0f / 2.2f) * 255.0f); + + uint32_t bgra = (a << 24) | (r << 16) | (g << 8) | b; + + pixels[(y * textureDesc.Width) + x] = bgra; + } + } + } else if ( + textureDesc.Format == DXGI_FORMAT_R32_FLOAT || + textureDesc.Format == DXGI_FORMAT_R32_TYPELESS || + textureDesc.Format == DXGI_FORMAT_D32_FLOAT || + textureDesc.Format == DXGI_FORMAT_D24_UNORM_S8_UINT || + textureDesc.Format == DXGI_FORMAT_R24G8_TYPELESS || + textureDesc.Format == DXGI_FORMAT_R24G8_TYPELESS) { + if (depthProj == nullptr && linearDepthScale == nullptr) { + OVR_ASSERT(false); + Log.LogError("Tried to save depth image but depth projection is null or invalid"); + } + + uint32_t inputPitchInPixels = mapped.RowPitch / 4; + + for (uint32_t y = 0; y < textureDesc.Height; ++y) { + for (uint32_t x = 0; x < textureDesc.Width; ++x) { + float rValue = 0.0f; + + // 32-bit float is just a float + if (textureDesc.Format == DXGI_FORMAT_R32_FLOAT || + textureDesc.Format == DXGI_FORMAT_R32_TYPELESS || + textureDesc.Format == DXGI_FORMAT_D32_FLOAT) { + rValue = ((float*)mapped.pData)[y * inputPitchInPixels + x]; + } else { + // 24-bit depth is a normalized value + uint32_t temp = ((uint32_t*)mapped.pData)[y * inputPitchInPixels + x]; + temp &= 0xffffff; + static const float MAX_24FLOAT = (powf(2.0f, 24.0f) - 1.0f); + rValue = ((float)temp) / (MAX_24FLOAT); + } + + // linearDepth = -(Proj.M[2][3]) / ( Proj.M[2][2] - Proj.M[3][2] * nonLinearDepth)) + float linearDepth = 0.0f; + if (linearDepthScale) { + linearDepth = rValue * *linearDepthScale; + } else { + linearDepth = -(depthProj->Projection23) / + (depthProj->Projection22 - depthProj->Projection32 * rValue); + } + + linearDepth *= -10.0f; + + // This is back-asswards but we're converting out of linear so + // all the other images stored directly match in brightness + // for comparision + uint32_t r = (uint32_t)(255.0f - linearDepth); + + r = std::min(r, 255u); + + uint32_t bgra = 0xff << 24 | r << 16 | r << 8 | r; + + pixels[y * textureDesc.Width + x] = bgra; + } + } + } else if ( + (textureDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM) || + (textureDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB) || + (textureDesc.Format == DXGI_FORMAT_B8G8R8A8_TYPELESS)) { + if (mapped.RowPitch != textureDesc.Height * sizeof(uint32_t)) { + // Copy BGRA texture line by line + auto src = static_cast(mapped.pData); + auto end = src + mapped.RowPitch * textureDesc.Height; + for (auto dst = pixels.get(); src < end; src += mapped.RowPitch, dst += textureDesc.Width) { + memcpy(dst, src, textureDesc.Width * sizeof(uint32_t)); + } + } else { + memcpy(pixels.get(), mapped.pData, mapped.RowPitch * textureDesc.Height); + } + } else if ( + (textureDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM) || + (textureDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) || + (textureDesc.Format == DXGI_FORMAT_R8G8B8A8_UINT) || + (textureDesc.Format == DXGI_FORMAT_R8G8B8A8_TYPELESS)) { + // Convert from RGBA to BGRA. + auto dst = pixels.get(); + auto src = static_cast(mapped.pData); + auto end = src + mapped.RowPitch * textureDesc.Height; + for (; src < end; src += mapped.RowPitch) { + dst = ConvertRGBA2BGRA(reinterpret_cast(src), dst, textureDesc.Width); + } + } else { + // DXGI_FORMAT_NV12, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UINT, possibly others. + uint32_t inputPitchInBytes = mapped.RowPitch; + + for (uint32_t y = 0; y < textureDesc.Height; ++y) { + for (uint32_t x = 0; x < textureDesc.Width; ++x) { + uint8_t c = ((uint8_t*)mapped.pData)[(y * inputPitchInBytes) + x]; + uint32_t bgra = (0xff << 24) | (c << 16) | (c << 8) | c; // Write as an RGB-based gray. + + pixels[(y * textureDesc.Width) + x] = bgra; + } + } + } + + deviceContext->Unmap(textureSource, 0); // Always succeeds. + + return Result::SUCCESS; +} + +uint32_t* +D3DTextureWriter::ConvertRGBA2BGRA(const uint32_t* src, uint32_t* dst, unsigned pixelCount) { +#ifdef OVR_64BIT_POINTERS + auto src2 = reinterpret_cast(src); + auto dst2 = reinterpret_cast(dst); + auto lineEnd = src2 + (pixelCount >> 1); + // Convert 2 pixels at a time on 64-bit platforms + while (src2 < lineEnd) { + auto pixel = *src2++; + *dst2++ = (pixel & 0xff00ff00ff00ff00LL) | ((pixel & 0xff000000ffLL) << 16) | + ((pixel >> 16) & 0xff000000ffLL); + } + if ((pixelCount & 1) == 0) { + return reinterpret_cast(dst2); + } + // Convert remaining odd pixel + auto pixel = *reinterpret_cast(src2); + dst = reinterpret_cast(dst2); + *dst++ = (pixel & 0xff00ff00) | ((pixel & 0xff) << 16) | ((pixel >> 16) & 0xff); +#else + auto lineEnd = src + pixelCount; + while (src < lineEnd) { + auto pixel = *src++; + *dst++ = (pixel & 0xff00ff00) | ((pixel & 0xff) << 16) | ((pixel >> 16) & 0xff); + } +#endif + return dst; +} + +char* D3DTextureWriter::ConvertBGRA2RGB(const uint32_t* src, char* byteDst, unsigned pixelCount) { +// Convert a stream of 16 byte quadruplets B1G1R1A1|B2R2G2A2|B3G3R3A3|B4G4R4A4 +// into 12 byte triplets R1G1B1R2|G2B2R3G3|B3R4G4B4 +#ifdef OVR_CPU_SSE + const auto* lineSrc = reinterpret_cast(src); + const auto* lineEnd = reinterpret_cast(src + (pixelCount & ~3)); + auto shuffle = _mm_set_epi8(-1, -1, -1, -1, 12, 13, 14, 8, 9, 10, 4, 5, 6, 0, 1, 2); + auto storeMask = _mm_set_epi8(0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + while (lineSrc < lineEnd) { + __m128i invec = _mm_lddqu_si128(lineSrc++); + invec = _mm_shuffle_epi8(invec, shuffle); + _mm_maskmoveu_si128(invec, storeMask, byteDst); + byteDst += 12; + } +#else + auto dst = reinterpret_cast(byteDst); + auto quadEnd = reinterpret_cast(byteDst + 3 * (pixelCount & ~3)); + while (dst < quadEnd) { + auto pixel1 = *src++; + auto pixel2 = *src++; + auto pixel3 = *src++; + auto pixel4 = *src++; + *dst++ = ((pixel1 >> 16) & 0xff) | (pixel1 & 0x0000ff00) | ((pixel1 << 16) & 0x00ff0000) | + ((pixel2 << 8) & 0xff000000); + *dst++ = ((pixel2 >> 8) & 0xff) | ((pixel2 << 8) & 0x0000ff00) | (pixel3 & 0x00ff0000) | + ((pixel3 << 16) & 0xff000000); + *dst++ = (pixel3 & 0xff) | ((pixel4 >> 8) & 0x0000ff00) | ((pixel4 << 8) & 0x00ff0000) | + ((pixel4 << 24) & 0xff000000); + } + byteDst = reinterpret_cast(dst); +#endif + // Convert the reminder + for (UINT x = (pixelCount & ~3); x < pixelCount; ++x) { + auto pixel = *src++; + *byteDst++ = (pixel >> 16) & 0xff; + *byteDst++ = (pixel >> 8) & 0xff; + *byteDst++ = pixel & 0xff; + } + return byteDst; +} + +D3DTextureWriter::Result D3DTextureWriter::SaveTexture( + ID3D11Texture2D* texture, + UINT subresource, + bool copyTexture, + const wchar_t* path, + const ovrTimewarpProjectionDesc* depthProj, + const float* linearDepthScale) { + auto rc = GrabPixels(texture, subresource, copyTexture, depthProj, linearDepthScale); + if (rc != Result::SUCCESS) { + return rc; + } + return SavePixelsToBMP(path); +} +} // namespace D3DUtil +} // namespace OVR + +#endif // OVR_OS_MS diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_D3D11_Blitter.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_D3D11_Blitter.h new file mode 100644 index 0000000..534f056 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_D3D11_Blitter.h @@ -0,0 +1,145 @@ +/************************************************************************************ + +Filename : Util_D3D11_Blitter.h +Content : D3D11 implementation for blitting, supporting scaling +Created : February 24, 2015 +Authors : Reza Nourai + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Util_D3D11_Blitter_h +#define OVR_Util_D3D11_Blitter_h + +#include "Kernel/OVR_RefCount.h" + +#ifdef OVR_OS_MS + +#include +#include +#include // unique_ptr + +#include "OVR_CAPI.h" + +namespace OVR { +namespace D3DUtil { + +//------------------------------------------------------------------------------------- +// ***** CAPI::Blitter + +// D3D11 implementation of blitter + +class Blitter : public RefCountBase { + public: + Blitter(const Ptr& device); + ~Blitter(); + + bool Initialize(bool single_channel = false); + + bool Blt(ID3D11RenderTargetView* dest, ID3D11ShaderResourceView* source); + bool Blt( + ID3D11RenderTargetView* dest, + ID3D11ShaderResourceView* source, + uint32_t topLeftX, + uint32_t topLeftY, + uint32_t width, + uint32_t height); + + private: + enum PixelShaders { OneMSAA = 0, TwoOrMoreMSAA = 1, Grayscale = 2, ShaderCount = 3 }; + + Ptr Device; + Ptr Context1; + Ptr BltState; + Ptr IL; + Ptr VB; + Ptr VS; + + std::array, PixelShaders::ShaderCount> PS; + Ptr Sampler; + Ptr DepthState; + bool AlreadyInitialized; + bool SingleChannel; + + struct BltVertex { + float x, y; + float u, v; + }; +}; + +// Writes a D3D texture to a file path. +class D3DTextureWriter { + public: + D3DTextureWriter(ID3D11Device* deviceNew = nullptr); + + void Shutdown(); + + void SetDevice(ID3D11Device* deviceNew); + + enum class Result { + SUCCESS, + NULL_SURFACE, + NULL_DEVICE, + TEXTURE_CREATION_FAILURE, + TEXTURE_MAP_FAILURE, + FILE_CREATION_FAILURE, + }; + + // Beware that if the texture being saved is one that is a render target then the rendering to + // that + // texture will need to be complete for this to work properly. You may need to flush the device or + // command buffer to achieve this. + // If copyTexture is true then we make a copy of the input texture before writing it to disk. + // If texture is mapped for writing then you may want to use copyTexture because reading from it + // will be slow. + Result GrabPixels( + ID3D11Texture2D* texture, + UINT subresource, + bool copyTexture, + const ovrTimewarpProjectionDesc* depthProj, + const float* linearDepthScale); + + Result SavePixelsToBMP(const wchar_t* path); + + // Simple composition of GrabPixels() and SavePixelsToBMP() functions + Result SaveTexture( + ID3D11Texture2D* texture, + UINT subresource, + bool copyTexture, + const wchar_t* path, + const ovrTimewarpProjectionDesc* depthProj, + const float* linearDepthScale); + + static uint32_t* ConvertRGBA2BGRA(const uint32_t* src, uint32_t* dst, unsigned pixelCount); + static char* ConvertBGRA2RGB(const uint32_t* src, char* dst, unsigned pixelCount); + + protected: + Ptr device; // D3D11Device we use. Must match the textures we work with. + Ptr textureCopy; // The last texture we used. Cached for future use. + D3D11_TEXTURE2D_DESC textureCopyDesc; // This is a D3D11_TEXTURE2D_DESC. The description of + // textureCopy, which allows us to know if we need to free + // it and reallocate it anew. + std::pair pixelsDimentions = {0, 0}; + std::unique_ptr pixels; // Windows RGB .bmp files are actually in BGRA or BGR format. +}; +} // namespace D3DUtil +} // namespace OVR + +#endif // OVR_OS_MS +#endif // OVR_Util_D3D11_Blitter_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Direct3D.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Direct3D.cpp new file mode 100644 index 0000000..f2baecf --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Direct3D.cpp @@ -0,0 +1,94 @@ +/************************************************************************************ + +Filename : Util_Direct3D.cpp +Content : Shared code for Direct3D +Created : Oct 14, 2014 +Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Util_Direct3D.h" +#include "Logging/Logging_Library.h" + +static ovrlog::Channel Logger("Util_Direct3D"); + +namespace OVR { +namespace D3DUtil { + +bool VerifyHRESULT(const char* file, int line, HRESULT hr) { + if (FAILED(hr)) { + Logger.LogErrorF( + "D3D function returned fail HRESULT at %s on line %d : %s", + file, + line, + D3DUtil::GetWindowsErrorString(hr).ToCStr()); + OVR_ASSERT(false); + return false; + } + + return true; +} + +String GetWindowsErrorString(HRESULT hr) { + wchar_t* errorText = nullptr; + + DWORD slen = FormatMessageW( + // use system message tables to retrieve error text + FORMAT_MESSAGE_FROM_SYSTEM + // allocate buffer on local heap for error text + | FORMAT_MESSAGE_ALLOCATE_BUFFER + // Important! will fail otherwise, since we're not + // (and CANNOT) pass insertion parameters + | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, // unused with FORMAT_MESSAGE_FROM_SYSTEM + hr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&errorText, // output, allocated via LocalAlloc (free with LocalFree) + 256, // minimum size for output buffer + nullptr); // arguments - see note + + char formatStr[512]; + snprintf(formatStr, sizeof(formatStr), "[Code=%lx = %ld]", hr, hr); + + String retStr = formatStr; + + if (slen > 0 && errorText) { + retStr += " "; + retStr += errorText; + + // release memory allocated by FormatMessage() + LocalFree(errorText); + } + + return retStr; +} + +void LogD3DCompileError(HRESULT hr, ID3DBlob* blob) { + if (FAILED(hr)) { + char* errStr = (char*)blob->GetBufferPointer(); + SIZE_T len = blob->GetBufferSize(); + + if (errStr && len > 0) { + Logger.LogErrorF("Error compiling shader: %s", errStr); + } + } +} +} // namespace D3DUtil +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Direct3D.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Direct3D.h new file mode 100644 index 0000000..af43fb4 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Direct3D.h @@ -0,0 +1,161 @@ +/************************************************************************************ + +Filename : Util_Direct3D.h +Content : Shared code for Direct3D +Created : Oct 14, 2014 +Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Util_Direct3D_h +#define OVR_Util_Direct3D_h + +#if defined(_WIN32) + +// Include Windows correctly first before implicitly including it below +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_Win32_IncludeWindows.h" + +// Direct3D 11 +#include +#include + +#if _MSC_VER >= 1800 +// Visual Studio 2013+ support newer D3D/DXGI headers. +#define OVR_D3D11_VER 2 +#include +#define OVR_DXGI_VER 3 +#include // Used in place of 1.2 for IDXGIFactory2 debug version (when available) +#elif _MSC_VER >= 1700 +// Visual Studio 2012+ only supports older D3D/DXGI headers. +#define OVR_D3D11_VER 1 +#include +#else +// Visual Studio 2010+ only supports original D3D/DXGI headers. +#define OVR_D3D11_VER 1 +#include +#endif + +namespace OVR { +namespace D3DUtil { + +String GetWindowsErrorString(HRESULT hr); + +//----------------------------------------------------------------------------- +// Helper macros for verifying HRESULT values from Direct3D API calls +// +// These will assert on failure in debug mode, and in release or debug mode +// these functions will report the file and line where the error occurred, +// and what the error code was to the log at Error-level. + +// Assert on HRESULT failure +bool VerifyHRESULT(const char* file, int line, HRESULT hr); + +#define OVR_D3D_CHECK(hr) OVR::D3DUtil::VerifyHRESULT(__FILE__, __LINE__, hr) + +// Internal implementation of the OVR_D3D_CHECK_RET family of functions. +#define OVR_D3D_CHECK_RET_IMPL(hr, returnExpression) \ + { \ + if (!OVR_D3D_CHECK(hr)) { \ + returnExpression \ + } \ + } + +// Returns provided value on failure. +// Example usage: +// size_t Func() { +// . . . +// HRESULT hr = Device->QueryInterface(__uuidof(IDXGIDevice), (void +// **)&pDXGIDevice.GetRawRef()); +// OVR_D3D_CHECK_RET_VAL(hr, 0); +// . . . +// } +#define OVR_D3D_CHECK_RET_VAL(hr, failureValue) OVR_D3D_CHECK_RET_IMPL(hr, return failureValue;) + +// Returns void on failure +// Example usage: +// void Func() { +// . . . +// HRESULT hr = Device->QueryInterface(__uuidof(IDXGIDevice), (void +// **)&pDXGIDevice.GetRawRef()); +// OVR_D3D_CHECK_RET(hr); +// . . . +// } +#define OVR_D3D_CHECK_RET(hr) OVR_D3D_CHECK_RET_IMPL(hr, return;) + +// Returns false on failure +// Example usage: +// bool Func() { +// . . . +// HRESULT hr = Device->QueryInterface(__uuidof(IDXGIDevice), (void +// **)&pDXGIDevice.GetRawRef()); +// OVR_D3D_CHECK_RET_FALSE(hr); +// . . . +// } +#define OVR_D3D_CHECK_RET_FALSE(hr) OVR_D3D_CHECK_RET_IMPL(hr, return false;) + +// Returns nullptr on failure +// Example usage: +// void* Func() { +// . . . +// HRESULT hr = Device->QueryInterface(__uuidof(IDXGIDevice), (void +// **)&pDXGIDevice.GetRawRef()); +// OVR_D3D_CHECK_RET_NULL(hr); +// . . . +// } +#define OVR_D3D_CHECK_RET_NULL(hr) OVR_D3D_CHECK_RET_IMPL(hr, return nullptr;) + +// If the result is a failure, it will write the exact compile error to the error log +void LogD3DCompileError(HRESULT hr, ID3DBlob* errorBlob); + +#if defined(OVR_BUILD_DEBUG) + +// Enable this to track down double-tagging object warnings from D3D. +#define OVR_D3D_TRACK_DOUBLE_TAGGING + +#if defined(OVR_D3D_TRACK_DOUBLE_TAGGING) +#define OVR_D3D_CHECK_REUSE(child) \ + char tagReuseBuffer[1024]; \ + UINT reuseSize = (UINT)sizeof(tagReuseBuffer); \ + OVR_ASSERT(FAILED(child->GetPrivateData(WKPDID_D3DDebugObjectName, &reuseSize, tagReuseBuffer))); +#else +#define OVR_D3D_CHECK_REUSE(child) (void(0)) +#endif + +#define OVR_D3D_TAG_OBJECT(child) \ + if (child) { \ + OVR_D3D_CHECK_REUSE(child); \ + const char* tagName = OVR_STRINGIZE(child) " " __FILE__ "(" OVR_STRINGIZE(__LINE__) ")"; \ + UINT tagDataSize = (UINT)strlen(tagName); \ + HRESULT tagHR = child->SetPrivateData(WKPDID_D3DDebugObjectName, tagDataSize, tagName); \ + OVR_D3D_CHECK(tagHR); \ + } + +#else // !Debug: + +#define OVR_D3D_TAG_OBJECT(child) (void(0)) + +#endif // !Debug +} // namespace D3DUtil +} // namespace OVR + +#endif // _WIN32 + +#endif // OVR_Util_Direct3D_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_GL_Blitter.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_GL_Blitter.cpp new file mode 100644 index 0000000..1e37eac --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_GL_Blitter.cpp @@ -0,0 +1,269 @@ +/************************************************************************************ + +Filename : Util_GL_Blitter.cpp +Content : GL implementation for blitting, supporting scaling & rotation +Created : February 24, 2015 +Authors : Reza Nourai + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Util_GL_Blitter.h" + +namespace OVR { +namespace GLUtil { + +#define AssertOnGLError() \ + { \ + GLuint err = glGetError(); \ + OVR_ASSERT_AND_UNUSED(!err, err); \ + } + +//------------------------------------------------------------------------------------- +// ***** CAPI::Blitter + +Blitter::Blitter() : ReadFBO(0) {} + +Blitter::~Blitter() { + glDeleteFramebuffers(1, &ReadFBO); + ReadFBO = 0; +} + +bool Blitter::Initialize() { + glGenFramebuffers(1, &ReadFBO); + AssertOnGLError(); + + return true; +} + +bool Blitter::Blt(GLuint sourceTexId) { + GLenum status = 0; + + GLint currentTex2D = 0; + GLint sourceWidth = 0, sourceHeight = 0; + + // Store off currently selected tex2d + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤tTex2D); + + // Get source texture dimensions + glBindTexture(GL_TEXTURE_2D, sourceTexId); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &sourceWidth); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &sourceHeight); + + // Put old texture back + glBindTexture(GL_TEXTURE_2D, currentTex2D); + + // Save off the current FBOs + GLint currentReadFB; + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, ¤tReadFB); + AssertOnGLError(); + + // setup draw buffer + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glDrawBuffer(GL_BACK); + + // setup read buffer + glBindFramebuffer(GL_READ_FRAMEBUFFER, ReadFBO); + AssertOnGLError(); + + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTexId, 0); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + AssertOnGLError(); + status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + OVR_ASSERT_AND_UNUSED(status == GL_FRAMEBUFFER_COMPLETE, status); + + // Do the blt + glBlitFramebuffer( + 0, + sourceHeight, + sourceWidth, + 0, + 0, + 0, + sourceWidth, + sourceHeight, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + AssertOnGLError(); + + // Restore the previous FBOs + glBindFramebuffer(GL_READ_FRAMEBUFFER, currentReadFB); + AssertOnGLError(); + + return true; +} + +bool Blitter::Blt( + GLuint sourceTexId, + uint32_t topLeftX, + uint32_t topLeftY, + uint32_t width, + uint32_t height) { + GLenum status = 0; + + GLint currentTex2D = 0; + GLint sourceWidth = 0, sourceHeight = 0; + + // Store off currently selected tex2d + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤tTex2D); + + // Get source texture dimensions + glBindTexture(GL_TEXTURE_2D, sourceTexId); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &sourceWidth); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &sourceHeight); + + // Put old texture back + glBindTexture(GL_TEXTURE_2D, currentTex2D); + + // Save off the current FBOs + GLint currentReadFB; + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, ¤tReadFB); + AssertOnGLError(); + + // setup draw buffer + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glDrawBuffer(GL_BACK); + + // Get the default framebuffer size : + GLint dims[4] = {0}; + glGetIntegerv(GL_VIEWPORT, dims); + GLint fbHeight = dims[3]; + + // setup read buffer + glBindFramebuffer(GL_READ_FRAMEBUFFER, ReadFBO); + AssertOnGLError(); + + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTexId, 0); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + AssertOnGLError(); + status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + OVR_ASSERT_AND_UNUSED(status == GL_FRAMEBUFFER_COMPLETE, status); + + // Do the blt + glBlitFramebuffer( + 0, + sourceHeight, + sourceWidth, + 0, + (GLint)topLeftX, + fbHeight - (GLint)topLeftY - (GLint)height, + (GLint)topLeftX + (GLint)width, + fbHeight - (GLint)topLeftY, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + AssertOnGLError(); + + // Restore the previous FBOs + glBindFramebuffer(GL_READ_FRAMEBUFFER, currentReadFB); + AssertOnGLError(); + + return true; +} + +bool Blitter::BltCubemap(GLuint sourceTexId, GLuint tempTexId, uint32_t cubeMapSize) { + GLenum status = 0; + GLint currentTex2D = 0; + GLint size = (GLint)cubeMapSize; + const int numFaces = 6; + + // Store off currently selected tex2d + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤tTex2D); + + // Save off the current FBOs + GLint currentReadFB; + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, ¤tReadFB); + AssertOnGLError(); + + for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) { + // Create framebuffers + GLuint drawCubeFBO; + glGenFramebuffers(1, &drawCubeFBO); + AssertOnGLError(); + + GLuint readCubeFBO; + glGenFramebuffers(1, &readCubeFBO); + AssertOnGLError(); + + GLuint drawFinalCubeFBO; + glGenFramebuffers(1, &drawFinalCubeFBO); + AssertOnGLError(); + + // Setup draw buffer with temp texture to hold flipped face + // tempTexId holds a Texture2D the size of one cubemap face (cubeMapSize) + // It is used to temporarily hold a flipped face before blitting it to the original cubemap + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawCubeFBO); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tempTexId, 0); + + // Setup read buffer with original cubemap texture + glBindFramebuffer(GL_READ_FRAMEBUFFER, readCubeFBO); + AssertOnGLError(); + + glFramebufferTexture2D( + GL_READ_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, + sourceTexId, + 0); + AssertOnGLError(); + status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + OVR_ASSERT_AND_UNUSED(status == GL_FRAMEBUFFER_COMPLETE, status); + + // Do the blt + glBlitFramebuffer(0, size, size, 0, 0, size, size, 0, GL_COLOR_BUFFER_BIT, GL_LINEAR); + AssertOnGLError(); + + // Setup final draw buffer + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFinalCubeFBO); + glFramebufferTexture2D( + GL_DRAW_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, + sourceTexId, + 0); + + // Setup read buffer to be the previous draw buffer + glBindFramebuffer(GL_READ_FRAMEBUFFER, drawCubeFBO); // flipped FBO + AssertOnGLError(); + + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tempTexId, 0); + AssertOnGLError(); + status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + OVR_ASSERT_AND_UNUSED(status == GL_FRAMEBUFFER_COMPLETE, status); + + // Do the blt again + glBlitFramebuffer(0, size, size, 0, 0, 0, size, size, GL_COLOR_BUFFER_BIT, GL_LINEAR); + AssertOnGLError(); + + // Delete framebuffers + glDeleteFramebuffers(1, &drawCubeFBO); + drawCubeFBO = 0; + glDeleteFramebuffers(1, &readCubeFBO); + readCubeFBO = 0; + glDeleteFramebuffers(1, &drawFinalCubeFBO); + drawFinalCubeFBO = 0; + } + + // Restore the previous FBOs + glBindFramebuffer(GL_READ_FRAMEBUFFER, currentReadFB); + AssertOnGLError(); + + return true; +} +} // namespace GLUtil +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_GL_Blitter.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_GL_Blitter.h new file mode 100644 index 0000000..6502632 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_GL_Blitter.h @@ -0,0 +1,70 @@ +/************************************************************************************ + +Filename : Util_GL_Blitter.h +Content : GL implementation for blitting, supporting scaling & rotation +Created : February 24, 2015 +Authors : Reza Nourai + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Util_GL_Blitter_h +#define OVR_Util_GL_Blitter_h + +#include "Kernel/OVR_RefCount.h" +#include "Kernel/OVR_Win32_IncludeWindows.h" + +#include "GL/CAPI_GLE.h" + +#if defined(OVR_OS_WIN32) +#include +#elif defined(__APPLE__) +#include +#else +#include +#endif + +namespace OVR { +namespace GLUtil { + +//------------------------------------------------------------------------------------- +// ***** CAPI::Blitter + +// D3D11 implementation of blitter + +class Blitter : public RefCountBase { + public: + Blitter(); + ~Blitter(); + + bool Initialize(); + + // Blit sourceTexture to the active frame buffer + bool Blt(GLuint sourceTexId); + bool + Blt(GLuint sourceTexId, uint32_t topLeftX, uint32_t topLeftY, uint32_t width, uint32_t height); + bool BltCubemap(GLuint sourceTexId, GLuint tempTexId, uint32_t cubeMapSize); + + private: + GLuint ReadFBO; +}; +} // namespace GLUtil +} // namespace OVR + +#endif // OVR_Util_GL_Blitter_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_ImageWindow.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_ImageWindow.cpp new file mode 100644 index 0000000..aa5b47e --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_ImageWindow.cpp @@ -0,0 +1,536 @@ +/************************************************************************************ + +Filename : Util_ImageWindow.cpp +Content : An output object for windows that can display raw images for testing +Created : March 13, 2014 +Authors : Dean Beeler + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Kernel/OVR_Types.h" + +OVR_DISABLE_ALL_MSVC_WARNINGS() + +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_Nullptr.h" +#include "Kernel/OVR_RefCount.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Timer.h" + +#include "Util_ImageWindow.h" + +#if defined(OVR_OS_WIN32) +#include "DWrite.h" +#include "Kernel/OVR_Win32_IncludeWindows.h" +#endif + +OVR_RESTORE_ALL_MSVC_WARNINGS() + +#if defined(OVR_OS_WIN32) + +typedef HRESULT(WINAPI* D2D1CreateFactoryFn)( + _In_ D2D1_FACTORY_TYPE, + _In_ REFIID, + _In_opt_ const D2D1_FACTORY_OPTIONS*, + _Out_ ID2D1Factory**); + +typedef HRESULT(WINAPI* DWriteCreateFactoryFn)( + _In_ DWRITE_FACTORY_TYPE factoryType, + _In_ REFIID iid, + _Out_ IUnknown** factory); + +namespace OVR { +namespace Util { + +ID2D1Factory* ImageWindow::pD2DFactory = NULL; +IDWriteFactory* ImageWindow::pDWriteFactory = NULL; +HINSTANCE ImageWindow::hInstD2d1 = NULL; +HINSTANCE ImageWindow::hInstDwrite = NULL; + +// TODO(review): This appears to be (at present) necessary, the global list is accessed by the +// render loop in Samples. In the current version, windows will just be lost when windowCount +// exceeds MaxWindows; I've left that in place, since this is unfamiliar code. I'm not sure what +// thread-safety guarantees this portion of the code needs to satisfy, so I don't want to +// change it to a list or whatever. Asserts added to catch the error. +ImageWindow* ImageWindow::globalWindow[ImageWindow::MaxWindows]; +int ImageWindow::windowCount = 0; + +LRESULT CALLBACK MainWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch (uMsg) { + case WM_CREATE: + return 0; + + case WM_PAINT: { + LONG_PTR ptr = GetWindowLongPtrW(hwnd, GWLP_USERDATA); + if (ptr) { + ImageWindow* iw = (ImageWindow*)ptr; + iw->OnPaint(); + } + } + + return 0; + + case WM_SIZE: + // Set the size and position of the window. + return 0; + + case WM_DESTROY: + // Clean up window-specific data objects. + return 0; + + // + // Process other messages. + // + + default: + return DefWindowProcW(hwnd, uMsg, wParam, lParam); + } + // return 0; +} + +ImageWindow::ImageWindow(uint32_t width, uint32_t height) + : hWindow(NULL), + pRT(NULL), + // resolution(), + frontBufferMutex(new Mutex()), + frames(), + greyBitmap(NULL), + colorBitmap(NULL) { + D2D1CreateFactoryFn createFactory = NULL; + DWriteCreateFactoryFn writeFactory = NULL; + + if (!hInstD2d1) { + hInstD2d1 = LoadLibraryW(L"d2d1.dll"); + } + + if (!hInstD2d1) { + hInstD2d1 = LoadLibraryW(L"Dwrite.dll"); + } + + if (hInstD2d1) { + createFactory = (D2D1CreateFactoryFn)GetProcAddress(hInstD2d1, "D2D1CreateFactory"); + } + + if (hInstDwrite) { + writeFactory = (DWriteCreateFactoryFn)GetProcAddress(hInstDwrite, "DWriteCreateFactory"); + } + + // TODO: see note where globalWindow is declared. + globalWindow[windowCount++ % MaxWindows] = this; + OVR_ASSERT(windowCount < MaxWindows); + + if (pD2DFactory == NULL && createFactory && writeFactory) { + // Create a Direct2D factory. + HRESULT hResult = createFactory( + D2D1_FACTORY_TYPE_MULTI_THREADED, + __uuidof(ID2D1Factory), + NULL, + &pD2DFactory // This will be AddRef'd for us. + ); + OVR_ASSERT_AND_UNUSED(hResult == S_OK, hResult); + + // Create a DirectWrite factory. + hResult = writeFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(pDWriteFactory), // This probably should instead be __uuidof(IDWriteFactory) + reinterpret_cast(&pDWriteFactory) // This will be AddRef'd for us. + ); + OVR_ASSERT_AND_UNUSED(hResult == S_OK, hResult); + } + + resolution = D2D1::SizeU(width, height); + + if (hWindow) { + SetWindowLongPtrW(hWindow, GWLP_USERDATA, (LONG_PTR)this); + } +} + +ImageWindow::~ImageWindow() { + for (int i = 0; i < MaxWindows; ++i) { + if (globalWindow[i] == this) { + globalWindow[i] = NULL; + break; + } + } + + if (greyBitmap) + greyBitmap->Release(); + + if (colorBitmap) + colorBitmap->Release(); + + if (pRT) + pRT->Release(); + + { + Mutex::Locker locker(frontBufferMutex); + + while (frames.GetSize()) { + Ptr aFrame = frames.PopBack(); + } + } + + if (hWindow) { + ShowWindow(hWindow, SW_HIDE); + DestroyWindow(hWindow); + } + + if (pD2DFactory) { + pD2DFactory->Release(); + pD2DFactory = NULL; + } + + if (pDWriteFactory) { + pDWriteFactory->Release(); + pDWriteFactory = NULL; + } + + if (hInstD2d1) { + FreeLibrary(hInstD2d1); + hInstD2d1 = NULL; + } + + if (hInstDwrite) { + FreeLibrary(hInstDwrite); + hInstDwrite = NULL; + } +} + +void ImageWindow::AssociateSurface(void* surface) { + if (pD2DFactory) { + // Assume an IUnknown + IUnknown* unknown = (IUnknown*)surface; + + IDXGISurface* pDxgiSurface = NULL; + HRESULT hr = unknown->QueryInterface(&pDxgiSurface); + if (hr == S_OK) { + D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties( + D2D1_RENDER_TARGET_TYPE_DEFAULT, + D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), + 96, + 96); + + pRT = NULL; + ID2D1RenderTarget* tmpTarget; + + hr = pD2DFactory->CreateDxgiSurfaceRenderTarget(pDxgiSurface, &props, &tmpTarget); + + if (hr == S_OK) { + DXGI_SURFACE_DESC desc{}; + pDxgiSurface->GetDesc(&desc); + int width = desc.Width; + int height = desc.Height; + + D2D1_SIZE_U size = D2D1::SizeU(width, height); + + D2D1_PIXEL_FORMAT pixelFormat = + D2D1::PixelFormat(DXGI_FORMAT_A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED); + + D2D1_PIXEL_FORMAT colorPixelFormat = + D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED); + + D2D1_BITMAP_PROPERTIES bitmapProps; + bitmapProps.dpiX = 96; + bitmapProps.dpiY = 96; + bitmapProps.pixelFormat = pixelFormat; + + D2D1_BITMAP_PROPERTIES colorBitmapProps; + colorBitmapProps.dpiX = 96; + colorBitmapProps.dpiY = 96; + colorBitmapProps.pixelFormat = colorPixelFormat; + + HRESULT result = tmpTarget->CreateBitmap(size, bitmapProps, &greyBitmap); + if (result != S_OK) { + tmpTarget->Release(); + tmpTarget = NULL; + } + + if (tmpTarget) { + result = tmpTarget->CreateBitmap(size, colorBitmapProps, &colorBitmap); + if (result != S_OK) { + tmpTarget->Release(); + tmpTarget = NULL; + } + } + pRT = tmpTarget; + } + } + } +} + +void ImageWindow::Process() { + if (pRT && greyBitmap) { + OnPaint(); + + pRT->Flush(); + } +} + +void ImageWindow::Complete() { + Mutex::Locker locker(frontBufferMutex); + + if (frames.IsEmpty()) + return; + + if (frames.PeekBack(0)->ready) + return; + + Ptr frame = frames.PeekBack(0); + + frame->ready = true; +} + +void ImageWindow::OnPaint() { + Mutex::Locker locker(frontBufferMutex); + + // Nothing to do + if (frames.IsEmpty()) + return; + + if (!frames.PeekFront(0)->ready) + return; + + Ptr currentFrame = frames.PopFront(); + + Ptr nextFrame = NULL; + + if (!frames.IsEmpty()) + nextFrame = frames.PeekFront(0); + + while (nextFrame && nextFrame->ready) { + // Free up the current frame since it's been removed from the deque + currentFrame = frames.PopFront(); + + if (frames.IsEmpty()) + break; + + nextFrame = frames.PeekFront(0); + } + + if (currentFrame->imageData) + greyBitmap->CopyFromMemory(NULL, currentFrame->imageData, currentFrame->width); + + if (currentFrame->colorImageData) + colorBitmap->CopyFromMemory(NULL, currentFrame->colorImageData, currentFrame->colorPitch); + + pRT->BeginDraw(); + + pRT->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); + + pRT->Clear(D2D1::ColorF(D2D1::ColorF::Black)); + + // This will mirror our image + D2D1_MATRIX_3X2_F m; + m._11 = -1; + m._12 = 0; + m._21 = 0; + m._22 = 1; + m._31 = 0; + m._32 = 0; + pRT->SetTransform(m); + + ID2D1SolidColorBrush* whiteBrush; + + pRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White, 1.0f), &whiteBrush); + + if (currentFrame->imageData) { + pRT->FillOpacityMask( + greyBitmap, + whiteBrush, + D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL, + D2D1::RectF(-(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height), + // D2D1::RectF( 0.0f, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), + D2D1::RectF(0.0f, 0.0f, (FLOAT)resolution.width, (FLOAT)resolution.height)); + } else if (currentFrame->colorImageData) { + pRT->DrawBitmap( + colorBitmap, + D2D1::RectF(-(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height)); + } + + pRT->SetTransform(D2D1::Matrix3x2F::Identity()); + + whiteBrush->Release(); + + Array::Iterator it; + + for (it = currentFrame->plots.Begin(); it != currentFrame->plots.End(); ++it) { + ID2D1SolidColorBrush* aBrush; + + pRT->CreateSolidColorBrush(D2D1::ColorF(it->r, it->g, it->b), &aBrush); + + D2D1_ELLIPSE ellipse; + ellipse.point.x = it->x; + ellipse.point.y = it->y; + ellipse.radiusX = it->radius; + ellipse.radiusY = it->radius; + + if (it->fill) + pRT->FillEllipse(&ellipse, aBrush); + else + pRT->DrawEllipse(&ellipse, aBrush); + + aBrush->Release(); + } + + static const WCHAR msc_fontName[] = L"Verdana"; + static const FLOAT msc_fontSize = 20; + + IDWriteTextFormat* textFormat = NULL; + + // Create a DirectWrite text format object. + pDWriteFactory->CreateTextFormat( + msc_fontName, + NULL, + DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + msc_fontSize, + L"", // locale + &textFormat); + + D2D1_SIZE_F renderTargetSize = pRT->GetSize(); + + Array::Iterator textIt; + for (textIt = currentFrame->textLines.Begin(); textIt != currentFrame->textLines.End(); + ++textIt) { + ID2D1SolidColorBrush* aBrush; + + pRT->CreateSolidColorBrush(D2D1::ColorF(textIt->r, textIt->g, textIt->b), &aBrush); + + WCHAR* tmpString = (WCHAR*)calloc(textIt->text.GetLength(), sizeof(WCHAR)); + for (unsigned i = 0; i < textIt->text.GetLength(); ++i) { + tmpString[i] = (WCHAR)textIt->text.GetCharAt(i); + } + + pRT->DrawText( + tmpString, + (UINT32)textIt->text.GetLength(), + textFormat, + D2D1::RectF(textIt->x, textIt->y, renderTargetSize.width, renderTargetSize.height), + aBrush); + + free(tmpString); + + aBrush->Release(); + } + + if (textFormat) + textFormat->Release(); + + pRT->EndDraw(); + + pRT->Flush(); +} + +Ptr ImageWindow::lastUnreadyFrame() { + static int framenumber = 0; + + if (frames.GetSize() && !frames.PeekBack(0)->ready) + return frames.PeekBack(0); + + // Create a new frame if an unready one doesn't already exist + Ptr tmpFrame = *new Frame(framenumber); + frames.PushBack(tmpFrame); + + ++framenumber; + + return tmpFrame; +} + +void ImageWindow::UpdateImageBW(const uint8_t* imageData, uint32_t width, uint32_t height) { + if (pRT && greyBitmap) { + Mutex::Locker locker(frontBufferMutex); + + Ptr frame = lastUnreadyFrame(); + frame->imageData = malloc(width * height); + frame->width = width; + frame->height = height; + memcpy(frame->imageData, imageData, width * height); + } +} + +void ImageWindow::UpdateImageRGBA( + const uint8_t* imageData, + uint32_t width, + uint32_t height, + uint32_t pitch) { + if (pRT && colorBitmap) { + Mutex::Locker locker(frontBufferMutex); + + Ptr frame = lastUnreadyFrame(); + frame->colorImageData = malloc(pitch * height); + frame->width = width; + frame->height = height; + frame->colorPitch = pitch; + memcpy(frame->colorImageData, imageData, pitch * height); + } +} + +void ImageWindow::addCircle(float x, float y, float radius, float r, float g, float b, bool fill) { + if (pRT) { + CirclePlot cp; + + cp.x = x; + cp.y = y; + cp.radius = radius; + cp.r = r; + cp.g = g; + cp.b = b; + cp.fill = fill; + + Mutex::Locker locker(frontBufferMutex); + + Ptr frame = lastUnreadyFrame(); + frame->plots.PushBack(cp); + } +} + +void ImageWindow::addText(float x, float y, float r, float g, float b, OVR::String text) { + if (pRT) { + TextPlot tp; + + tp.x = x; + tp.y = y; + tp.r = r; + tp.g = g; + tp.b = b; + tp.text = text; + + Mutex::Locker locker(frontBufferMutex); + Ptr frame = lastUnreadyFrame(); + frame->textLines.PushBack(tp); + } +} +} // namespace Util +} // namespace OVR + +#else // defined(OVR_OS_WIN32) + +namespace OVR { +namespace Util { + +ImageWindow* ImageWindow::globalWindow[4]; +int ImageWindow::windowCount = 0; +} // namespace Util +} // namespace OVR + +#endif //#else //defined(OVR_OS_WIN32) diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_ImageWindow.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_ImageWindow.h new file mode 100644 index 0000000..a543000 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_ImageWindow.h @@ -0,0 +1,234 @@ +/************************************************************************************ + +Filename : Util_ImageWindow.h +Content : An output object for windows that can display raw images for testing +Created : March 13, 2014 +Authors : Dean Beeler + +Copyright : Copyright 2014 Oculus, Inc. All Rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_ImageWindow_h +#define OVR_Util_ImageWindow_h + +#if defined(OVR_OS_WIN32) +#include +#include +#include "Kernel/OVR_Win32_IncludeWindows.h" +#endif + +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_Deque.h" +#include "Kernel/OVR_Threads.h" + +#include + +namespace OVR { +namespace Util { + +typedef struct { + float x; + float y; + float radius; + float r; + float g; + float b; + bool fill; +} CirclePlot; + +typedef struct { + float x; + float y; + float r; + float g; + float b; + OVR::String text; +} TextPlot; + +class Frame : virtual public RefCountBaseV { + public: + Frame(int frame) + : frameNumber(frame), + plots(), + textLines(), + imageData(NULL), + colorImageData(NULL), + width(0), + height(0), + colorPitch(0), + ready(false) {} + + ~Frame() { + if (imageData) + free(imageData); + if (colorImageData) + free(colorImageData); + + plots.ClearAndRelease(); + textLines.ClearAndRelease(); + } + + int frameNumber; + + Array plots; + Array textLines; + void* imageData; + void* colorImageData; + int width; + int height; + int colorPitch; + bool ready; +}; + +#if defined(OVR_OS_WIN32) +class ImageWindow { + HWND hWindow; + ID2D1RenderTarget* pRT; + D2D1_SIZE_U resolution; + + std::unique_ptr frontBufferMutex; + + InPlaceMutableDeque> frames; + + ID2D1Bitmap* greyBitmap; + ID2D1Bitmap* colorBitmap; + + public: + // constructors + ImageWindow(); + ImageWindow(uint32_t width, uint32_t height); + virtual ~ImageWindow(); + + void GetResolution(size_t& width, size_t& height) { + width = resolution.width; + height = resolution.height; + } + + void OnPaint(); // Called by Windows when it receives a WM_PAINT message + + void UpdateImage(const uint8_t* imageData, uint32_t width, uint32_t height) { + UpdateImageBW(imageData, width, height); + } + void UpdateImageBW(const uint8_t* imageData, uint32_t width, uint32_t height); + void UpdateImageRGBA(const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch); + void Complete(); // Called by drawing thread to submit a frame + + void Process(); // Called by rendering thread to do window processing + + void AssociateSurface(void* surface); + + void addCircle(float x, float y, float radius, float r, float g, float b, bool fill); + void addText(float x, float y, float r, float g, float b, OVR::String text); + + static ImageWindow* GlobalWindow(int window) { + return globalWindow[window]; + } + static int WindowCount() { + return windowCount; + } + + private: + Ptr lastUnreadyFrame(); + + static const int MaxWindows = 4; + static ImageWindow* globalWindow[MaxWindows]; + static int windowCount; + static ID2D1Factory* pD2DFactory; + static IDWriteFactory* pDWriteFactory; + static HINSTANCE hInstD2d1; + static HINSTANCE hInstDwrite; +}; + +#else + +class ImageWindow { + public: + // constructors + ImageWindow() {} + ImageWindow(uint32_t width, uint32_t height) { + OVR_UNUSED(width); + OVR_UNUSED(height); + } + virtual ~ImageWindow() {} + + void GetResolution(size_t& width, size_t& height) { + width = 0; + height = 0; + } + + void OnPaint() {} + + void UpdateImage(const uint8_t* imageData, uint32_t width, uint32_t height) { + UpdateImageBW(imageData, width, height); + } + void UpdateImageBW(const uint8_t* imageData, uint32_t width, uint32_t height) { + OVR_UNUSED(imageData); + OVR_UNUSED(width); + OVR_UNUSED(height); + } + void UpdateImageRGBA(const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch) { + OVR_UNUSED(imageData); + OVR_UNUSED(width); + OVR_UNUSED(height); + OVR_UNUSED(pitch); + } + void Complete() {} + + void Process() {} + + void AssociateSurface(void* surface) { + OVR_UNUSED(surface); + } + + void addCircle(float x, float y, float radius, float r, float g, float b, bool fill) { + OVR_UNUSED(x); + OVR_UNUSED(y); + OVR_UNUSED(radius); + OVR_UNUSED(r); + OVR_UNUSED(g); + OVR_UNUSED(b); + OVR_UNUSED(fill); + } + void addText(float x, float y, float r, float g, float b, OVR::String text) { + OVR_UNUSED(x); + OVR_UNUSED(y); + OVR_UNUSED(r); + OVR_UNUSED(g); + OVR_UNUSED(b); + OVR_UNUSED(text); + } + + static ImageWindow* GlobalWindow(int window) { + return globalWindow[window]; + } + static int WindowCount() { + return windowCount; + } + + private: + static const int MaxWindows = 4; + static ImageWindow* globalWindow[4]; + static int windowCount; +}; + +#endif +} // namespace Util +} // namespace OVR + +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_LongPollThread.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_LongPollThread.cpp new file mode 100644 index 0000000..4eaaae4 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_LongPollThread.cpp @@ -0,0 +1,86 @@ +/************************************************************************************ + +Filename : Util_LongPollThread.cpp +Content : Allows us to do all long polling tasks from a single thread to minimize deadlock +risk +Created : June 30, 2013 +Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Util_LongPollThread.h" +#include "Util_Watchdog.h" + +OVR_DEFINE_SINGLETON(OVR::Util::LongPollThread); + +namespace OVR { +namespace Util { + +void LongPollThread::AddPollFunc(CallbackListener* func) { + PollSubject.AddListener(func); +} + +LongPollThread::LongPollThread() : Terminated(false) { + LongPollThreadHandle = std::make_unique([this] { this->Run(); }); + + // Must be at end of function + PushDestroyCallbacks(); +} + +LongPollThread::~LongPollThread() { + OVR_ASSERT(!LongPollThreadHandle->joinable()); +} + +void LongPollThread::OnThreadDestroy() { + fireTermination(); + + LongPollThreadHandle->join(); +} + +void LongPollThread::Wake() { + WakeEvent.SetEvent(); +} + +void LongPollThread::fireTermination() { + Terminated.store(true, std::memory_order_relaxed); + Wake(); +} + +void LongPollThread::OnSystemDestroy() { + delete this; +} + +void LongPollThread::Run() { + Thread::SetCurrentThreadName("LongPoll"); + WatchDog watchdog("LongPoll"); + + // While not terminated, + do { + watchdog.Feed(10000); + + PollSubject.Call(); + + WakeEvent.Wait(WakeupInterval); + WakeEvent.ResetEvent(); + } while (!Terminated.load(std::memory_order_acquire)); +} + +} // namespace Util +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_LongPollThread.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_LongPollThread.h new file mode 100644 index 0000000..6b4cf24 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_LongPollThread.h @@ -0,0 +1,76 @@ +/************************************************************************************ + +Filename : Util_LongPollThread.h +Content : Allows us to do all long polling tasks from a single thread to minimize deadlock +risk Created : June 30, 2013 Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_LongPollThread_h +#define OVR_Util_LongPollThread_h + +#include +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Atomic.h" +#include "Kernel/OVR_Callbacks.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Threads.h" +#include "Kernel/OVR_Timer.h" + +namespace OVR { +namespace Util { + +//----------------------------------------------------------------------------- +// LongPollThread + +// This thread runs long-polling subsystems that wake up every second or so +// The motivation is to reduce the number of threads that are running to minimize the risk of +// deadlock +class LongPollThread : public SystemSingletonBase { + OVR_DECLARE_SINGLETON(LongPollThread); + virtual void OnThreadDestroy() override; + + public: + typedef Delegate0 PollFunc; + static const int WakeupInterval = 1000; // milliseconds + + void AddPollFunc(CallbackListener* func); + + void Wake(); + + // debug method for assertion to maintain initialization order for this singleton + static bool IsInitialized(); + + protected: + CallbackEmitter PollSubject; + + std::atomic Terminated; + Event WakeEvent; + std::unique_ptr LongPollThreadHandle; + + void fireTermination(); + + void Run(); +}; +} // namespace Util +} // namespace OVR + +#endif // OVR_Util_LongPollThread_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.cpp new file mode 100644 index 0000000..7b347be --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.cpp @@ -0,0 +1,288 @@ +/************************************************************************************ + +Filename : Util_SystemGUI.cpp +Content : OS GUI access, usually for diagnostics. +Created : October 20, 2014 +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Util_SystemGUI.h" + +#include "Kernel/OVR_UTF8Util.h" +#if defined(OVR_OS_WIN32) +#include "Kernel/OVR_Win32_IncludeWindows.h" +#endif // OVR_OS_WIN32 +#include +#include +#include +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Std.h" + +namespace OVR { +namespace Util { + +bool DisplayMessageBoxVaList(const char* pTitle, const char* pFormat, va_list argList) { + char buffer[512]; + char* pBuffer = buffer; + std::unique_ptr pAllocated; + + va_list argListSaved; + OVR_VA_COPY(argListSaved, argList); + + int result = vsnprintf( + buffer, OVR_ARRAY_COUNT(buffer), pFormat, argList); // Returns the required strlen of buffer. + + if (result >= (int)OVR_ARRAY_COUNT(buffer)) // If there was insufficient capacity... + { + pAllocated = std::make_unique(result + 1); + pBuffer = pAllocated.get(); + + va_end(argList); // The caller owns argList and will call va_end on it. + OVR_VA_COPY(argList, argListSaved); + + vsnprintf(pBuffer, (size_t)result + 1, pFormat, argList); + } + + bool returnValue = DisplayMessageBox(pTitle, pBuffer); + + return returnValue; +} + +bool DisplayMessageBoxF(const char* pTitle, const char* pFormat, ...) { + va_list argList; + va_start(argList, pFormat); + bool returnValue = DisplayMessageBoxVaList(pTitle, pFormat, argList); + va_end(argList); + return returnValue; +} + +#if defined(OVR_OS_MS) + +// On Windows we implement a manual dialog message box. The reason for this is that there's no way +// to +// have a message box like this without either using MFC or WinForms or relying on Windows Vista+. + +bool DisplayMessageBox(const char* pTitle, const char* pText) { +#define ID_EDIT 100 + + struct Dialog { + static size_t LineCount(const char* pText) { + size_t count = 0; + while (*pText) { + if (*pText++ == '\n') + count++; + } + return count; + } + + static WORD* WordUp(WORD* pIn) { + return (WORD*)((((uintptr_t)pIn + 3) >> 2) << 2); + } + + static INT_PTR CALLBACK Proc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) { + switch (iMsg) { + case WM_INITDIALOG: { + HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT); + + const wchar_t* pText = (const wchar_t*)lParam; + SetWindowTextW(hWndEdit, pText); + + HFONT hFont = CreateFontW( + -11, + 0, + 0, + 0, + FW_DONTCARE, + FALSE, + FALSE, + FALSE, + ANSI_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, + DEFAULT_PITCH, + L"Courier New"); + if (hFont) + SendMessageW(hWndEdit, WM_SETFONT, WPARAM(hFont), TRUE); + + SendMessageW(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0); + + return TRUE; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case ID_EDIT: { + // Handle messages from the edit control here. + HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT); + SendMessageW(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0); + return TRUE; + } + + case IDOK: + EndDialog(hDlg, 0); + return TRUE; + case IDABORT: + _exit(0); // We don't call abort() because the visual studio runtime + // will capture the signal and throw up another dialog + } + break; + case WM_CLOSE: + + EndDialog(hDlg, 0); + return TRUE; + } + + return FALSE; + } + }; + + char dialogTemplateMemory[1024]; + memset(dialogTemplateMemory, 0, sizeof(dialogTemplateMemory)); + LPDLGTEMPLATEW pDlg = (LPDLGTEMPLATEW)dialogTemplateMemory; + + const size_t textLength = strlen(pText); + const size_t textLineCount = Dialog::LineCount(pText); + + // Sizes are in Windows dialog units, which are relative to a character size. Depends on the font + // and environment settings. Often the pixel size will be ~3x the dialog unit x size. Often the + // pixel size will be ~3x the dialog unit y size. + const int kGutterSize = 6; // Empty border space around controls within the dialog + const int kButtonWidth = 30; + const int kButtonHeight = 10; + const int kDialogWidth = + ((textLength > 1000) + ? 600 + : ((textLength > 400) ? 300 : 200)); // To do: Clip this against screen bounds. + const int kDialogHeight = + ((textLineCount > 100) ? 400 + : ((textLineCount > 25) ? 300 : ((textLineCount > 10) ? 200 : 100))); + + // Define a dialog box. + pDlg->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION; + pDlg->cdit = 3; // Control count + pDlg->x = 10; // X position To do: Center the dialog. + pDlg->y = 10; + pDlg->cx = (short)kDialogWidth; + pDlg->cy = (short)kDialogHeight; + WORD* pWord = (WORD*)(pDlg + 1); + *pWord++ = 0; // No menu + *pWord++ = 0; // Default dialog box class + + WCHAR* pWchar = (WCHAR*)pWord; + const size_t titleLength = strlen(pTitle); + size_t wcharCount = OVR::UTF8Util::Strlcpy(pWchar, 128, pTitle, titleLength); + + pWord += wcharCount + 1; + + // Define an OK button. + pWord = Dialog::WordUp(pWord); + + PDLGITEMTEMPLATEW pDlgItem = (PDLGITEMTEMPLATEW)pWord; + pDlgItem->x = pDlg->cx - (kGutterSize + kButtonWidth); + pDlgItem->y = pDlg->cy - (kGutterSize + kButtonHeight); + pDlgItem->cx = kButtonWidth; + pDlgItem->cy = kButtonHeight; + pDlgItem->id = IDOK; + pDlgItem->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; + + pWord = (WORD*)(pDlgItem + 1); + *pWord++ = 0xFFFF; + *pWord++ = 0x0080; // button class + + pWchar = (WCHAR*)pWord; + pWchar[0] = 'O'; + pWchar[1] = 'K'; + pWchar[2] = '\0'; // Not currently localized. + pWord += 3; // OK\0 + *pWord++ = 0; // no creation data + + // Define a QUIT button + pWord = Dialog::WordUp(pWord); + + pDlgItem = (PDLGITEMTEMPLATEW)pWord; + pDlgItem->x = pDlg->cx - ((kGutterSize + kButtonWidth) * 2); + pDlgItem->y = pDlg->cy - (kGutterSize + kButtonHeight); + pDlgItem->cx = kButtonWidth; + pDlgItem->cy = kButtonHeight; + pDlgItem->id = IDABORT; + pDlgItem->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; + + pWord = (WORD*)(pDlgItem + 1); + *pWord++ = 0xFFFF; + *pWord++ = 0x0080; // button class + + pWchar = (WCHAR*)pWord; + pWchar[0] = 'Q'; + pWchar[1] = 'U'; + pWchar[2] = 'I'; + pWchar[3] = 'T'; + pWchar[4] = '\0'; // Not currently localized. + pWord += 5; // QUIT\0 + *pWord++ = 0; // no creation data + + // Define an EDIT contol. + pWord = Dialog::WordUp(pWord); + + pDlgItem = (PDLGITEMTEMPLATEW)pWord; + pDlgItem->x = kGutterSize; + pDlgItem->y = kGutterSize; + pDlgItem->cx = pDlg->cx - (kGutterSize + kGutterSize); + pDlgItem->cy = pDlg->cy - (kGutterSize + kButtonHeight + kGutterSize + (kGutterSize / 2)); + pDlgItem->id = ID_EDIT; + pDlgItem->style = ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | + ES_READONLY | WS_VSCROLL | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE; + + pWord = (WORD*)(pDlgItem + 1); + *pWord++ = 0xFFFF; + *pWord++ = 0x0081; // edit class atom + *pWord++ = 0; // no creation data + + // We use SafeMMapAlloc instead of malloc/new because we may be in a situation with a broken heap, + // which triggered this message box. + LRESULT ret = 0; + size_t textBuffWCapacity = textLength + 1; + wchar_t* textBuffW = (wchar_t*)OVR::SafeMMapAlloc(textBuffWCapacity * sizeof(wchar_t)); + + if (textBuffW) { + OVR::UTF8Util::Strlcpy(textBuffW, textBuffWCapacity, pText, textLength); + ret = + DialogBoxIndirectParamW(NULL, (LPDLGTEMPLATEW)pDlg, NULL, Dialog::Proc, (LPARAM)textBuffW); + OVR::SafeMMapFree(textBuffW, textBuffWCapacity * sizeof(wchar_t)); + } + + return (ret != 0); +} + +#elif defined(OVR_OS_MAC) + +// For Apple we use the Objective C implementation in Util_GUI.mm + +#else + +// To do. +bool DisplayMessageBox(const char* pTitle, const char* pText) { + printf("\n\nMessageBox\n%s\n", pTitle); + printf("%s\n\n", pText); + return false; +} + +#endif +} // namespace Util +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.h new file mode 100644 index 0000000..862c267 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemGUI.h @@ -0,0 +1,43 @@ +/************************************************************************************ + +Filename : Util_SystemGUI.h +Content : OS GUI access, usually for diagnostics. +Created : October 20, 2014 +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_SystemGUI_h +#define OVR_Util_SystemGUI_h + +#include + +namespace OVR { +namespace Util { + +// Displays a modal message box on the default GUI display (not on a VR device). +// The message box interface (e.g. OK button) is not localized. +bool DisplayMessageBox(const char* pTitle, const char* pText); + +bool DisplayMessageBoxF(const char* pTitle, const char* pFormat, ...); + +bool DisplayMessageBoxVaList(const char* pTitle, const char* pFormat, va_list argList); +} // namespace Util +} // namespace OVR + +#endif // OVR_Util_SystemGUI_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemInfo.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemInfo.cpp new file mode 100644 index 0000000..42b3ffc --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemInfo.cpp @@ -0,0 +1,2329 @@ +/************************************************************************************ + +Filename : Util_SystemInfo.cpp +Content : Various operations to get information about the system +Created : September 26, 2014 +Author : Kevin Jenkins + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Util_SystemInfo.h" +#include +#include +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_Error.h" +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Threads.h" +#include "Kernel/OVR_Timer.h" +#include "Logging/Logging_Library.h" + +#if defined(OVR_OS_LINUX) +#include +#endif + +// Includes used for GetBaseOVRPath() +#ifdef OVR_OS_WIN32 +#include +#include +#include +#include +#include +#include +#include +#include +#include "Kernel/OVR_Win32_IncludeWindows.h" + +#pragma comment(lib, "Shlwapi") // PathFileExistsW +#pragma comment(lib, "Wtsapi32.lib") // WTSQuerySessionInformation +#pragma comment(lib, "pdh.lib") // PDH +#elif defined(OVR_OS_MS) // Other Microsoft OSs +// Nothing, thanks. +#else +#include +#include + +#ifdef OVR_OS_LINUX +#include +#include +#elif defined(OVR_OS_MAC) +#include +#endif + +#endif + +static ovrlog::Channel Logger("Util_SystemInfo"); + +namespace OVR { +namespace Util { + +// From http://blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx +#if defined(OVR_OS_WIN64) || defined(OVR_OS_WIN32) + +#pragma comment(lib, "version.lib") + +typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); + +bool Is64BitWindows() { +#if defined(_WIN64) + return TRUE; // 64-bit programs run only on Win64 +#elif defined(_WIN32) + // 32-bit programs run on both 32-bit and 64-bit Windows + // so must sniff + BOOL f64 = FALSE; + LPFN_ISWOW64PROCESS fnIsWow64Process; + + fnIsWow64Process = + (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process"); + if (NULL != fnIsWow64Process) { + return fnIsWow64Process(GetCurrentProcess(), &f64) && f64; + } + return FALSE; +#else + return FALSE; // Win64 does not support Win16 +#endif +} +#endif + +const char* OSAsString() { +#if defined(OVR_OS_IPHONE) + return "IPhone"; +#elif defined(OVR_OS_DARWIN) + return "Darwin"; +#elif defined(OVR_OS_MAC) + return "Mac"; +#elif defined(OVR_OS_BSD) + return "BSD"; +#elif defined(OVR_OS_WIN64) || defined(OVR_OS_WIN32) + if (Is64BitWindows()) + return "Win64"; + else + return "Win32"; +#elif defined(OVR_OS_ANDROID) + return "Android"; +#elif defined(OVR_OS_LINUX) + return "Linux"; +#elif defined(OVR_OS_BSD) + return "BSD"; +#else + return "Other"; +#endif +} + +uint64_t GetGuidInt() { + uint64_t g = Timer::GetTicksNanos(); + + uint64_t lastTime, thisTime; + int j; + // Sleep a small random time, then use the last 4 bits as a source of randomness + for (j = 0; j < 8; j++) { + lastTime = Timer::GetTicksNanos(); + Thread::MSleep(1); + // Note this does not actually sleep for "only" 1 millisecond + // necessarily. Since we do not call timeBeginPeriod(1) explicitly + // before invoking this function it may be sleeping for 10+ milliseconds. + thisTime = Timer::GetTicksNanos(); + uint64_t diff = thisTime - lastTime; + unsigned int diff4Bits = (unsigned int)(diff & 15); + diff4Bits <<= 32 - 4; + diff4Bits >>= j * 4; + ((char*)&g)[j] ^= diff4Bits; + } + + return g; +} + +String GetGuidString() { + uint64_t guid = GetGuidInt(); + + char buff[64]; +#if defined(OVR_CC_MSVC) + snprintf(buff, sizeof(buff), "%I64u", guid); +#else + snprintf(buff, sizeof(buff), "%llu", (unsigned long long)guid); +#endif + return String(buff); +} + +const char* GetProcessInfo() { +#if defined(OVR_CPU_X86_64) + return "64 bit"; +#elif defined(OVR_CPU_X86) + return "32 bit"; +#else + return "TODO"; +#endif +} + +#ifdef OVR_OS_WIN32 + +String OSVersionAsString() { + return GetSystemFileVersionStringW(L"\\kernel32.dll"); +} +String GetSystemFileVersionStringW(const wchar_t filePath[MAX_PATH]) { + wchar_t strFilePath[MAX_PATH]; // Local variable + UINT sysDirLen = GetSystemDirectoryW(strFilePath, ARRAYSIZE(strFilePath)); + if (sysDirLen != 0) { + OVR_wcscat(strFilePath, MAX_PATH, filePath); + return GetFileVersionStringW(strFilePath); + } else { + return "GetSystemDirectoryW failed"; + } +} + +// See +// http://stackoverflow.com/questions/940707/how-do-i-programatically-get-the-version-of-a-dll-or-exe-file +String GetFileVersionStringW(const wchar_t filePath[MAX_PATH]) { + String result; + + DWORD dwSize = GetFileVersionInfoSizeW(filePath, NULL); + if (dwSize == 0) { + Logger.LogDebugF( + "Error in GetFileVersionInfoSizeW: %d (for %s)", GetLastError(), String(filePath).ToCStr()); + result = String(filePath) + " not found"; + } else { + auto pVersionInfo = std::make_unique(dwSize); + if (!pVersionInfo) { + Logger.LogDebugF("Out of memory allocating %d bytes (for %s)", dwSize, filePath); + result = "Out of memory"; + } else { + if (!GetFileVersionInfoW(filePath, 0, dwSize, pVersionInfo.get())) { + Logger.LogDebugF( + "Error in GetFileVersionInfo: %d (for %s)", GetLastError(), String(filePath).ToCStr()); + result = "Cannot get version info"; + } else { + VS_FIXEDFILEINFO* pFileInfo = NULL; + UINT pLenFileInfo = 0; + + static HMODULE library; + static std::once_flag once; + std::call_once(once, [&]() { library = LoadLibraryW(L"version.dll"); }); + + decltype(&::VerQueryValueW) const call = reinterpret_cast( + GetProcAddress(library, "VerQueryValueW")); + + if (!call(pVersionInfo.get(), L"\\", (LPVOID*)&pFileInfo, &pLenFileInfo)) { + Logger.LogDebugF( + "Error in VerQueryValueW: %d (for %s)", GetLastError(), String(filePath).ToCStr()); + result = "File has no version info"; + } else { + int major = (pFileInfo->dwFileVersionMS >> 16) & 0xffff; + int minor = (pFileInfo->dwFileVersionMS) & 0xffff; + int hotfix = (pFileInfo->dwFileVersionLS >> 16) & 0xffff; + int other = (pFileInfo->dwFileVersionLS) & 0xffff; + + char str[128]; + snprintf(str, 128, "%d.%d.%d.%d", major, minor, hotfix, other); + + result = str; + } + } + } + } + + return result; +} + +String GetCameraDriverVersion() { + return GetSystemFileVersionStringW(L"\\drivers\\OCUSBVID.sys"); +} + +// From http://stackoverflow.com/questions/9524309/enumdisplaydevices-function-not-working-for-me +void GetGraphicsCardList(Array& gpus) { + gpus.Clear(); + DISPLAY_DEVICEW dd; + dd.cb = sizeof(dd); + + DWORD deviceNum = 0; + while (EnumDisplayDevicesW(NULL, deviceNum, &dd, 0)) { + if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) + gpus.PushBack(String(dd.DeviceString)); + deviceNum++; + } +} + +String GetProcessorInfo() { + char brand[0x40] = {}; + int cpui[4] = {-1}; + + __cpuidex(cpui, 0x80000002, 0); + + // unsigned int blocks = cpui[0]; + for (int i = 0; i <= 2; ++i) { + __cpuidex(cpui, 0x80000002 + i, 0); + *reinterpret_cast(brand + i * 16) = cpui[0]; + *reinterpret_cast(brand + 4 + i * 16) = cpui[1]; + *reinterpret_cast(brand + 8 + i * 16) = cpui[2]; + *reinterpret_cast(brand + 12 + i * 16) = cpui[3]; + } + return String(brand, 0x40); +} + +#else + +#ifdef OVR_OS_MAC +// use objective c source + +// used for driver files +String GetFileVersionString(String /*filePath*/) { + return String(); +} + +String GetSystemFileVersionString(String /*filePath*/) { + return String(); +} + +String GetDisplayDriverVersion() { + return String(); +} + +String GetCameraDriverVersion() { + return String(); +} + +#else + +String GetDisplayDriverVersion() { + char info[256] = {0}; + FILE* file = popen("/usr/bin/glxinfo", "r"); + if (file) { + int status = 0; + while (status == 0) { + status = fscanf(file, "%*[^\n]\n"); // Read up till the end of the current line, leaving the + // file pointer at the beginning of the next line + // (skipping any leading whitespace). + OVR_UNUSED(status); // Prevent GCC compiler warning: "ignoring return value of ‘int + // fscanf(FILE*, const char*, ...)" + + status = fscanf(file, "OpenGL version string: %255[^\n]", info); + } + pclose(file); + if (status == 1) { + return String(info); + } + } + return String("No graphics driver details found."); +} + +String GetCameraDriverVersion() { + struct utsname kver; + if (uname(&kver)) { + return String(); + } + return String(kver.release); +} + +void GetGraphicsCardList(OVR::Array& gpus) { + gpus.Clear(); + + char info[256] = {0}; + FILE* file = popen("/usr/bin/lspci", "r"); + if (file) { + int status = 0; + while (status >= 0) { + status = fscanf(file, "%*[^\n]\n"); // Read up till the end of the current line, leaving the + // file pointer at the beginning of the next line + // (skipping any leading whitespace). + OVR_UNUSED(status); // Prevent GCC compiler warning: "ignoring return value of ‘int + // fscanf(FILE*, const char*, ...)" + + status = fscanf(file, "%*[^ ] VGA compatible controller: %255[^\n]", info); + if (status == 1) { + gpus.PushBack(String(info)); + } + } + pclose(file); + } + if (gpus.GetSizeI() <= 0) { + gpus.PushBack(String("No video card details found.")); + } +} + +String OSVersionAsString() { + char info[256] = {0}; + FILE* file = fopen("/etc/issue", "r"); + if (file) { + int status = fscanf(file, "%255[^\n\\]", info); + fclose(file); + if (status == 1) { + return String(info); + } + } + return String("No OS version details found."); +} + +String GetProcessorInfo() { + char info[256] = {0}; + FILE* file = fopen("/proc/cpuinfo", "r"); + if (file) { + int status = 0; + while (status == 0) { + status = fscanf(file, "%*[^\n]\n"); // Read up till the end of the current line, leaving the + // file pointer at the beginning of the next line + // (skipping any leading whitespace). + OVR_UNUSED(status); // Prevent GCC compiler warning: "ignoring return value of ‘int + // fscanf(FILE*, const char*, ...)" + + status = fscanf(file, "model name : %255[^\n]", info); + } + fclose(file); + if (status == 1) { + return String(info); + } + } + return String("No processor details found."); +} +#endif // OVR_OS_MAC +#endif // WIN32 + +std::string GetProcessPath(pid_t processId, bool fileNameOnly, bool enableErrorResults) { + std::string result; + + if (processId == OVR_INVALID_PID) { + if (enableErrorResults) { + result = "(invalid PID)"; + } + } + +#if defined(OVR_OS_WIN32) + ScopedProcessHANDLE processHandle( + OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId)); + + if (processHandle.IsValid()) { + result = GetProcessPath(processHandle.Get(), fileNameOnly, enableErrorResults); + } else if (enableErrorResults) { + result = "(OpenProcess failure)"; + } + +#elif defined(OVR_OS_LINUX) + char procPath[1024]; + char linkPath[64]; + snprintf(linkPath, OVR_ARRAY_COUNT(linkPath), "/proc/%d/exe", processId); + + int readResult = readlink(linkPath, procPath, OVR_ARRAY_COUNT(procPath)); + + if ((readResult != -1) || (readResult >= int(OVR_ARRAY_COUNT(procPath)))) { + // If the file was deleted, its name will have "(deleted)" after it, which we may want to deal + // with. + procPath[readResult] = '\0'; + OVR_UNUSED(fileNameOnly); // To do. + } else + procPath[0] = '\0'; + result = procPath; + +#elif defined(OVR_OS_MAC) + char procPath[PROC_PIDPATHINFO_MAXSIZE]; + int ret = proc_pidpath(processId, procPath, sizeof(procPath)); + if (ret <= 0) { + Logger.LogDebugF("Unable to lookup PID: %d -- %s", processId, strerror(errno)); + procPath[0] = '\0'; + OVR_UNUSED(fileNameOnly); // To do. + } + result = procPath; +#endif + + return result; +} + +#if defined(_WIN32) +std::string GetProcessPath(HANDLE processHandle, bool fileNameOnly, bool enableErrorResults) { + std::string result; + WCHAR procPathW[MAX_PATH]; + DWORD processNameLength = OVR_ARRAY_COUNT(procPathW); + + if (QueryFullProcessImageNameW(processHandle, 0, procPathW, &processNameLength) != 0) { + result = OVR::UCSStringToUTF8String(procPathW); + + if (fileNameOnly) { + char fileName[_MAX_FNAME]; + fileName[0] = '\0'; + char fileExtension[_MAX_EXT]; + fileExtension[0] = '\0'; + + if (_splitpath_s( + result.c_str(), + nullptr, + 0, + nullptr, + 0, + fileName, + _MAX_FNAME, + fileExtension, + _MAX_EXT) == 0) { + result = fileName; + result += fileExtension; + } // Else leave it as its full path, though that will in practice rarely or never occur. + } + } else if (enableErrorResults) { + DWORD dwProcessId = GetProcessId(processHandle); + DWORD dwLastError = GetLastError(); + OVR::String strError; + if (dwLastError == 31) // Windows reports "A device attached to the system is not functioning." + strError = "Process has previously exited."; + else + OVR::GetSysErrorCodeString(ovrSysErrorCodeType::OS, dwLastError, false, strError); + + char buffer[256]; + snprintf( + buffer, + sizeof(buffer), + "(QueryFullProcessImageNameW failure for process handle 0x%llx, pid %u. Error code: %u: %s)", + (uint64_t)processHandle, + static_cast(dwProcessId), + static_cast(dwLastError), + strError.ToCStr()); + result = buffer; + } + + return result; +} +#endif + +// Same as GetProcessPath, except scrubs the returned process path string if it's something we have +// deemed +// cannot be reported in our log, usually due to privacy measures we have enacted. +std::string GetLoggableProcessPath(pid_t processId, bool fileNameOnly) { + std::string processPath = GetProcessPath(processId, fileNameOnly, true); + + // The following is currently disabled, as we decided to not redact side-loaded file names from + // the server log, and added a ReadMe.txt to the log folder which has a disclaimer about this. + // + //#ifdef OVR_INTERNAL_CODE + // // For internal builds, we do no scrubbing. + //#else + // // For public builds we scrub the process path if it's side-loaded. + // if (IsProcessSideLoaded(GetProcessPath(processId, false))) + // processPath = "(side-loaded app)"; + //#endif + + return processPath; +} + +#if defined(_WIN32) +// Same as GetProcessPath, except scrubs the returned process path string if it's something we have +// deemed +// cannot be reported in our log, usually due to privacy measures we have enacted. +std::string GetLoggableProcessPath(HANDLE processHandle, bool fileNameOnly) { + std::string processPath = GetProcessPath(processHandle, fileNameOnly, true); + + // The current design, which may change, is that we allow logging of process file paths in public + // builds. + //#ifdef OVR_INTERNAL_CODE + // // For internal builds, we do no scrubbing. + //#else + // // For public builds we scrub the process path if it's side-loaded. + // if (IsProcessSideLoaded(processPath)) + // processPath = "(side-loaded app)"; + //#endif + + return processPath; +} +#endif + +//----------------------------------------------------------------------------- +// Get a path under BaseOVRPath +// This version returns a std::wstring object. +std::wstring GetOVRPathW(const wchar_t* subPath, bool create_dir) { +#if defined(_WIN32) + wchar_t fullPath[MAX_PATH]; + SHGetFolderPathW(0, CSIDL_LOCAL_APPDATA, NULL, 0, fullPath); + PathAppendW(fullPath, L"Oculus"); + if (subPath != nullptr) { + OVR_ASSERT(subPath[0] != '\0' && subPath[0] != L'/' && subPath[0] != L'\\'); + PathAppendW(fullPath, subPath); + } + + if (create_dir) { + DWORD attrib = ::GetFileAttributesW(fullPath); + bool exists = attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY); + if (!exists) { + ::CreateDirectoryW(fullPath, NULL); + } + } + + return std::wstring(fullPath); +#else + std::wstring_convert> converter; + + const char* home = getenv("HOME"); + std::string path = home; + +#if defined(OVR_OS_MAC) + path += "/Library/Preferences/Oculus"; +#else + path += "/.config/Oculus"; +#endif + + if (subPath != nullptr) { + OVR_ASSERT(subPath[0] != '\0' && subPath[0] != L'/' && subPath[0] != L'\\'); + std::string narrow = converter.to_bytes(subPath); + path += "/"; + path += narrow; + } + + // Create the Oculus directory if it doesn't exist + if (create_dir) { + DIR* dir = opendir(path.c_str()); + if (dir == NULL) { + mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); + } else { + closedir(dir); + } + } + + return converter.from_bytes(path); +#endif +} +//----------------------------------------------------------------------------- +// Get a path under BaseOVRPath +// This version returns an OVR::String. +String GetOVRPath(const wchar_t* subPath, bool create_dir) { + return OVR::UCSStringToOVRString(GetOVRPathW(subPath, create_dir)); +} +//----------------------------------------------------------------------------- +// Get the (wide) path for local app data. +std::wstring GetBaseOVRPathW(bool create_dir) { + return GetOVRPathW(nullptr, create_dir); +} +//----------------------------------------------------------------------------- +// Get the path for local app data. +// This version returns an OVR::String. +String GetBaseOVRPath(bool create_dir) { + return GetOVRPath(nullptr, create_dir); +} + +#ifdef _WIN32 + +// subKey and stringName must point to 256 or greater buffers. +static bool +ParseRegistryPath(const char* path, HKEY& rootKey, wchar_t* subKey, wchar_t* stringName) { + std::wstring pathW = OVR::UTF8StringToUCSString(path); + + // We need to convert the path to a Windows registry path. + // "/HKEY_LOCAL_MACHINE/Software/Oculus/ForceGPUDriverVersionAcceptance" needs to convert + // to HKEY_LOCAL_MACHINE, "Software\\Oculus", "ForceGPUDriverVersionAcceptance". + std::replace(pathW.begin(), pathW.end(), L'/', L'\\'); // Convert / -> \ + + // Find the root key + if (pathW.find(L"\\HKEY_LOCAL_MACHINE\\") == 0) { + pathW.erase(0, wcslen(L"\\HKEY_LOCAL_MACHINE\\")); + rootKey = HKEY_LOCAL_MACHINE; + } else if (pathW.find(L"\\HKEY_CLASSES_ROOT\\") == 0) { + pathW.erase(0, wcslen(L"\\HKEY_CLASSES_ROOT\\")); + rootKey = HKEY_CLASSES_ROOT; + } else if (pathW.find(L"\\HKEY_CURRENT_CONFIG\\") == 0) { + pathW.erase(0, wcslen(L"\\HKEY_CURRENT_CONFIG\\")); + rootKey = HKEY_CURRENT_CONFIG; + } else if (pathW.find(L"\\HKEY_CURRENT_USER\\") == 0) { + pathW.erase(0, wcslen(L"\\HKEY_CURRENT_USER\\")); + rootKey = HKEY_CURRENT_USER; + } else if (pathW.find(L"\\HKEY_USERS\\") == 0) { + pathW.erase(0, wcslen(L"\\HKEY_USERS\\")); + rootKey = HKEY_USERS; + } else { + rootKey = 0; + subKey[0] = L'\0'; + stringName[0] = L'\0'; + return false; + } + + // pathW now looks like: "Software\\Oculus\\ForceGPUDriverVersionAcceptance" + + size_t lastSeparator = pathW.rfind('\\'); + if ((lastSeparator == std::wstring::npos) || ((pathW.length() - lastSeparator) > 256)) + return false; + + OVR_strlcpy(stringName, &pathW[lastSeparator + 1], 256); + pathW.erase(lastSeparator, pathW.length() - lastSeparator); + + // stringName now looks like: "ForceGPUDriverVersionAcceptance" + // pathW now looks like: "Software\\Oculus" + + if ((pathW.length()) >= 256) + return false; + + OVR_strlcpy(subKey, pathW.c_str(), 256); + + return true; +} + +#endif // _WIN32 + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// SettingsManager +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#if (__cplusplus >= 201103L) || (defined(_MSC_VER) && (_MSC_VER >= 1800)) // C++11 required + +SettingsManager DefaultSettingsManager; + +#ifdef _WIN32 +SettingsManager::Win32RegistryAnyValue::Win32RegistryAnyValue() + : type(REG_NONE), binaryData(), dwordData(), qwordData(), stringData(), stringArrayData() {} +#endif + +void SettingsManager::AddAlternativeLocation(const char* path) { +#ifdef _WIN32 + auto it = + std::find(RegistryAlternativeLocations.begin(), RegistryAlternativeLocations.end(), path); + if (it == RegistryAlternativeLocations.end()) + RegistryAlternativeLocations.insert(path); +#else + (void)path; +#endif +} + +void SettingsManager::RemoveAlternativeLocation(const char* path) { +#ifdef _WIN32 + auto it = RegistryAlternativeLocations.find(path); + if (it != RegistryAlternativeLocations.end()) + RegistryAlternativeLocations.erase(it); +#else + (void)path; +#endif +} + +SettingsManager::StringSet SettingsManager::GetAlternativeLocations() const { +#ifdef _WIN32 + return RegistryAlternativeLocations; +#else + return StringSet(); +#endif +} + +void SettingsManager::SetDefaultAlternativeLocations() { +#ifdef _WIN32 + // The following is disabled because we are using this are our default. + // RegistryAlternativeLocations.push_back("/HKEY_LOCAL_MACHINE/SOFTWARE/Oculus/"); + RegistryAlternativeLocations.insert("/HKEY_CURRENT_USER/SOFTWARE/Oculus/"); + RegistryAlternativeLocations.insert("/HKEY_LOCAL_MACHINE/SOFTWARE/Oculus VR, LLC/Oculus/"); + RegistryAlternativeLocations.insert("/HKEY_LOCAL_MACHINE/SOFTWARE/Oculus VR, LLC/LibOVR/"); + RegistryAlternativeLocations.insert( + "/HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Oculus VR, LLC/Oculus/"); + RegistryAlternativeLocations.insert( + "/HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Oculus VR, LLC/Oculus/Config/"); + RegistryAlternativeLocations.insert("/HKEY_CURRENT_USER/SOFTWARE/Oculus/Dash/"); + RegistryAlternativeLocations.insert(OVR_XRS_SETTINGS_LOCATION); +#endif +} + +#ifdef _WIN32 + +bool SettingsManager::Win32ReadAnyRegistryValue( + DWORD dwType, + uint8_t* data, + size_t dataSize, + Win32RegistryAnyValue& anyValue) const { + switch (dwType) { + case REG_BINARY: + anyValue.type = dwType; + anyValue.binaryData.assign(data, data + dataSize); + break; + + case REG_DWORD: + anyValue.type = dwType; + anyValue.dwordData = *reinterpret_cast(data); + break; + + case REG_QWORD: + anyValue.type = dwType; + anyValue.qwordData = *reinterpret_cast(data); + break; + + case REG_SZ: { + case REG_EXPAND_SZ: + anyValue.type = dwType; + std::wstring stringW(reinterpret_cast(data), (dataSize / sizeof(wchar_t)) - 1); + anyValue.stringData = + std::wstring_convert, wchar_t>().to_bytes(stringW); + break; + } + + case REG_MULTI_SZ: { + anyValue.type = dwType; + + for (wchar_t* p = reinterpret_cast(data); *p; p += (wcslen(p) + 1)) { + std::wstring stringW(p); + std::string string8 = + std::wstring_convert, wchar_t>().to_bytes(stringW); + anyValue.stringArrayData.emplace_back(string8); + } + break; + } + + default: + // Unsupported type. Leave anyValue.type as REG_NONE. + return false; + } + + return true; +} + +bool SettingsManager::Win32ReadAnyRegistryValue( + const char* path, + Win32RegistryAnyValue& anyValue, + int options) const { + bool success = false; + HKEY rootKey; // e.g. HKEY_CURRENT_USER/ + wchar_t subKey[256]; // e.g. Software/Oculus + wchar_t stringName[256]; // e.g. SomeValue + std::string fullPath; // Used in case path is relative. + + anyValue.type = REG_NONE; + + if (path[0] != '/') { // If this is a path relative to the default... make a full path. + fullPath = defaultLocation + path; + path = fullPath.c_str(); + } + + if (!ParseRegistryPath(path, rootKey, subKey, stringName)) + return false; + + int64_t iEnd = + ((options & OptionIgnoreAlternativeLocations) ? 0 + : (int64_t)RegistryAlternativeLocations.size()); + + // We do a loop starting with -1 because we are reading from two locations: the input path and + // an array of alternative locations. -1 is for the input path and 0+ is the alternative + // locations. + for (int64_t i = -1; !success && (i < iEnd); ++i) { + if (i >= 0) { // If the input path didn't find it... + // try reading from the alternative locations. + wchar_t stringNameIgnore[256]; + auto it = RegistryAlternativeLocations.begin(); + std::advance(it, (size_t)i); // This is a little slow, but not commonly called. + ParseRegistryPath(it->c_str(), rootKey, subKey, stringNameIgnore); + } // Else i == -1 and use the input path as-is. + + HKEY hKey = 0; // Always use the 64 bit registry view. All Oculus runtime software is 64 bit. + DWORD keyOptions = + KEY_QUERY_VALUE | ((options & OptionUse32BitDatabase) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); + LONG openResult = RegOpenKeyExW(rootKey, subKey, 0, keyOptions, &hKey); + + if (openResult == ERROR_SUCCESS) { + DWORD dwType; + uint8_t data[2048]; // We don't currently have handling for accepting data larger than this. + DWORD dataSize(2048); // We could add extra logic to support this if needed. + + // RegGetValue is like RegQueryValueEx except that Windows guarantees + // that string data is properly 0-terminated. RegGetValue returns ERROR_FILE_NOT_FOUND if + // the given value doesn't exist. + const DWORD flags = RRF_RT_REG_BINARY | RRF_RT_REG_DWORD | RRF_RT_REG_QWORD | RRF_RT_REG_SZ | + RRF_RT_REG_MULTI_SZ | RRF_RT_REG_EXPAND_SZ | + RRF_NOEXPAND; // NOEXPAND needed for RRF_RT_REG_EXPAND_SZ specifically on Win7 + LONG queryResult = RegGetValueW(hKey, nullptr, stringName, flags, &dwType, data, &dataSize); + + if (queryResult == ERROR_SUCCESS) // We don't currently support handling ERROR_MORE_DATA. + success = Win32ReadAnyRegistryValue(dwType, data, dataSize, anyValue); + + RegCloseKey(hKey); + } + } + + return success; +} + +#endif // _WIN32 + +bool SettingsManager::ReadValue(const char* path, std::vector& value, int options) { +#ifdef _WIN32 + Win32RegistryAnyValue anyValue; + + if (!Win32ReadAnyRegistryValue(path, anyValue, options)) + return false; + + switch (anyValue.type) { + case REG_BINARY: + value = anyValue.binaryData; + break; + + case REG_QWORD: + value.assign( + reinterpret_cast(&anyValue.qwordData), + reinterpret_cast(&anyValue.qwordData) + sizeof(anyValue.qwordData)); + break; + + case REG_DWORD: + value.assign( + reinterpret_cast(&anyValue.dwordData), + reinterpret_cast(&anyValue.dwordData) + sizeof(anyValue.dwordData)); + break; + + case REG_SZ: + case REG_EXPAND_SZ: + // Copy the trailing '\0'. + value.assign( + anyValue.stringData.c_str(), + anyValue.stringData.c_str() + anyValue.stringData.size() + 1); + break; + + case REG_MULTI_SZ: + if (!anyValue.stringArrayData.empty() && !anyValue.stringArrayData[0].empty()) { + // Copy the trailing '\0'. + value.assign( + anyValue.stringArrayData[0].c_str(), + anyValue.stringArrayData[0].c_str() + anyValue.stringArrayData[0].size() + 1); + } + break; + } + + return true; +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::ReadValue(const char* path, uint8_t* data, size_t& dataSize, int options) { + std::vector value; + + if (ReadValue(path, value, options)) { + if (value.size() <= dataSize) { + dataSize = std::min(value.size(), dataSize); + memcpy(data, value.data(), dataSize); + return true; + } + } + + return false; +} + +bool SettingsManager::ReadValue(const char* path, double& value, int options) { +#ifdef _WIN32 + Win32RegistryAnyValue anyValue; + + if (!Win32ReadAnyRegistryValue(path, anyValue, options)) + return false; + + try { // Some of the std C++ calls below can throw exceptions. + switch (anyValue.type) { + case REG_BINARY: + // reinterpreting binary as a floating point value is probably not something to rely on. + if (anyValue.binaryData.size() >= 8) + value = *reinterpret_cast(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 4) + value = *reinterpret_cast(anyValue.binaryData.data()); + break; + + case REG_QWORD: + value = (double)anyValue.qwordData; + break; + + case REG_DWORD: + value = (double)anyValue.dwordData; + break; + + case REG_SZ: + case REG_EXPAND_SZ: + value = std::stod(anyValue.stringData); // may throw an execption. + break; + + case REG_MULTI_SZ: + if (!anyValue.stringArrayData.empty() && !anyValue.stringArrayData[0].empty()) + value = std::stod(anyValue.stringArrayData[0]); // may throw an execption. + break; + } + } catch (...) { + // Leave value as-is. + } + + return true; +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::ReadValue(const char* path, float& value, int options) { + double valueDouble; + + if (!ReadValue(path, valueDouble, options)) + return false; + + value = (float)valueDouble; + return true; +} + +bool SettingsManager::ReadValue(const char* path, uint64_t& value, int options) { +#ifdef _WIN32 + Win32RegistryAnyValue anyValue; + + if (!Win32ReadAnyRegistryValue(path, anyValue, options)) + return false; + + try { // Some of the std C++ calls below can throw exceptions. + switch (anyValue.type) { + case REG_BINARY: + if (anyValue.binaryData.size() >= 8) + value = *reinterpret_cast(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 4) + value = *reinterpret_cast(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 2) + value = *reinterpret_cast(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 1) + value = *reinterpret_cast(anyValue.binaryData.data()); + break; + + case REG_QWORD: + value = anyValue.qwordData; + break; + + case REG_DWORD: + value = anyValue.dwordData; + break; + + case REG_SZ: + case REG_EXPAND_SZ: + value = std::stoull(anyValue.stringData, 0, 0); // may throw an execption. + break; + + case REG_MULTI_SZ: + if (!anyValue.stringArrayData.empty() && !anyValue.stringArrayData[0].empty()) + value = std::stoull(anyValue.stringArrayData[0], 0, 0); // may throw an execption. + break; + } + } catch (...) { + // Leave value as-is. + } + + return true; +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::ReadValue(const char* path, uint32_t& value, int options) { + uint64_t value64; + + if (!ReadValue(path, value64, options)) + return false; + + value = (uint32_t)value64; + return true; +} + +bool SettingsManager::ReadValue(const char* path, int64_t& value, int options) { +#ifdef _WIN32 + Win32RegistryAnyValue anyValue; + + if (!Win32ReadAnyRegistryValue(path, anyValue, options)) + return false; + + try { // Some of the std C++ calls below can throw exceptions. + switch (anyValue.type) { + case REG_BINARY: + if (anyValue.binaryData.size() >= 8) + value = *reinterpret_cast(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 4) + value = *reinterpret_cast(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 2) + value = *reinterpret_cast(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 1) + value = *reinterpret_cast(anyValue.binaryData.data()); + break; + + case REG_QWORD: + value = (int64_t)anyValue.qwordData; + break; + + case REG_DWORD: + value = (int64_t)((int32_t)anyValue.dwordData); + break; + + case REG_SZ: + case REG_EXPAND_SZ: + value = std::stoll(anyValue.stringData, 0, 0); // may throw an execption. + break; + + case REG_MULTI_SZ: + if (!anyValue.stringArrayData.empty() && !anyValue.stringArrayData[0].empty()) + value = std::stoll(anyValue.stringArrayData[0], 0, 0); // may throw an execption. + break; + } + } catch (...) { + // Leave value as-is. + } + + return true; +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::ReadValue(const char* path, int32_t& value, int options) { + int64_t value64; + + if (!ReadValue(path, value64, options)) + return false; + + value = (int32_t)value64; + return true; +} + +bool SettingsManager::ReadValue(const char* path, std::string& value, int options) { +#ifdef _WIN32 + Win32RegistryAnyValue anyValue; + + if (!Win32ReadAnyRegistryValue(path, anyValue, options)) + return false; + + // std::to_string usage below may throw std::bad_alloc, but we don't handle bad_alloc here, + // but rather we catch it at a higher level, as it's an indicator not of a data format problem, + // but of a system problem. In practice std::to_string will virtually never throw. + switch (anyValue.type) { + case REG_BINARY: + // When interpreting binary data as a string, how do we interpret the binary data? + // We write binary under two conditions: if the type is floating point and if the type + // is natively binary. Between floating point and binary, the only one which we can + // Possibly convert to a string with any consistency is floating point. + if (anyValue.binaryData.size() == sizeof(double)) { + const double* d = reinterpret_cast(anyValue.binaryData.data()); + value = std::to_string(*d); + } else { + // Currently we have no translation for this. We could potentially interpret it as + // string data, but the problem with that is that we would be inconsistent because + // we interpret the binary data as floating point if the length is 8 but a string + // for all other sizes. + return false; + } + break; + + case REG_QWORD: + value = std::to_string(anyValue.qwordData); + break; + + case REG_DWORD: + value = std::to_string(anyValue.dwordData); + break; + + case REG_SZ: + case REG_EXPAND_SZ: + value = anyValue.stringData; + break; + + case REG_MULTI_SZ: + if (!anyValue.stringArrayData.empty() && !anyValue.stringArrayData[0].empty()) + value = anyValue.stringArrayData[0]; + break; + } + + return true; +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::ReadValue(const char* path, std::wstring& value, int options) { + std::string value8; + + if (!ReadValue(path, value8, options)) // Read as UTF8 + return false; + + value = std::wstring_convert, wchar_t>().from_bytes(value8); + return true; +} + +bool SettingsManager::ReadValue(const char* path, bool& value, int options) { + uint64_t result64; + + if (!ReadValue(path, result64, options)) + return false; + + value = (result64 != 0); + return true; +} + +bool SettingsManager::WriteValue(const char* path, bool value, int options) { +#ifdef _WIN32 + // There's no Windows registry bool type, but the defacto standard for + // supporting it is to use the DWORD type as 0 or 1. + return WriteValue(path, value ? (uint32_t)1 : (uint32_t)0, options); +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::WriteValue(const char* path, const std::string& str, int options) { + return WriteValue(path, str.data(), str.size(), options); +} + +bool SettingsManager::WriteValue(const char* path, const std::wstring& str, int options) { + return WriteValue(path, str.data(), str.size(), options); +} + +bool SettingsManager::WriteValue( + const char* path, + const wchar_t* value, + size_t valueStrlen, + int options) { + // Caller is required to provide a 0-terminated string. + if (value[valueStrlen] != '\0') { + OVR_FAIL(); + return false; + } + +#ifdef _WIN32 + bool result = false; + HKEY rootKey; // e.g. HKEY_CURRENT_USER/ + wchar_t subKey[256]; // e.g. Software/Oculus + wchar_t stringName[256]; // e.g. SomeValue + + if (!ParseRegistryPath(path, rootKey, subKey, stringName)) + return false; + + // RegCreateKeyExW returns success if the key already exists. + HKEY hKey = 0; // Always use the 64 bit registry view. All Oculus runtime software is 64 bit. + DWORD keyOptions = KEY_CREATE_SUB_KEY | KEY_SET_VALUE | + ((options & OptionUse32BitDatabase) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); + LONG regResult = + RegCreateKeyExW(rootKey, subKey, 0, nullptr, 0, keyOptions, nullptr, &hKey, nullptr); + // If regResult fails with a value of 5 (ERROR_ACCESS_DENIED), it's often because the process + // is trying to write to HLEY_LOCAL_MACHINE and doesn't have admin privileges. + + if (regResult == ERROR_SUCCESS) { + regResult = RegSetValueExW( + hKey, + stringName, + 0, + REG_SZ, + reinterpret_cast(const_cast(value)), + (DWORD)(((valueStrlen + 1) * sizeof(wchar_t)))); + result = (regResult == ERROR_SUCCESS); + // Note that if the RegSetValueExW failed then we make no attempt to uncreate + // the key that may have been created above via RegCreateKeyExW. + RegCloseKey(hKey); + } + + return result; +#else + OVR_UNUSED2(path, options); + return false; +#endif +} + +bool SettingsManager::WriteValue( + const char* path, + const char* value, + size_t valueStrlen, + int options) { +#ifdef _WIN32 + std::wstring stringW = std::wstring_convert, wchar_t>().from_bytes( + value, value + valueStrlen); + return SettingsManager::WriteValue(path, stringW.c_str(), stringW.size(), options); +#else + OVR_UNUSED4(path, value, valueStrlen, options); + return false; +#endif +} + +bool SettingsManager::WriteValue(const char* path, uint32_t value, int options) { +#ifdef _WIN32 + bool result = false; + HKEY rootKey; // e.g. HKEY_CURRENT_USER/ + wchar_t subKey[256]; // e.g. Software/Oculus + wchar_t stringName[256]; // e.g. SomeValue + std::string fullPath; // Used in case path is relative. + + if (path[0] != '/') { // If this is a path relative to the default... make a full path. + fullPath = defaultLocation + path; + path = fullPath.c_str(); + } + + if (!ParseRegistryPath(path, rootKey, subKey, stringName)) + return false; + + // RegCreateKeyExW returns success if the key already exists. + HKEY hKey = 0; // Always use the 64 bit registry view. All Oculus runtime software is 64 bit. + DWORD keyOptions = KEY_CREATE_SUB_KEY | KEY_SET_VALUE | + ((options & OptionUse32BitDatabase) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); + LONG regResult = + RegCreateKeyExW(rootKey, subKey, 0, nullptr, 0, keyOptions, nullptr, &hKey, nullptr); + // If regResult fails with a value of 5 (ERROR_ACCESS_DENIED), it's often because the process + // is trying to write to HLEY_LOCAL_MACHINE and doesn't have admin privileges. + + if (regResult == ERROR_SUCCESS) { + regResult = RegSetValueExW( + hKey, stringName, 0, REG_DWORD, reinterpret_cast(&value), sizeof(value)); + result = (regResult == ERROR_SUCCESS); + // Note that if the RegSetValueExW failed then we make no attempt to uncreate + // the key that may have been created above via RegCreateKeyExW. + RegCloseKey(hKey); + } + + return result; +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::WriteValue(const char* path, int32_t value, int options) { +#ifdef _WIN32 + // If we write it as uint32_t bits, when we read it back as int32_t bits it will be as expected. + return SettingsManager::WriteValue(path, (uint32_t)value, options); +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::WriteValue(const char* path, uint64_t value, int options) { +#ifdef _WIN32 + bool result = false; + HKEY rootKey; // e.g. HKEY_CURRENT_USER/ + wchar_t subKey[256]; // e.g. Software/Oculus + wchar_t stringName[256]; // e.g. SomeValue + std::string fullPath; // Used in case path is relative. + + if (path[0] != '/') { // If this is a path relative to the default... make a full path. + fullPath = defaultLocation + path; + path = fullPath.c_str(); + } + + if (!ParseRegistryPath(path, rootKey, subKey, stringName)) + return false; + + // RegCreateKeyExW returns success if the key already exists. + HKEY hKey = 0; // Always use the 64 bit registry view. All Oculus runtime software is 64 bit. + DWORD keyOptions = KEY_CREATE_SUB_KEY | KEY_SET_VALUE | + ((options & OptionUse32BitDatabase) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); + LONG regResult = + RegCreateKeyExW(rootKey, subKey, 0, nullptr, 0, keyOptions, nullptr, &hKey, nullptr); + // If regResult fails with a value of 5 (ERROR_ACCESS_DENIED), it's often because the process + // is trying to write to HLEY_LOCAL_MACHINE and doesn't have admin privileges. + + if (regResult == ERROR_SUCCESS) { + regResult = RegSetValueExW( + hKey, stringName, 0, REG_QWORD, reinterpret_cast(&value), sizeof(value)); + result = (regResult == ERROR_SUCCESS); + // Note that if the RegSetValueExW failed then we make no attempt to uncreate + // the key that may have been created above via RegCreateKeyExW. + RegCloseKey(hKey); + } + + return result; +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::WriteValue(const char* path, int64_t value, int options) { +#ifdef _WIN32 + // If we write it as uint32_t bits, when we read it back as int32_t bits it will be as expected. + return SettingsManager::WriteValue(path, (uint64_t)value, options); +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::WriteValue(const char* path, double value, int options) { +#ifdef _WIN32 + // There's no explicit Windows registry support for writing floating point data, + // but the only lossless way to do is is to use REG_BINARY. + return WriteValue(path, reinterpret_cast(&value), sizeof(value), options); +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::WriteValue(const char* path, float value, int options) { +#ifdef _WIN32 + // There's no explicit Windows registry support for writing floating point data, + // but the only lossless way to do is is to use REG_BINARY. + return WriteValue(path, reinterpret_cast(&value), sizeof(value), options); +#else + OVR_UNUSED3(path, value, options); + return false; +#endif +} + +bool SettingsManager::WriteValue( + const char* path, + const uint8_t* value, + size_t valueSize, + int options) { +#ifdef _WIN32 + bool result = false; + HKEY rootKey; // e.g. HKEY_CURRENT_USER/ + wchar_t subKey[256]; // e.g. Software/Oculus + wchar_t stringName[256]; // e.g. SomeValue + std::string fullPath; // Used in case path is relative. + + if (path[0] != '/') { // If this is a path relative to the default... make a full path. + fullPath = defaultLocation + path; + path = fullPath.c_str(); + } + + if (!ParseRegistryPath(path, rootKey, subKey, stringName)) + return false; + + // RegCreateKeyExW returns success if the key already exists. + HKEY hKey = 0; // Always use the 64 bit registry view. All Oculus runtime software is 64 bit. + DWORD keyOptions = KEY_CREATE_SUB_KEY | KEY_SET_VALUE | + ((options & OptionUse32BitDatabase) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); + LONG regResult = + RegCreateKeyExW(rootKey, subKey, 0, nullptr, 0, keyOptions, nullptr, &hKey, nullptr); + // If regResult fails with a value of 5 (ERROR_ACCESS_DENIED), it's often because the process + // is trying to write to HLEY_LOCAL_MACHINE and doesn't have admin privileges. + + if (regResult == ERROR_SUCCESS) { + regResult = RegSetValueExW( + hKey, stringName, 0, REG_BINARY, const_cast(value), (DWORD)valueSize); + result = (regResult == ERROR_SUCCESS); + // Note that if the RegSetValueExW failed then we make no attempt to uncreate + // the key that may have been created above via RegCreateKeyExW. + RegCloseKey(hKey); + } + + return result; +#else + OVR_UNUSED4(path, value, valueSize, options); + return false; +#endif +} + +bool SettingsManager::ValueExists(const char* path, int options) const { +#ifdef _WIN32 + Win32RegistryAnyValue anyValue; + return Win32ReadAnyRegistryValue(path, anyValue, options); +#else + OVR_UNUSED2(path, options); + return false; +#endif +} + +bool SettingsManager::DeleteValue(const char* path, bool* wasPresent, int options) { +#ifdef _WIN32 + bool result = true; // True until proven false below. + + if (wasPresent) + *wasPresent = false; + + std::vector registryLocations; + + if ((options & OptionIgnoreAlternativeLocations) == 0) + registryLocations.insert( + registryLocations.begin(), + RegistryAlternativeLocations.begin(), + RegistryAlternativeLocations.end()); + + registryLocations.emplace_back(std::string(path)); + + for (const auto& pathStr : registryLocations) { + HKEY rootKey; // e.g. HKEY_CURRENT_USER/ + wchar_t subKey[256]; // e.g. Software/Oculus + wchar_t stringName[256]; // e.g. SomeValue + std::string fullPath; // Used in case path is relative. + + path = pathStr.c_str(); + + if (path[0] != '/') { // If this is a path relative to the default... make a full path. + fullPath = defaultLocation + path; + path = fullPath.c_str(); + } + + Win32RegistryAnyValue anyValue; + anyValue.type = REG_NONE; + + if (ParseRegistryPath(path, rootKey, subKey, stringName)) { + HKEY hKey; + DWORD keyOptions = KEY_QUERY_VALUE | KEY_SET_VALUE | + ((options & OptionUse32BitDatabase) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); + + if (RegOpenKeyExW(rootKey, subKey, 0, keyOptions, &hKey) == ERROR_SUCCESS) { + // Unfortunately, Windows provides no way to properly tell if a value deletion + // attempt failed due to the value not existing. The error code from RegDeleteValue + // can't tell you this. You can call RegQueryValue before calling RegDeleteValue to + // tell if it pre-existed, but between your call to RegQueryValue and RegDeleteValue + // another thread may have deleted it and give you a false error return from + // RegDeleteValue. Our best response to this is to check the value again and if it's + // mising then we know somebody else deleted it. + DWORD dwType; + + if (RegGetValueW(hKey, nullptr, stringName, RRF_RT_ANY, &dwType, nullptr, nullptr) == + ERROR_SUCCESS) { + if (wasPresent) + *wasPresent = true; + + if (RegDeleteValueW(hKey, stringName) != ERROR_SUCCESS) // If failed... + result = + (RegGetValueW(hKey, nullptr, stringName, RRF_RT_ANY, &dwType, nullptr, nullptr) != + ERROR_SUCCESS); + // If result fails with a value of 5 (ERROR_ACCESS_DENIED), it's often because the process + // is trying to write to HLEY_LOCAL_MACHINE and doesn't have admin privileges. + } + + RegCloseKey(hKey); + } + } + } + + return result; +#else + OVR_UNUSED2(path, options); + if (wasPresent) + *wasPresent = false; + return true; +#endif +} + +void SettingsManager::SetDefaultLocation(const char* parentPath) { + OVR_ASSERT(parentPath && (parentPath[0] == '/' || parentPath[0] == '\0')); + defaultLocation = parentPath; +} + +std::string SettingsManager::GetDefaultLocation() const { + return defaultLocation; +} + +std::string SettingsManager::EnumerateValues(const char* parentPath, int options) const { + std::string result; + +#ifdef _WIN32 + HKEY rootKey; // e.g. HKEY_CURRENT_USER/ + wchar_t subKey[256]; // e.g. Software/Oculus + wchar_t stringName[256]; // e.g. SomeValue + + if (!parentPath) + parentPath = defaultLocation.c_str(); + + int64_t kEnd = + ((options & OptionIgnoreAlternativeLocations) ? 0 + : (int64_t)RegistryAlternativeLocations.size()); + + // We do a loop starting with -1 because we are reading from two locations: the input path and + // an array of alternative locations. -1 is for the input path and 0+ is the alternative + // locations. + for (int64_t k = -1; k < kEnd; ++k) { + if (k >= 0) { + auto it = RegistryAlternativeLocations.begin(); + std::advance(it, (size_t)k); // This is a little slow, but not commonly called. + parentPath = it->c_str(); + } + // Assert that parentPath begins and ends with /. + OVR_ASSERT(parentPath && (parentPath[0] == '/') && (parentPath[strlen(parentPath) - 1] == '/')); + + if (!ParseRegistryPath(parentPath, rootKey, subKey, stringName)) { + return ""; + } + + HKEY hKey = 0; // Always use the 64 bit registry view. All Oculus runtime software is 64 bit. + LONG openResult = RegOpenKeyExW(rootKey, subKey, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey); + + if (openResult == ERROR_SUCCESS) { + LONG regResult = ERROR_SUCCESS; + + for (DWORD j = 0; regResult != ERROR_NO_MORE_ITEMS; ++j) { + DWORD dwType; + DWORD stringNameSize = OVR_ARRAY_COUNT(stringName); + uint8_t data[2048]; + DWORD dataSize(2048); + + regResult = + RegEnumValueW(hKey, j, stringName, &stringNameSize, nullptr, &dwType, data, &dataSize); + + if (regResult == ERROR_SUCCESS) { // There's also ERROR_MORE_DATA. + Win32RegistryAnyValue anyValue; + + if (Win32ReadAnyRegistryValue(dwType, data, dataSize, anyValue)) { + char buffer[256]; + + snprintf(buffer, sizeof(buffer), "%s%ls: ", parentPath, stringName); + result += buffer; + + switch (dwType) { + case REG_BINARY: + result += "binary: "; + + for (size_t i = 0, iEnd = std::min(64, anyValue.binaryData.size()); + i < iEnd; + ++i) { + snprintf(buffer, sizeof(buffer), "%02x ", anyValue.binaryData[i]); + result += buffer; + } + + if (anyValue.binaryData.size() > 64) // If we had to truncate it... + result += "..."; + + result += "\n"; + break; + + case REG_QWORD: + snprintf( + buffer, + sizeof(buffer), + "uint64: %llu (%#llx)\n", + anyValue.qwordData, + anyValue.qwordData); + result += buffer; + break; + + case REG_DWORD: + snprintf( + buffer, + sizeof(buffer), + "uint32: %u (%#x)\n", + anyValue.dwordData, + anyValue.dwordData); + result += buffer; + break; + + case REG_SZ: + case REG_EXPAND_SZ: + static_assert(sizeof(buffer) >= 256, "buffer size failure"); + snprintf( + buffer, + sizeof(buffer), + "string: %.250s%s\n", + anyValue.stringData.c_str(), + anyValue.stringData.size() >= 256 ? "..." : ""); + result += buffer; + break; + + case REG_MULTI_SZ: + result += "string array: "; + for (size_t i = 0; i < std::max(8, anyValue.stringArrayData.size()); ++i) { + snprintf( + buffer, + sizeof(buffer), + "%s%.250s%s\n", + i > 0 ? " " : "", + anyValue.stringArrayData[i].c_str(), + anyValue.stringData.size() >= 256 ? "..." : ""); + result += buffer; + } + if (anyValue.stringArrayData.size() >= 256) // If we had to truncate it... + result += "...\n"; + break; + + default: { + OVR_FAIL(); + } + } + } + } + } + } + } +#else + OVR_UNUSED2(parentPath, options); + OVR_FAIL(); +#endif + return result; +} + +#endif //#if (__cplusplus >= 201103L) // C++11 required + +#ifdef _WIN32 + +bool GetRegistryDwordW( + const wchar_t* pSubKey, + const wchar_t* stringName, + DWORD& out, + RegistryDB registryDB, + RegistryBase registryBase) { + HKEY root = (registryBase == RegistryBase::currentUser) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; + DWORD dwType = REG_DWORD; + HKEY hKey = 0; + DWORD value_length = sizeof(DWORD); + + if ((RegOpenKeyExW( + root, + pSubKey, + 0, + KEY_QUERY_VALUE | + ((registryDB == RegistryDB::wow64_32) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY), + &hKey) != ERROR_SUCCESS) || + (RegQueryValueExW(hKey, stringName, NULL, &dwType, (LPBYTE)&out, &value_length) != + ERROR_SUCCESS) || + (dwType != REG_DWORD)) { + out = 0; + RegCloseKey(hKey); + return false; + } + RegCloseKey(hKey); + + return true; +} + +// When reading Oculus registry keys, we recognize that the user may have inconsistently +// used a DWORD 1 vs. a string "1", and so we support either when checking booleans. +bool GetRegistryBoolW( + const wchar_t* pSubKey, + const wchar_t* stringName, + bool defaultValue, + RegistryDB registryDB, + RegistryBase registryBase) { + wchar_t out[MAX_PATH]; + if (GetRegistryStringW(pSubKey, stringName, out, registryDB, registryBase)) { + return (_wtoi64(out) != 0); + } + + DWORD dw; + if (GetRegistryDwordW(pSubKey, stringName, dw, registryDB, registryBase)) { + return (dw != 0); + } + + return defaultValue; +} + +bool GetRegistryStringW( + const wchar_t* pSubKey, + const wchar_t* stringName, + wchar_t out[MAX_PATH], + RegistryDB registryDB, + RegistryBase registryBase) { + HKEY root = (registryBase == RegistryBase::currentUser) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; + DWORD dwType = REG_SZ; + HKEY hKey = 0; + wchar_t value[MAX_PATH + 1]; // +1 because RegQueryValueEx doesn't necessarily 0-terminate. + DWORD value_length = MAX_PATH; + + if ((RegOpenKeyExW( + root, + pSubKey, + 0, + KEY_QUERY_VALUE | + ((registryDB == RegistryDB::wow64_32) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY), + &hKey) != ERROR_SUCCESS) || + (RegQueryValueExW(hKey, stringName, NULL, &dwType, (LPBYTE)&value, &value_length) != + ERROR_SUCCESS) || + (dwType != REG_SZ)) { + out[0] = L'\0'; + RegCloseKey(hKey); + return false; + } + RegCloseKey(hKey); + + value[value_length] = L'\0'; + wcscpy_s(out, MAX_PATH, value); + return true; +} + +bool SetRegistryDwordW( + const wchar_t* pSubKey, + const wchar_t* stringName, + DWORD newValue, + RegistryDB registryDB, + RegistryBase registryBase) { + HKEY root = (registryBase == RegistryBase::currentUser) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; + HKEY hKey = 0; + + if ((RegCreateKeyExW( + root, + pSubKey, + 0, + nullptr, + 0, + KEY_CREATE_SUB_KEY | KEY_SET_VALUE | + ((registryDB == RegistryDB::wow64_32) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY), + nullptr, + &hKey, + nullptr) != ERROR_SUCCESS) || + (RegSetValueExW( + hKey, stringName, 0, REG_DWORD, reinterpret_cast(&newValue), sizeof(newValue)) != + ERROR_SUCCESS)) { + RegCloseKey(hKey); + return false; + } + RegCloseKey(hKey); + return true; +} + +bool DeleteRegistryValue( + const wchar_t* pSubKey, + const wchar_t* stringName, + RegistryDB registryDB, + RegistryBase registryBase) { + HKEY root = (registryBase == RegistryBase::currentUser) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; + HKEY hKey = 0; + + if (RegOpenKeyExW( + root, + pSubKey, + 0, + KEY_ALL_ACCESS | + ((registryDB == RegistryDB::wow64_32) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY), + &hKey) != ERROR_SUCCESS) { + RegCloseKey(hKey); + return false; + } + bool result = (RegDeleteValueW(hKey, stringName) == ERROR_SUCCESS); + + RegCloseKey(hKey); + return result; +} + +String GetMachineTags() { + // We check both HKLM and HKCU for machine tags and append HKCU tags onto + // HKLM tags. The tag list is comma separated. + std::wstring allTags; + std::wstring tempStr; + + if (DefaultSettingsManager.ReadValue( + "/HKEY_LOCAL_MACHINE/Software/Oculus/MachineTags", + tempStr, + SettingsManager::OptionIgnoreAlternativeLocations)) + allTags = tempStr; + + if (DefaultSettingsManager.ReadValue( + "/HKEY_CURRENT_USER/Software/Oculus/MachineTags", + tempStr, + SettingsManager::OptionIgnoreAlternativeLocations)) { + if (!allTags.empty()) + allTags += L","; + allTags += tempStr; + } + + return OVR::String(OVR::UCSStringToUTF8String(allTags).c_str()); +} + +std::wstring GetOVRRuntimePathW() { + std::wstring result; + + // HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Oculus VR, LLC\Oculus\Base + if (DefaultSettingsManager.ReadValue( + "/HKEY_LOCAL_MACHINE/SOFTWARE/Oculus VR, LLC/Oculus/Base", + result, + SettingsManager::OptionUse32BitDatabase)) { + // Default case + } else { + // If our registry value gets corrupted we should attempt to use + // a sensible value. + result = L"C:\\Program Files\\Oculus\\"; + } + + // At this point, runtimePath is usually "C:\Program Files\Oculus\", so append what we need to + // it. + result += L"Support\\oculus-runtime"; + + return result; +} +#endif // _WIN32 + +#if OVR_UTIL_STD_FILESYSTEM_AVAILABLE + +std::filesystem::path GetCurrentModuleDirectoryPath() { + namespace fs = std::filesystem; + +#ifdef _WIN32 + // Get the module handle to the currently executing code. Can't use NULL or GetModuleHandle(NULL), + // as that will return the parent exe and not the current module (dll or exe). + HMODULE hModule = NULL; + BOOL result = GetModuleHandleExW( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPWSTR)GetCurrentModuleDirectoryPath, + &hModule); + + if (result) { // Should always succeed. + std::array path{}; + + if (GetModuleFileNameW(hModule, path.data(), (DWORD)path.size())) { // Should always succeed. + auto fsPath = fs::path(path.data()); + return fsPath.parent_path(); + } + } +#endif + + return fs::path(); +} + +#endif // defined(__cpp_lib_filesystem) + +// Returns if the computer is currently locked +bool CheckIsComputerLocked() { +#ifdef OVR_OS_MS + LPWSTR pBuf = nullptr; + DWORD bytesReturned = 0; + + if (::WTSQuerySessionInformationW( + WTS_CURRENT_SERVER_HANDLE, + WTS_CURRENT_SESSION, + WTSSessionInfoEx, + &pBuf, + &bytesReturned)) { + if (pBuf && bytesReturned >= sizeof(WTSINFOEX)) { + WTSINFOEXW* info = (WTSINFOEXW*)pBuf; + + WTSINFOEX_LEVEL1_W* level1 = (WTSINFOEX_LEVEL1_W*)&info->Data; + + bool isLocked = false; + + if (level1->SessionFlags == WTS_SESSIONSTATE_LOCK) { + isLocked = true; + } else if (level1->SessionFlags != WTS_SESSIONSTATE_UNLOCK) // if not unlocked, we expect + // locked + { + Logger.LogErrorF("Unknown Lock State = %d", (int)level1->SessionFlags); + } + + // Note: On Windows 7, the locked and unlocked flags are reversed! + // See: https://msdn.microsoft.com/en-us/library/windows/desktop/ee621019(v=vs.85).aspx + if (IsAtMostWindowsVersion(WindowsVersion::Windows7_SP1)) { + isLocked = !isLocked; + } + + return isLocked; + } else { + Logger.LogErrorF("Wrong return size from WTSQuerySessionInformation %u", bytesReturned); + } + if (pBuf) { + WTSFreeMemory(pBuf); + } + } +#endif // OVR_OS_MS + return false; +} + +#ifdef OVR_OS_MS + +static INIT_ONCE OSVersionInitOnce = INIT_ONCE_STATIC_INIT; +static uint32_t OSVersion; +static uint32_t OSBuildNumber; + +BOOL CALLBACK VersionCheckInitOnceCallback(PINIT_ONCE, PVOID, PVOID*) { + typedef NTSTATUS(WINAPI * pfnRtlGetVersion)(PRTL_OSVERSIONINFOEXW lpVersionInformation); + + NTSTATUS status = STATUS_DLL_NOT_FOUND; + + HMODULE hNTDll = LoadLibraryW(L"ntdll.dll"); + OVR_ASSERT(hNTDll); + + if (hNTDll) { + status = STATUS_ENTRYPOINT_NOT_FOUND; + + pfnRtlGetVersion pRtlGetVersion = (pfnRtlGetVersion)GetProcAddress(hNTDll, "RtlGetVersion"); + OVR_ASSERT(pRtlGetVersion); + + if (pRtlGetVersion) { + RTL_OSVERSIONINFOEXW OSVersionInfoEx; + OSVersionInfoEx.dwOSVersionInfoSize = sizeof(OSVersionInfoEx); + status = pRtlGetVersion(&OSVersionInfoEx); + OVR_ASSERT(status == 0); + + if (status == 0) { + OSVersion = OSVersionInfoEx.dwMajorVersion * 100 + OSVersionInfoEx.dwMinorVersion; + OSBuildNumber = OSVersionInfoEx.dwBuildNumber; + } + } + + FreeLibrary(hNTDll); + } + + if (status != 0) { + Logger.LogErrorF( + "[VersionCheckInitOnceCallback] Failed to obtain OS version information. 0x%08x", status); + } + + return (status == 0); +} + +#endif // OVR_OS_MS + +bool IsAtLeastWindowsVersion(WindowsVersion version) { +#ifdef OVR_OS_MS + if (!InitOnceExecuteOnce(&OSVersionInitOnce, VersionCheckInitOnceCallback, nullptr, nullptr)) { + OVR_ASSERT(false); + return false; + } + + switch (version) { + case WindowsVersion::Windows10_TH2: + return (OSVersion > 1000) || (OSVersion == 1000 && OSBuildNumber >= 10586); + + case WindowsVersion::Windows10: + return (OSVersion >= 1000); + + case WindowsVersion::Windows8_1: + return (OSVersion >= 603); + + case WindowsVersion::Windows8: + return (OSVersion >= 602); + + case WindowsVersion::Windows7_SP1: + return (OSVersion >= 601) && (OSBuildNumber >= 7601); + + default: + OVR_ASSERT(false); // Forget to add a case for a new OS? + return false; + } +#else // OVR_OS_MS + OVR_UNUSED(version); + return false; +#endif // OVR_OS_MS +} + +bool IsAtMostWindowsVersion(WindowsVersion version) { +#ifdef OVR_OS_MS + if (!InitOnceExecuteOnce(&OSVersionInitOnce, VersionCheckInitOnceCallback, nullptr, nullptr)) { + OVR_ASSERT(false); + return false; + } + + switch (version) { + case WindowsVersion::Windows10_TH2: + return (OSVersion < 1000) || (OSVersion == 1000 && OSBuildNumber <= 10586); + + case WindowsVersion::Windows10: + return (OSVersion < 1000) || (OSVersion == 1000 && OSBuildNumber == 10000); + + case WindowsVersion::Windows8_1: + return (OSVersion <= 603); + + case WindowsVersion::Windows8: + return (OSVersion <= 602); + + case WindowsVersion::Windows7_SP1: + return (OSVersion < 601) || (OSVersion == 601 && OSBuildNumber <= 7601); + + default: + OVR_ASSERT(false); // Forget to add a case for a new OS? + return false; + } +#else // OVR_OS_MS + OVR_UNUSED(version); + return false; +#endif // OVR_OS_MS +} + +ProcessMemoryInfo GetCurrentProcessMemoryInfo() { + ProcessMemoryInfo pmi = {}; + +#if defined(_WIN32) + PROCESS_MEMORY_COUNTERS_EX pmce = {}; + pmce.cb = sizeof(pmce); + + // This should always succeed for the current process. + // We need PROCESS_QUERY_LIMITED_INFORMATION rights if we want to read the info from a different + // process. + // This call used nearly 1ms on a sampled computer, and so should be called infrequently. + if (::GetProcessMemoryInfo( + GetCurrentProcess(), reinterpret_cast(&pmce), sizeof(pmce))) { + pmi.UsedMemory = (uint64_t)pmce.WorkingSetSize; // The set of pages in the virtual address space + // of the process that are currently resident in + // physical memory. + } +#else +// To do: Implement this. +#endif + + return pmi; +} + +#if defined(_WIN32) + +//----------------------------------------------------------------------------- +// PdhHelper is a helper class for querying perf counters using PDH. +// It is implemented as a singleton and initialized upon the first use. +// Currently, it is only used by GetSystemMemoryInfo() to obtain +// page fault information. There is one RateCounter object within +// PdhHelper for that. +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa373083(v=vs.85).aspx +// +class PdhHelper : public SystemSingletonBase { + OVR_DECLARE_SINGLETON(PdhHelper); + + public: + // RateCounter encapsulates a single counter that represents rate information. + struct RateCounter { + // Requires a query object and counter path. + RateCounter() : Valid(false), HasLast(false), CounterHandle(0) {} + + ~RateCounter() { + if (CounterHandle) + PdhRemoveCounter(CounterHandle); + } + + // Note this call may take some time to complete (180ms from testing) due to + // PdhAddCounterW, so be mindful if adding a bunch of counter objects in synchronous + // or blocking manner. + void Init(PDH_HQUERY hQuery, LPCWSTR counterPath) { + if (!hQuery) + return; + + PDH_STATUS status = PdhAddCounterW(hQuery, counterPath, 0, &CounterHandle); + if (ERROR_SUCCESS != status) + return; + + Valid = true; + } + + // Call this to obtain the latest counter value. + // Note that PdhHelper::Collect() must be called prior to this call. + double Query() { + if (!Valid) + return 0.0; + + PDH_RAW_COUNTER now; + DWORD counterType; + PDH_STATUS status = PdhGetRawCounterValue(CounterHandle, &counterType, &now); + if (ERROR_SUCCESS == status && PDH_CSTATUS_VALID_DATA == now.CStatus) { + // Calculate the rate (since this is a rate counter). + // FirstValue is the instance count. SecondValue is the timestamp. + double result = (HasLast && (now.SecondValue - Last.SecondValue)) + ? double(now.FirstValue - Last.FirstValue) / + (double(now.SecondValue - Last.SecondValue) * Timer::GetPerfFrequencyInverse()) + : 0.0; + + Last = now; + HasLast = true; + + return result; + } + + return 0.0; + } + + bool Valid; // Whether this counter object was initialized properly + bool HasLast; // Whether we have a previous snapshot. Need it to compute rate. + PDH_RAW_COUNTER Last; // Previous counter values + PDH_HCOUNTER CounterHandle; // PDH handle + }; + + public: + virtual void OnThreadDestroy() override { + CleanUp(); + } + + void CleanUp() { + if (PdhQuery) + PdhCloseQuery(PdhQuery); + } + + // Collects raw counter values for all counters in this query. + bool Collect() { + return ERROR_SUCCESS == PdhCollectQueryData(PdhQuery); + } + + public: + // Here we define the counters that we are interested in. + RateCounter CounterPageFault; + + private: + PDH_HQUERY PdhQuery; +}; + +PdhHelper::PdhHelper() { + PDH_STATUS status = PdhOpenQueryW(NULL, 0, &PdhQuery); + if (ERROR_SUCCESS != status) { + // If this fails, PdhQuery will be null, and subsequent query will + // check for this and return default data if we have no query object. + CleanUp(); + } + + // Initialize the counters + CounterPageFault.Init(PdhQuery, L"\\Memory\\Page Reads/sec"); +} + +PdhHelper::~PdhHelper() {} + +void PdhHelper::OnSystemDestroy() { + delete this; +} + +#endif // _WIN32 + +//----------------------------------------------------------------------------- + +SystemMemoryInfo GetSystemMemoryInfo() { + SystemMemoryInfo smi = {}; + +#if defined(_WIN32) + PdhHelper* ph = PdhHelper::GetInstance(); + + if (ph) { + // A single Collect call is required for the query object regardless of how many counters + // we are interested in. + if (ph->Collect()) { + smi.PageFault = ph->CounterPageFault.Query(); + } else { + // Can't get the counter for some reason. Use default. + smi.PageFault = 0.0; + } + + PERFORMANCE_INFORMATION pi{}; + pi.cb = sizeof(pi); + if (GetPerformanceInfo(&pi, sizeof(pi))) + smi.CommittedTotal = pi.CommitTotal; + } +#endif + + return smi; +} + +static void cpuid(int output[4], int functionNumber) { +#if defined(_MSC_VER) || defined(__INTEL_COMPILER) + __cpuidex(output, functionNumber, 0); +#elif defined(__GNUC__) || defined(__clang__) + int a, b, c, d; + __asm("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(functionNumber), "c"(0) :); + output[0] = a; + output[1] = b; + output[2] = c; + output[3] = d; +#endif +} + +CPUInstructionSet GetSupportedCPUInstructionSet(bool* popcntSupported, bool* lzcntSupported) { + static CPUInstructionSet cpuIS = CPUInstructionSet::Unknown; + + if (cpuIS != CPUInstructionSet::Unknown) + return cpuIS; + + cpuIS = CPUInstructionSet::Basic; + + int features[4] = {}; + cpuid(features, 0); + if (features[0] == 0) // If there are no features... + return cpuIS; + + // Check for lzcnt + if (lzcntSupported) { + cpuid(features, 0x80000001); + *lzcntSupported = ((features[2] & (1 << 5)) == 0); + } + + // Check for popcnt + if (popcntSupported) { + cpuid(features, 1); + *popcntSupported = ((features[2] & (1 << 23)) == 0); + } + + cpuid(features, 1); + + if ((features[3] & (1 << 0)) == 0 || // If floating point is not supported... + (features[3] & (1 << 23)) == 0 || // If MMX is not supported... + (features[3] & (1 << 15)) == 0 || // If conditional move is not supported... + (features[3] & (1 << 24)) == 0 || // If FXSAVE is not supported... + (features[3] & (1 << 25)) == 0) // If SSE is not supported... + { + return cpuIS; + } + cpuIS = CPUInstructionSet::SEE1; + + if ((features[3] & (1 << 26)) == 0) // If SSE2 is not supported... + return cpuIS; + cpuIS = CPUInstructionSet::SSE2; + + if ((features[2] & (1 << 0)) == 0) // If SSE3 is not supported... + return cpuIS; + cpuIS = CPUInstructionSet::SSE3; + + if ((features[2] & (1 << 9)) == 0) // If SSSE3 is not supported... + return cpuIS; + cpuIS = CPUInstructionSet::SSSE3; + + if ((features[2] & (1 << 19)) == 0) // If SSE4.1 is not supported... + return cpuIS; + cpuIS = CPUInstructionSet::SSE41; + + if ((features[2] & (1 << 20)) == 0) // If SSE42 is not supproted... + return cpuIS; + cpuIS = CPUInstructionSet::SSE42; + +#if defined(_MSC_VER) + if ((features[2] & (1 << 27)) == 0 || // If OSXSAVE is not supported... + (_xgetbv(0) & 6) != 6 || // If AVX is not recognized by the OS... + (features[2] & (1 << 28)) == 0) // If AVX is not supported by the CPU... + { + return cpuIS; + } +#else +// To do: Implement this. +#endif + + cpuIS = CPUInstructionSet::AVX1; + + cpuid(features, 7); + if ((features[1] & (1 << 5)) == 0) // If AVX2 is not supported... + return cpuIS; + + cpuIS = CPUInstructionSet::AVX2; + return cpuIS; +} + +//----------------------------------------------------------------------------- +// ModuleInfoLookup +// + +OVR::Util::ModuleInfoLookup DefaultModuleInfoLookup; + +const OVR::ModuleInfo* ModuleInfoLookup::GetModuleInfoForAddress(uint64_t address) { + if (ModuleInfoArray.empty()) { + ModuleInfoArray.resize(256); + + size_t requiredCount = OVR::SymbolLookup::GetModuleInfoArray( + &ModuleInfoArray[0], ModuleInfoArray.size(), OVR::SymbolLookup::ModuleSortByAddress); + OVR_ASSERT_AND_UNUSED(requiredCount <= ModuleInfoArray.size(), requiredCount); + } + + OVR::ModuleInfo + moduleInfo; // Construct a temporary so std::lower_bound can binary-search find it. + moduleInfo.baseAddress = address; + moduleInfo.size = 0; + + auto mi = std::lower_bound( + ModuleInfoArray.begin(), + ModuleInfoArray.end(), + moduleInfo, + [](const OVR::ModuleInfo& mi1, const OVR::ModuleInfo& mi2) -> bool { + return ((mi1.baseAddress + mi1.size) < (mi2.baseAddress + mi2.size)); + }); + + if (mi != ModuleInfoArray.end()) { + if ((mi->baseAddress <= address) && (address <= (mi->baseAddress + mi->size))) + return &*mi; + } + + return nullptr; +} + +const OVR::ModuleInfo& ModuleInfoLookup::GetModuleInfoForCurrentModule() { + if (CurrentModuleInfo.baseAddress == kMIBaseAddressInvalid) { + // Use GetInstructionAddress because it happens to be a function we forcibly non-inline. + const OVR::ModuleInfo* mi = GetModuleInfoForAddress((uintptr_t)GetInstructionAddress); + + if (mi) + CurrentModuleInfo = *mi; + } + + return CurrentModuleInfo; +} + +bool ModuleInfoLookup::GetAddressIsFromCurrentModule(uint64_t address) { + const OVR::ModuleInfo* mi = GetModuleInfoForAddress(address); + const OVR::ModuleInfo& miCurrent = GetModuleInfoForCurrentModule(); + + return (mi && (mi->baseAddress == miCurrent.baseAddress)); +} + +} // namespace Util + +} // namespace OVR + +#if defined(_WIN32) +OVR_DEFINE_SINGLETON(OVR::Util::PdhHelper); +#endif diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemInfo.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemInfo.h new file mode 100644 index 0000000..62e55c3 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_SystemInfo.h @@ -0,0 +1,490 @@ +/************************************************************************************ + +Filename : Util_SystemInfo.h +Content : Various operations to get information about the system +Created : September 26, 2014 +Author : Kevin Jenkins + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Util_SystemInfo_h +#define OVR_Util_SystemInfo_h + +#include +#include +#include +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_DebugHelp.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_Types.h" + +// XCode 11 ships with std::filesystem, but std::filesystem::path is only available when setting +// the minimum Mac OS X version to 10.15. Once the Mac builds use 10.15 as minimum version this can +// be reverted. +#if defined(__cpp_lib_filesystem) && !defined(__APPLE__) +#include +#define OVR_UTIL_STD_FILESYSTEM_AVAILABLE 1 +#else +#define OVR_UTIL_STD_FILESYSTEM_AVAILABLE 0 +#endif + +namespace OVR { +namespace Util { + +//----------------------------------------------------------------------------- +// Utility functions +// + +#if defined(_WIN32) +bool Is64BitWindows(); +#endif + +const char* OSAsString(); +String OSVersionAsString(); +uint64_t GetGuidInt(); +String GetGuidString(); +const char* GetProcessInfo(); +String GetCameraDriverVersion(); +void GetGraphicsCardList(OVR::Array& gpus); +String GetProcessorInfo(); + +enum WindowsVersion { Windows7_SP1 = 0, Windows8, Windows8_1, Windows10, Windows10_TH2 }; + +bool IsAtLeastWindowsVersion(WindowsVersion version); +bool IsAtMostWindowsVersion(WindowsVersion version); + +#if OVR_UTIL_STD_FILESYSTEM_AVAILABLE +// Returns the current module (e.g. exe or dll) path. If executed within a DLL, it returns the +// DLL path. +std::filesystem::path GetCurrentModuleDirectoryPath(); +#endif // OVR_UTIL_STD_FILESYSTEM_AVAILABLE + +// Checks if the computer is currently locked +bool CheckIsComputerLocked(); + +//----------------------------------------------------------------------------- +// SettingsManager +// +// This is a portable interface replacement for Windows-specific registry key functions. +// +// For all path-based functions: +// - Paths are UTF8-encoded. +// - Paths are case-insensitive. +// - Path follows Unix path conventions (e.g. /a/b/c/d). +// +// Windows platform: +// Applications may use Registry setting paths to read the Windows registry. +// An example Windows path is: +// "/HKEY_LOCAL_MACHINE/Software/Oculus/ForceGPUDriverVersionAcceptance" +// Windows registry path reading for Win32 apps on Win64 OSs does not change +// the path to insert Wow64 paths, though users of this functionality may explicitly +// use "WoW64" in paths. +// +// Example Windows usage with default paths: +// mgr.SetDefaultLocation("/HKEY_LOCAL_MACHINE/Software/Oculus/"); +// ... +// mgr.ReadValue("EnableTimeouts", timeoutsEnabled); +// mgr.ReadValue("FileName", test.tga); +// mgr.ReadValue("Graphics/ATWEnabled", aswEnabled); +// +// Example Windows usage with full paths: +// bool result = mgr.ReadValue("/HKEY_LOCAL_MACHINE/Software/Oculus/EnablePTW", ptwEnabled); +// bool result = mgr.WriteValue("/HKEY_LOCAL_MACHINE/Software/Oculus/FileName", "test.tga"); +// +class SettingsManager { + public: + SettingsManager() = default; + ~SettingsManager() = default; + + enum Options { + OptionNone = 0x00, + OptionUse32BitDatabase = 0x01, // Windows: This means to use KEY_WOW64_32KEY + OptionIgnoreAlternativeLocations = 0x02 + }; + + // ReadValue: + // - Return true if value exists and could be read, false if doesn't exist or can't be read. + // - The value is written to only if the setting could be read (true return value). + // - If the value was not originally written as the requested type, + // it is interpreted as the type. + // - If the path is relative path (no initial '/' char) then the default location + // is prefixed to path. + bool ReadValue(const char* path, bool& value, int options = OptionNone); + bool ReadValue(const char* path, int32_t& value, int options = OptionNone); + bool ReadValue(const char* path, uint32_t& value, int options = OptionNone); + bool ReadValue(const char* path, int64_t& value, int options = OptionNone); + bool ReadValue(const char* path, uint64_t& value, int options = OptionNone); + bool ReadValue(const char* path, float& value, int options = OptionNone); + bool ReadValue(const char* path, double& value, int options = OptionNone); + bool ReadValue(const char* path, std::string& value, int options = OptionNone); + bool ReadValue(const char* path, std::wstring& value, int options = OptionNone); + bool ReadValue(const char* path, std::vector& value, int options = OptionNone); + bool ReadValue(const char* path, uint8_t* data, size_t& dataSize, int options = OptionNone); + + // WriteValue: + // - Creates the setting if not already present + // - Return true if the setting could be created (if needed) and written. + // - Writes only the given path and not alternative locations. + // - A value of a given type can be overwritten with a value of a different type. + bool WriteValue(const char* path, bool value, int options = OptionNone); + bool WriteValue(const char* path, int32_t value, int options = OptionNone); + bool WriteValue(const char* path, uint32_t value, int options = OptionNone); + bool WriteValue(const char* path, int64_t value, int options = OptionNone); + bool WriteValue(const char* path, uint64_t value, int options = OptionNone); + bool WriteValue(const char* path, float value, int options = OptionNone); + bool WriteValue(const char* path, double value, int options = OptionNone); + bool WriteValue(const char* path, const char* value, size_t valStrlen, int options = OptionNone); + bool WriteValue(const char* path, const std::string& str, int options = OptionNone); + bool WriteValue(const char* path, const wchar_t* val, size_t valStrlen, int options = OptionNone); + bool WriteValue(const char* path, const std::wstring& str, int options = OptionNone); + bool WriteValue(const char* path, const uint8_t* data, size_t dataSize, int options = OptionNone); + + // Returns true if the value can be read and exists. + bool ValueExists(const char* path, int options = OptionNone) const; + + // Returns true if the value could be deleted. Returns false if the value was present but deletion + // failed. wasPresent indicates if the value was present before deletion was attempted. Deletion + // affects the path and any registered alternative locations, unless + // OptionIgnoreAlternativeLocations is specified. + bool DeleteValue(const char* path, bool* wasPresent = nullptr, int options = OptionNone); + + // Sets the default location for read and written value paths. + // Path must be a "full path", which begins with a path separator. + // Path must end with trailing path separtor. + // Defaults to empty. + // Example usage: + // settingsMgr.SetDefaultLocation("/HKEY_LOCAL_MACHINE/Software/Oculus/"); + void SetDefaultLocation(const char* parentPath); + +#define OVR_DEFAULT_SETTINGS_LOCATION "/HKEY_LOCAL_MACHINE/Software/Oculus/" +// OVR_XRS_SETTINGS_LOCATION Declared here because shared with OculusDebugTool +#define OVR_XRS_SETTINGS_LOCATION "/HKEY_CURRENT_USER/Software/Oculus/RemoteHeadset/" + + // Returns the default location, which can be set by SetDefaultLocation. + std::string GetDefaultLocation() const; + + // Adds an alternative location for value reads. + // Path must end with trailing path separtor. + // This function exists for the purpose of allowing migration of old Oculus settings + // paths to a single unified path. + // This function is not thread safe. It can be called from only a single thread at a time. + // Example usage: + // settingsMgr.AddAlternativeLocation("/HKEY_LOCAL_MACHINE/Software/Oculus2/"); + void AddAlternativeLocation(const char* parentPath); + + // This function is not thread safe. It can be called from only a single thread at a time. + // Example usage: + // settingsMgr.RemoveAlternativeLocation("/HKEY_LOCAL_MACHINE/Software/Oculus2/"); + void RemoveAlternativeLocation(const char* parentPath); + + struct InsensitiveCompare { + bool operator()(const std::string& a, const std::string& b) const { + return OVR_stricmp(a.c_str(), b.c_str()) < 0; + } + }; + + typedef std::set StringSet; + + // Gets a set of all currently registered alternative locations. + StringSet GetAlternativeLocations() const; + + // Sets Oculus-specific alternative locations. + // This function is not thread safe. It can be called from only a single thread at a time. + void SetDefaultAlternativeLocations(); + + // Returns the values present at the given parentPath. + // Writes a single line per enumerated value, with each line followed by a newline, + // including the last line. + // The parentPath must begin with '/' and end with '/' or be NULL to indicate usage of the + // default path. + // Example usage: + // str = settingsMgr.EnumerateValues("/HKEY_LOCAL_MACHINE/Software/Oculus/"); + // Note: + // When this data is backed by the Windows registry, the enumerated types won't be the + // same as the written types. For example, WriteDouble writes to the Windows registry as + // a binary value, and will be enumerated by EnumerateValues as binary instead of float. + std::string EnumerateValues(const char* parentPath = nullptr, int options = OptionNone) const; + + protected: + // This is a parent settings directory which acts as the default if value + // reads and writes do not include a parent path. + // Example Windows value: "/HKEY_LOCAL_MACHINE/Software/Oculus2/" + std::string defaultLocation; + +#ifdef _WIN32 + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724884(v=vs.85).aspx + struct Win32RegistryAnyValue { + uint32_t type; // Which REG_XXX type is used. + std::vector binaryData; // REG_BINARY + uint32_t dwordData; // REG_DWORD + uint64_t qwordData; // REG_QWORD + std::string stringData; // REG_SZ or REG_EXPAND_SZ + std::vector stringArrayData; // REG_MULTI_SZ + + Win32RegistryAnyValue(); + }; + + // Reads the Windows registry at the given path to a Win32RegistryAnyValue. + bool Win32ReadAnyRegistryValue(const char* path, Win32RegistryAnyValue& any, int options) const; + + // Reads the Windows registry value (sourceData/sourceDataSize) to a Win32RegistryAnyValue. + bool Win32ReadAnyRegistryValue( + DWORD dwType, + uint8_t* sourceData, + size_t sourceDataSize, + Win32RegistryAnyValue& anyValue) const; + + // Oculus unfortunately has a history of divergent Windows registry key storage locations. + // As part of the effort to converge on a single location, we provide backward-compatible + // old locations to check when reading values, so existing users that have registry keys at + // the old locations can still have their settings work. The locations are the parent + // registry key "directory". So for the "/HKEY_LOCAL_MACHINE/Software/Oculus LLC/Test" key, + // the location would be stored here as "/HKEY_LOCAL_MACHINE/Software/Oculus LLC/" + StringSet RegistryAlternativeLocations; +#endif +}; + +extern SettingsManager DefaultSettingsManager; + +#ifdef OVR_OS_MS + +//-------------------------------------------------------------------------------------------------- +// Windows registry functions +// +// Use these functions only for reading non-Oculus registry data. For Oculus settings, use the +// SettingsManager instead, which supplants direct Windows registry usage. +//-------------------------------------------------------------------------------------------------- + +enum class RegistryDB { + normal, // KEY_WOW64_64KEY. 64 bit apps use 64 bit database, 32 bit apps use 32 bit database. + wow64_32 // KEY_WOW64_32KEY. Force looking at the 32 bit database even if this is a 64 bit app. +}; + +enum class RegistryBase { + localMachine, // HKEY_LOCAL_MACHINE + currentUser // HKEY_CURRENT_USER +}; + +// Returns true if a registry key of the given type is present and can be interpreted as a boolean, +// otherwise +// returns defaultValue. It's not possible to tell from a single call to this function if the given +// registry key +// was present. For Strings, boolean means (atoi(str) != 0). For DWORDs, boolean means (dw != 0). +// If registryDB is RegistryDB::normal then KEY_WOW64_32KEY is used in the registry lookup. +// If registryBase is RegistryBase::currentUser then the HKEY_CURRENT_USER root is used +// instead of HKEY_LOCAL_MACHINE +bool GetRegistryBoolW( + const wchar_t* pSubKey, + const wchar_t* stringName, + bool defaultValue, + RegistryDB registryDB = RegistryDB::normal, + RegistryBase registryBase = RegistryBase::localMachine); + +// Returns true if a DWORD-type registry key of the given name is present, else sets out to 0 and +// returns false. +// If registryDB is RegistryDB::normal then KEY_WOW64_32KEY is used in the registry lookup. +// If registryBase is RegistryBase::currentUser then the HKEY_CURRENT_USER root is used +// instead of HKEY_LOCAL_MACHINE +bool GetRegistryDwordW( + const wchar_t* pSubKey, + const wchar_t* stringName, + DWORD& out, + RegistryDB registryDB = RegistryDB::normal, + RegistryBase registryBase = RegistryBase::localMachine); + +// Returns true if a string-type registry key of the given name is present, else sets out to empty +// and returns false. +// The output string will always be 0-terminated, but may be empty. +// If registryDB is RegistryDB::normal then KEY_WOW64_32KEY is used in the registry lookup. +// If registryBase is RegistryBase::currentUser then the HKEY_CURRENT_USER root is used +// instead of HKEY_LOCAL_MACHINE +bool GetRegistryStringW( + const wchar_t* pSubKey, + const wchar_t* stringName, + wchar_t out[MAX_PATH], + RegistryDB registryDB = RegistryDB::normal, + RegistryBase registryBase = RegistryBase::localMachine); + +// Returns true if the DWORD value could be successfully written to the registry. +// If registryDB is RegistryDB::normal then KEY_WOW64_32KEY is used in the registry lookup. +// If registryBase is RegistryBase::currentUser then the HKEY_CURRENT_USER root is used +// instead of HKEY_LOCAL_MACHINE +bool SetRegistryDwordW( + const wchar_t* pSubKey, + const wchar_t* stringName, + DWORD newValue, + RegistryDB registryDB = RegistryDB::normal, + RegistryBase registryBase = RegistryBase::localMachine); + +// Returns true if the value could be successfully deleted from the registry. +// If registryDB is RegistryDB::normal then KEY_WOW64_32KEY is used in the registry lookup. +// If registryBase is RegistryBase::currentUser then the HKEY_CURRENT_USER root is used +// instead of HKEY_LOCAL_MACHINE +bool DeleteRegistryValue( + const wchar_t* pSubKey, + const wchar_t* stringName, + RegistryDB registryDB = RegistryDB::normal, + RegistryBase registryBase = RegistryBase::localMachine); + +#endif // OVR_OS_MS + +//----------------------------------------------------------------------------- +// Get the path where the Oculus runtime output is written. +// +// GetBaseOVRPath() returns the top level Oculus output path. +// On Windows, this is %LOCALAPPDATA%\Oculus. +// +// GetBaseOVRPathW() has the identical behavior as GetBaseOVRPath(), but +// returns its result in a std::wstring. +// +// GetOVRPath() returns a path that represents a subdirectory from the top-level +// Oculus output path. (The top-level path is what GetBaseOVRPath() returns.) +// +// GetOVRPathW() has the identical behavior as GetOVRPath(), but returns its +// result in a std::wstring. + +String GetBaseOVRPath(bool create_dir); +std::wstring GetBaseOVRPathW(bool create_dir); +String GetOVRPath(const wchar_t* subPath, bool create_dir); +std::wstring GetOVRPathW(const wchar_t* subPath, bool create_dir); + +//----------------------------------------------------------------------------- +// Process path information + +// Returns the file path for the binary associated with the given runtime process id. +// Returns an empty string if the process id is invalid or could not be read. +// If enableErrorResults is true then failure strings will be written to the returned +// value in parentheses. This is useful for logging. +std::string GetProcessPath(pid_t processId, bool fileNameOnly, bool enableErrorResults); + +#if defined(_WIN32) +// Returns the file path for the binary associated with the given runtime process id. +// Returns an empty string if the process handle is invalid or could not be read. +// If enableErrorResults is true then failure strings will be written to the returned +// value in parentheses. This is useful for logging. +std::string GetProcessPath(HANDLE processHandle, bool fileNameOnly, bool enableErrorResults); +#endif + +// Returns true if the process was loaded outside of our Oculus store directory. +bool IsProcessSideLoaded(const std::string& processPath); + +// Same as GetProcessPath, except scrubs the returned process path string if it's something we have +// deemed +// cannot be reported in our log, usually due to privacy measures we have enacted. +std::string GetLoggableProcessPath(pid_t processId, bool fileNameOnly); + +#if defined(_WIN32) +// Same as GetProcessPath, except scrubs the returned process path string if it's something we have +// deemed +// cannot be reported in our log, usually due to privacy measures we have enacted. +std::string GetLoggableProcessPath(HANDLE processHandle, bool fileNameOnly); + +// Retrives the root of the Oculus install directory +// The returned string is a directory path and does not have a trailing path separator. +// Example return value: L"C:\Program Files// (x86)\Oculus\Support\oculus-runtime" +std::wstring GetOVRRuntimePathW(); +#endif + +// Returns a string with a comma-separated list of tags for the machine. +// The tags are obtained from the registry. +String GetMachineTags(); + +#if defined(_WIN32) +String GetFileVersionStringW(const wchar_t filePath[MAX_PATH]); + +String GetSystemFileVersionStringW(const wchar_t filePath[MAX_PATH]); +#endif + +//----------------------------------------------------------------------------- +// Retrieves memory usage info for the current process. +// +// Do not call this function frequently as it takes hundreds of microseconds to +// execute on typical computers. + +struct ProcessMemoryInfo { + uint64_t UsedMemory; // Same as Windows working set size. + // https://msdn.microsoft.com/en-us/library/windows/desktop/cc441804%28v=vs.85%29.aspx +}; + +ProcessMemoryInfo GetCurrentProcessMemoryInfo(); + +//----------------------------------------------------------------------------- +// Retrieves memory info for the system (counterpart of GetCurrentProcessMemoryInfo) +// +// Do not call this function frequently as it takes a long time to +// execute on typical computers. + +struct SystemMemoryInfo { + double PageFault; // System-wide hard page faults per sec + uint64_t CommittedTotal; // Total number of committed memory (in bytes) on the system +}; + +SystemMemoryInfo GetSystemMemoryInfo(); + +enum class CPUInstructionSet { + Unknown, + Basic, // Just basic 32 bit 386. + SEE1, + SSE2, + SSE3, + SSSE3, // Supplementary SSE3 + SSE41, + SSE42, + AVX1, + AVX2 +}; + +//----------------------------------------------------------------------------- +// Indicates the minimum instruction set that the CPU + OS support. Note that an older OS may +// not properly support a given CPU instruction set, usually because it doesn't know how to +// preserve its registers on context switch. + +CPUInstructionSet GetSupportedCPUInstructionSet(bool* popcntSupported, bool* lzcntSupported); + +//----------------------------------------------------------------------------- +// Implements ModuleInfo lookup functionalitity. +// This class is separate from the OVR::SymbolLookup class, which has some +// similar functionality, because that class has extra wiring to support (heavy) +// symbol lookups, which we don't want here and which would put a lot more weight +// on the usage of this functionality (which we want to be able to call frequently +// at runtime). +// +class ModuleInfoLookup { + public: + ModuleInfoLookup() = default; + ~ModuleInfoLookup() = default; + + const OVR::ModuleInfo* GetModuleInfoForAddress(uint64_t address); + const OVR::ModuleInfo& GetModuleInfoForCurrentModule(); + bool GetAddressIsFromCurrentModule(uint64_t address); + + // All process ModuleInfo, sorted by address. + std::vector ModuleInfoArray; + + // ModuleInfo for the current module. Not necessarily the main executable module. + OVR::ModuleInfo CurrentModuleInfo; +}; + +extern ModuleInfoLookup DefaultModuleInfoLookup; + +} // namespace Util +} // namespace OVR + +#endif // OVR_Util_SystemInfo_h diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Watchdog.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Watchdog.cpp new file mode 100644 index 0000000..0998735 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Watchdog.cpp @@ -0,0 +1,335 @@ +/************************************************************************************ + +Filename : Util_Watchdog.cpp +Content : Deadlock reaction +Created : June 27, 2013 +Authors : Kevin Jenkins, Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Util_Watchdog.h" + +#include + +#include "Kernel/OVR_DebugHelp.h" +#include "Kernel/OVR_Win32_IncludeWindows.h" + +#if defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) +#include +#include +#include + +#if defined(OVR_OS_LINUX) +#include +#endif +#endif + +OVR_DEFINE_SINGLETON(OVR::Util::WatchDogObserver); + +namespace OVR { +namespace Util { + +// Watchdog class default threshold before announcing a long cycle +const int DefaultThreshholdMsec = 60000; // milliseconds + +//----------------------------------------------------------------------------- +// Tools + +static uint32_t GetFastMsTime() { +#if defined(OVR_OS_MS) + return ::GetTickCount(); +#else + return Timer::GetTicksMs(); +#endif +} + +static std::string SanitizeString(const char* cstr) { + std::ostringstream ss; + char ch; + while (ch = *cstr++, ch != '\0') { + if (ch < ' ' || ch == '\"' || ch == '\'' || ch == '\\' || ch == '`' || ch > '~') + ch = '_'; + ss << ch; + } + return ss.str(); +} + +//----------------------------------------------------------------------------- +// WatchDogObserver + +static ovrlog::Channel Logger("Kernel:Watchdog"); + +WatchDogObserver::WatchDogObserver() + : ListLock(), + DogList(), + IsReporting(false), + TerminationEvent(), + DeadlockSeen(false), + AutoTerminateOnDeadlock(true), + ApplicationName(), + OrganizationName(), + WriteMiniDump(nullptr), + AddBreakpadInfoClient(nullptr) { + WatchdogThreadHandle = std::make_unique([this] { this->Run(); }); + // Must be at end of function + PushDestroyCallbacks(); +} + +WatchDogObserver::~WatchDogObserver() { + OVR_ASSERT(!WatchdogThreadHandle->joinable()); +} + +void WatchDogObserver::OnThreadDestroy() { + Logger.LogDebug("Setting TerminationEvent for watchdog thread."); + TerminationEvent.SetEvent(); + + WatchdogThreadHandle->join(); +} + +void WatchDogObserver::OnSystemDestroy() { + // NOTE: Explicitly allowed to do this by the top-level comment of OnSystemDestroy() + delete this; +} + +void WatchDogObserver::OnDeadlock(const String& deadlockedThreadName) { + // If is reporting deadlock details: + if (IsReporting) { + if (SymbolLookup::Initialize()) { + // Static to avoid putting 32 KB on the stack. This is only called once, so it's safe. + static SymbolLookup symbolLookup; + String threadListOutput, moduleListOutput; + symbolLookup.ReportThreadCallstacks(threadListOutput); + symbolLookup.ReportModuleInformation(moduleListOutput); + + Logger.LogWarning( + "---DEADLOCK STATE---\n\n", + threadListOutput.c_str(), + "\n\n", + moduleListOutput.c_str(), + "\n---END OF DEADLOCK STATE---"); + } + + // For internal builds done by our engineers, we write minidumps as per the settings below. We + // don't generate breakpad minidumps nor upload breakpad crash reports. For non-internal builds + // (typically public builds), we generate breakpad mindumps and will upload them as necessary. + if (WriteMiniDump != nullptr) { + // non-internal builds + OVR_ASSERT(AddBreakpadInfoClient != nullptr); + AddBreakpadInfoClient("is_deadlock_minidump", "true"); + // deadlockedThreadName might contain special characters + std::string threadName = SanitizeString(deadlockedThreadName.c_str()); + AddBreakpadInfoClient("deadlock_thread_name", threadName.c_str()); + WriteMiniDump(nullptr); + } else { + // internal builds + ExceptionHandler::ReportDeadlock(deadlockedThreadName, OrganizationName, ApplicationName); + } + + // Disable reporting after the first deadlock report + DisableReporting(); + } + + DeadlockSeen = true; + + Logger.LogError( + "WatchDogObserver::OnDeadlock: Deadlock detected in thread '", + deadlockedThreadName.c_str(), + "'"); + + if (OVRIsDebuggerPresent()) { + Logger.LogWarning( + "WatchDogObserver::OnDeadlock: Aborting termination since debugger is present. Normally the app would terminate itself here"); + } else if (AutoTerminateOnDeadlock) { + Logger.LogError( + "WatchDogObserver::OnDeadlock: Waiting ", + TerminationDelayMsec, + " msec until deadlock termination"); + + if (!TerminationEvent.Wait(TerminationDelayMsec)) { +#if defined(_WIN32) // To do: Implement a generic OVR library terminate self API. With a clean + // option (exit()) and drastic option (TerminateProcess()). + ::TerminateProcess(GetCurrentProcess(), 0xd00ddead); +#else + exit(0xd00ddead); +#endif + } + + Logger.LogError( + "WatchDogObserver::OnDeadlock: Deadlock termination aborted - Graceful shutdown"); + } +} + +int WatchDogObserver::Run() { + Thread::SetCurrentThreadName("WatchDog"); + + Logger.LogDebug("WatchDogObserver::Run: Starting watchdog thread"); + + // Milliseconds between checks + static const int kWakeupIntervalMsec = 4000; // 4 seconds + + // Number of consecutive long cycles before the watchdog dumps a minidump + static const int kLongCycleTimeLimitMsec = 60000; // 1 minute + static const int kMaxConsecutiveLongCycles = kLongCycleTimeLimitMsec / kWakeupIntervalMsec; + + // By counting consecutive long cycles instead of using a timeout, we prevent false positives + // from debugger breakpoints and sleep/resume of the OS. + int ConsecutiveLongCycles = 0; // Number of long cycles seen in a row + + // While not requested to terminate: + while (!TerminationEvent.Wait(kWakeupIntervalMsec)) { + bool sawLongCycle = false; + String deadlockedThreadName; + + { + Lock::Locker locker(&ListLock); + + const uint32_t t1 = GetFastMsTime(); + + const int count = DogList.GetSizeI(); + for (int i = 0; i < count; ++i) { + const WatchDog* dog = DogList[i]; + + const int threshold = dog->ThreshholdMilliseconds; + const uint32_t t0 = dog->WhenLastFedMilliseconds; + + // If threshold exceeded, assume there is thread deadlock of some sort. + int delta = static_cast(t1 - t0); + + // Include an upper bound in case the computer went to sleep + if (delta > threshold && (ConsecutiveLongCycles > 0 || delta < threshold * 5)) { + sawLongCycle = true; + + deadlockedThreadName = dog->ThreadName; + Logger.LogWarning( + "WatchDogObserver::Run: Long cycle detected ", + ConsecutiveLongCycles + 1, + "x (max=", + kMaxConsecutiveLongCycles, + ") in thread '", + deadlockedThreadName.c_str(), + "'"); + } + } + } + + // If we did not see a long cycle: + if (!sawLongCycle) { + if (ConsecutiveLongCycles > 0) { + // Reset log cycle count + ConsecutiveLongCycles = 0; + + Logger.LogWarning("WatchDogObserver::Run: Recovered from long cycles"); + } + + // Reset deadlock seen flag + DeadlockSeen = false; + } else if (++ConsecutiveLongCycles >= kMaxConsecutiveLongCycles) { + // Since it requires consecutive long cycles, waking up from sleep/resume will not trigger a + // deadlock. + OnDeadlock(deadlockedThreadName); + } + } + + Logger.LogDebug("WatchDogObserver::Run: Terminating watchdog thread"); + + return 0; +} + +void WatchDogObserver::Add(WatchDog* dog) { + Lock::Locker locker(&ListLock); + + if (!dog->Listed) { + Logger.LogDebugF("WatchDogObserver::Add Watchdog: %s", dog->GetThreadName().c_str()); + DogList.PushBack(dog); + dog->Listed = true; + } else + Logger.LogDebugF( + "WatchDogObserver::Add Watchdog: %s already added.", dog->GetThreadName().c_str()); +} + +void WatchDogObserver::Remove(WatchDog* dog) { + Lock::Locker locker(&ListLock); + bool removed = false; + + Logger.LogDebugF("WatchDogObserver::Remove Watchdog: %s", dog->GetThreadName().c_str()); + + if (dog->Listed) { + for (int i = 0; i < DogList.GetSizeI(); ++i) { + if (DogList[i] == dog) { + DogList.RemoveAt(i--); + removed = true; + break; + } + } + + dog->Listed = false; + } + + if (!removed) + Logger.LogDebugF( + "WatchDogObserver::Remove Watchdog: %s already removed.", dog->GetThreadName().c_str()); +} + +void WatchDogObserver::EnableReporting(const String& organization, const String& application) { + OrganizationName = organization; + ApplicationName = application; + IsReporting = true; +} + +void WatchDogObserver::DisableReporting() { + IsReporting = false; +} + +//----------------------------------------------------------------------------- +// WatchDog + +WatchDog::WatchDog(const String& threadName) + : ThreshholdMilliseconds(DefaultThreshholdMsec), ThreadName(threadName), Listed(false) { + WhenLastFedMilliseconds = GetFastMsTime(); + + OVR_ASSERT(!ThreadName.empty()); +} + +WatchDog::~WatchDog() { + Disable(); +} + +String WatchDog::GetThreadName() const { + return ThreadName; +} + +void WatchDog::Disable() { + WatchDogObserver::GetInstance()->Remove(this); +} + +void WatchDog::Enable() { + WatchDogObserver::GetInstance()->Add(this); +} + +void WatchDog::Feed(int threshold) { + WhenLastFedMilliseconds = GetFastMsTime(); + ThreshholdMilliseconds = threshold; + + if (!Listed) { + Enable(); + } +} +} // namespace Util +} // namespace OVR diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Watchdog.h b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Watchdog.h new file mode 100644 index 0000000..e5e11b6 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Util/Util_Watchdog.h @@ -0,0 +1,166 @@ +/************************************************************************************ + +Filename : Util_Watchdog.h +Content : Deadlock reaction +Created : June 27, 2013 +Authors : Kevin Jenkins, Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_Watchdog_h +#define OVR_Util_Watchdog_h + +#include +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Atomic.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Threads.h" +#include "Kernel/OVR_Timer.h" + +namespace OVR { +namespace Util { + +//----------------------------------------------------------------------------- +// WatchDog +// +// A watchdog is kept active ("fed") via regular calls to Feed() once per +// iteration of your thread's loop. Pass the expected duration upper bound (in +// msec) to Feed(), which will add the watchdog to the global observer if it +// hasn't been already. This value becomes the watchdog threshold-- if the next +// call to Feed() occurs after this duration has elapsed, the observer +// considers the previous loop iteration to have taken longer than expected (a +// "long cycle"). Watchdogs are removed from the global observer either via an +// explicit call to Disable() or upon destruction / going out of scope. +// +// The observer is a global object that normally does not need to be +// interacted with directly. It runs a background thread that checks on each +// watchdog every ~4s. For each watchdog, it calculates a delta from when +// Feed() was last called to the current time. If this delta exceeds the value +// passed to the last call to Feed(), then the previous loop iteration took too +// long and the observer increments a count of that watchdog's detected "long +// cycles." Long cycles are counted to protect against false positives e.g. +// when the system goes to sleep or the debugger is active. When 15 long cycles +// have been detected, the observer sees that thread as deadlocked and a report +// is generated / the offending process is terminated. + +class WatchDog : public NewOverrideBase { + friend class WatchDogObserver; + + public: + WatchDog(const String& threadName); + ~WatchDog(); + + String GetThreadName() const; + + void Disable(); + void Enable(); + + void Feed(int threshold); + + protected: + // Use 32 bit int so assignment and comparison is atomic + std::atomic WhenLastFedMilliseconds = {0}; + std::atomic ThreshholdMilliseconds = {0}; + + String ThreadName; + bool Listed; +}; + +//----------------------------------------------------------------------------- +// WatchDogObserver + +class WatchDogObserver : public SystemSingletonBase { + OVR_DECLARE_SINGLETON(WatchDogObserver); + virtual void OnThreadDestroy() override; + + friend class WatchDog; + + std::unique_ptr WatchdogThreadHandle; + + public: + // Uses the exception logger to write deadlock reports + void EnableReporting(const String& organization = String(), const String& application = String()); + + // Disables deadlock reports + void DisableReporting(); + + // This is the delay between deciding a deadlock occurred and terminating the process, to allow + // for logging + const int TerminationDelayMsec = 10000; // 10 seconds in msec + + // Enable/disable auto-terminate on deadlock report + // IsDeadlocked() will return true, and after TerminationDelayMsec it will exit the process + void SetAutoTerminateOnDeadlock(bool enable = true) { + AutoTerminateOnDeadlock = enable; + } + + // Is currently in a deadlock state? + bool IsDeadlocked() const { + return DeadlockSeen; + } + + // Sets the callback used to trigger a Breakpad Minidump write. + // Note: Lock does not need to be held here because only accessed on startup before deadlocks are + // reported. + void SetMiniDumpWriteCallback(void (*pWriteMiniDump)(void*)) { + WriteMiniDump = pWriteMiniDump; + } + + // Sets the callback used to add additional info to Breakpad client + void SetAddBreakpadInfoClientCallback( + void (*pAddBreakpadInfoClient)(const char* name, const char* value)) { + AddBreakpadInfoClient = pAddBreakpadInfoClient; + } + + protected: + Lock ListLock; + Array DogList; + + // This indicates that EnableReporting() was requested + bool IsReporting = false; + + Event TerminationEvent; + + // Has a deadlock been seen? + bool DeadlockSeen = false; + bool AutoTerminateOnDeadlock = true; + + // On Windows, deadlock logs are stored in %AppData%\OrganizationName\ApplicationName\. + // See ExceptionHandler::ReportDeadlock() for how these are used. + String ApplicationName; + String OrganizationName; + + void OnDeadlock(const String& deadlockedThreadName); + + // Breakpad is used to write minidump files. + void (*WriteMiniDump)(void* pExceptionPtrs); + void (*AddBreakpadInfoClient)(const char* name, const char* value); + + protected: + int Run(); + + void Add(WatchDog* dog); + void Remove(WatchDog* dog); +}; +} // namespace Util +} // namespace OVR + +#endif // OVR_Util_Watchdog_h diff --git a/ovr_sdk_win_23.0.0/Logging/Logging/Logging-fwd.h b/ovr_sdk_win_23.0.0/Logging/Logging/Logging-fwd.h new file mode 100644 index 0000000..26537f0 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/Logging/Logging-fwd.h @@ -0,0 +1,58 @@ +/************************************************************************************ + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#pragma once + +#include + +namespace ovrlog { + +struct LogStringBuffer; +class Channel; +class Configurator; + +typedef uint32_t Log_Level_t; +typedef uint32_t Write_Option_t; + +enum class Level : Log_Level_t; + +class Name; + +struct LogStringBuffer; + +template +void LogStringize(LogStringBuffer& buffer, const T& thing); + +class OutputPlugin; + +struct ChannelNode; + +class OutputWorker; + +class ErrorSilencer; + +class Channel; + +class ConfiguratorPlugin; + +class Configurator; + +} // namespace ovrlog diff --git a/ovr_sdk_win_23.0.0/Logging/Logging/Logging_Library.h b/ovr_sdk_win_23.0.0/Logging/Logging/Logging_Library.h new file mode 100644 index 0000000..594d8f3 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/Logging/Logging_Library.h @@ -0,0 +1,1262 @@ +/************************************************************************************ + +Filename : Logging_Library.h +Content : Logging system +Created : Oct 26, 2015 +Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#pragma once + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4530) // C++ exception handler used, but unwind semantics are not enabled +#endif // _MSC_VER + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#endif // _MSC_VER + +#include "Logging/Logging-fwd.h" +#include "Logging/Logging_Tools.h" + +#if !defined(_WIN32) +#include +#include +#include +#endif // !defined(_WIN32) + +namespace ovrlog { + +struct LogStringBuffer; +class Channel; +class Configurator; + +typedef uint32_t Log_Level_t; +typedef uint32_t Write_Option_t; + +//----------------------------------------------------------------------------- +// Log Level +// +// Log message priority is indicated by its level. The level can inform how +// prominently it is displayed on the console window or whether or not a +// message is displayed at all. + +enum class Level : Log_Level_t { + // No logging occurs. + Disabled, + + // Trace message. This is a message that can potentially happen once per + // camera/HMD frame and are probably being reviewed after they are recorded + // since they will scroll by too fast otherwise. + Trace, + + // Debug message. This is a verbose log level that can be selectively + // turned on by the user in the case of perceived problems to help + // root-cause the problems. This log level is intended to be used for + // messages that happen less often than once per camera/HMD frame, + // such that they can be human readable. + Debug, + + // Info messages, which should be the default message type for infrequent + // messages used during subsystem initialization and/or shutdown. This + // log level is fairly visible so should be used sparingly. Expect users to + // have these turned on, so avoid printing anything here that would obscure + // Warning and Error messages. + Info, + + // Warning message, which is also displayed almost everywhere. For most + // purposes it is as visible as an Error message, so it should also be used + // very selectively. The main difference from Error level is informational + // as it is just as visible. + Warning, + + // Highest level of logging. If any logging is going on it will include this + // message. For this reason, please avoid using the Error level unless the + // message should be displayed absolutely everywhere. + Error, + + // Number of error levels + Count, // Used to static assert where updates must happen in code. +}; + +//----------------------------------------------------------------------------- +// LOGGING_LOC +// +// C++11 Trait that can be used to insert the file and line number into a log +// message. Often times it is a good idea to put these at the start of a log +// message so that the user can click on them to have the code editor IDE jump +// to that line of code. + +// Log Line of Code FileLineInfo object. +#if defined(LOGGING_DEBUG) +#define LOGGING_FILE_LINE_STRING_ __FILE__ "(" LOGGING_STRINGIZE(__LINE__) ")" +#define LOGGING_LOC LOGGING_FILE_LINE_STRING_ +#else +#define LOGGING_LOC "(no LOC)" +#endif + +//----------------------------------------------------------------------------- +// LOGGING_LOCATION_HASH +// +// Provides a compile-time constexpr hash of the file/line combination, which is +// likely unique across all locations within a source code base. The primary weakness +// of this is a compiler environment in which __FILE__ represents just a file name +// and not a path, and there are two files with the same name and this is used on +// the same line within those files. +// +// Example usage: +// printf("%llu", LOGGING_LOCATION_HASH()); +// +#if defined(_WIN64) || defined(__x64__) +#define LOGGING_FILE_LINE_FNV_HASH_PRIME 1099511628211ULL +#define LOGGING_FILE_LINE_FNV_HASH_OFFSET 14695981039346656037ULL +#else +#define LOGGING_FILE_LINE_FNV_HASH_PRIME 16777619 +#define LOGGING_FILE_LINE_FNV_HASH_OFFSET 2166136261 +#endif + +// Implementation function for calculating a hash that's ~unique for a given file/line combination. +constexpr uint64_t LoggingFileLineHash(const char* const path, uint32_t index, uint64_t hash) { + return path[index] + ? ovrlog::LoggingFileLineHash( + path, index + 1, (((uint8_t)path[index] ^ hash) * LOGGING_FILE_LINE_FNV_HASH_PRIME)) + : hash; +} + +#ifdef _MSC_VER +#define LOGGING_LOCATION_HASH() \ + __pragma(warning(push)) __pragma(warning(disable : 4307)) ovrlog::LoggingFileLineHash( \ + __FILE__, \ + 0, \ + (uint64_t)( \ + (__LINE__ ^ LOGGING_FILE_LINE_FNV_HASH_OFFSET) * LOGGING_FILE_LINE_FNV_HASH_PRIME)) \ + __pragma(warning(pop)) +#else +#define LOGGING_LOCATION_HASH() \ + ovrlog::LoggingFileLineHash( \ + __FILE__, \ + 0, \ + (uint64_t)( \ + (__LINE__ ^ LOGGING_FILE_LINE_FNV_HASH_OFFSET) * LOGGING_FILE_LINE_FNV_HASH_PRIME)) +#endif + +//----------------------------------------------------------------------------- +// LogTime +// +// Our time type +// +#if defined(WIN32) +typedef SYSTEMTIME LogTime; +#else +typedef std::chrono::system_clock::time_point LogTime; +#endif + +// Gets the current time in LogTime format. +// May be called from multiple threads concurrently. +LogTime GetCurrentLogTime(); + +//----------------------------------------------------------------------------- +// Name +// +// A fixed length name which avoids allocation and is safe to share across DLL +// boundaries. + +class Name { + public: + // Longest string not including '\0' termination + static const size_t MaxLength = 63; + + Name(const char* init) { + // Maximum portability vs. ::strncpy_s + for (size_t i = 0; i < MaxLength; ++i) { + if ((name[i] = init[i]) == '\0') + return; + } + name[MaxLength] = '\0'; + } + Name(std::string init) : Name(init.c_str()) {} + const char* Get() const { + return name.data(); + } + int cmp(const Name& rhs) { + // Maximum portability vs. std::strncmp + int diff = 0; + for (size_t i = 0; i < MaxLength; ++i) { + // this < rhs => (-), this > rhs => (+) + diff = int(name[i]) - int(rhs.name[i]); + // If strings are equal it is sufficent to terminate on either '\0' + if ((diff != 0) || (name[i] == '\0')) // => (rhs.name[i] == '\0') + break; + } + return diff; + } + bool operator==(const Name& rhs) { + return cmp(rhs) == 0; + } + bool operator!=(const Name& rhs) { + return cmp(rhs) != 0; + } + + private: + // '\0'-terminated + std::array name; +}; + +//----------------------------------------------------------------------------- +// LogStringBuffer +// +// Thread-local buffer for constructing a log message. + +struct LogStringBuffer { + const Name SubsystemName; + const Level MessageLogLevel; + + // Buffer containing string as it is constructed + std::stringstream Stream; + // TBD: We can optimize this better than std::string + // TBD: We can remember the last log string size to avoid extra allocations. + + // Flag indicating that the message is being relogged. + // This is useful to prevent double-logging messages. + bool Relogged; + + // Ctor + LogStringBuffer(const char* subsystem, Level level) + : SubsystemName(subsystem), MessageLogLevel(level), Stream(), Relogged(false) {} +}; + +//----------------------------------------------------------------------------- +// LogStringize Override +// +// This is the function that user code can override to control how special types +// are serialized into the log messages. + +// Delete logging a shared_ptr +template +LOGGING_INLINE void LogStringize(LogStringBuffer& buffer, const std::shared_ptr& thing) { + (void)buffer; + (void)thing; +#if !defined(__clang__) + static_assert( + false, "Don't log a shared_ptr, log *ptr (or ptr.get() for the raw pointer value)."); +#endif +} + +// Delete logging a unique_ptr +template +LOGGING_INLINE void LogStringize( + LogStringBuffer& buffer, + const std::unique_ptr& thing) { + (void)buffer; + (void)thing; +#if !defined(__clang__) + static_assert( + false, "Don't log a unique_ptr, log *ptr (or ptr.get() for the raw pointer value)."); +#endif +} + +template +LOGGING_INLINE void LogStringize(LogStringBuffer& buffer, const T& first) { + buffer.Stream << first; +} + +// Overrides for various types we want to handle specially: + +template <> +LOGGING_INLINE void LogStringize(LogStringBuffer& buffer, const bool& first) { + buffer.Stream << (first ? "true" : "false"); +} + +template <> +void LogStringize(LogStringBuffer& buffer, wchar_t const* const& first); + +template +LOGGING_INLINE void LogStringize(LogStringBuffer& buffer, const wchar_t (&first)[N]) { + const wchar_t* str = first; + LogStringize(buffer, str); +} + +template <> +LOGGING_INLINE void LogStringize(LogStringBuffer& buffer, const std::wstring& first) { + const wchar_t* str = first.c_str(); + LogStringize(buffer, str); +} + +//----------------------------------------------------------------------------- +// Log Output Worker Thread +// +// Worker thread that produces the output. +// Call AddPlugin() to register an output plugin. + +// User-defined output plugin +class OutputPlugin { + public: + virtual ~OutputPlugin() {} + + // Return a unique string naming this output plugin. + virtual const char* GetUniquePluginName() = 0; + + // Write data to output. + virtual void + Write(Level level, const char* subsystem, const char* header, const char* utf8msg) = 0; +}; + +//----------------------------------------------------------------------------- +// Used by channel to specify how to write +enum class WriteOption : Write_Option_t { + // Default log write. If the output message queue size limit is reached, then the write + // is discarded. This is intended to be an unusual case that occurs only if the message + // generation is very rapid compared to queue processing. + Default, + + // If the Write would require adding an entry that goes over the max queue size, usually we + // drop the write. But this flag indicates to exceed the queue size, which can user more memory + // than expected and possibly exhaust memory if it is used very much. + DangerouslyIgnoreQueueLimit +}; + +//-------------------------------------------------------------------------------------------------- +// RepeatedMessageManager +// +// We have a problem in which sometimes a subsystem will spam the log with essentially the +// same message repeatedly. +// +// This class handles the ownership of repeated messages, which it aggregates and counts. +// The logging system can use an instance of this class to aggregate redundant messages. +// +// Example usage: +// RepeatedMessageManager gRepeatedMessageManager; // Some kind of singleton. +// +// void OutputWorker::Write(const char* subsystemName, Level messageLogLevel, +// const char* stream, bool relogged, WriteOption option) +// { +// if (gRepeatedMessageManager.HandleMessage(subsystemName, messageLogLevel, stream) == +// HandleMessage::Aggregated) +// return; +// } +// +// void OutputWorker::ProcessQueuedMessages() { +// while(...) { +// [...] +// gRepeatedMessageManager.Poll(); +// } +// } +// +// Design +// In our HandleMessage function: +// For every message we receive, we look at the last N messages received and see if this message +// appears to be a duplicate of any of the previous ones. We make that decision by first checking +// if the text of the message matches an entry in a hash table of known currently repeating +// messages. If not present then we make that decision based on the text of the message being +// similar to message text of the last N received messages and being received within some period +// of time since the last similar message. It it appears to be a repeat, then we add it to the +// hash table. +// +// In our Poll function: +// Each message in the hash table has a repeat count, which is the number of times +// the message has been previously seen since it was last printed. When that count gets above +// some value, we print the message and set the count to zero for further accumulation. +// Messages that have been in the hash table without having been repeated recently are printed +// a final time and removed from the hash table. Since this final printing occurs only after a +// timeout, it will be occurring after the last message was received and thus be delayed by some +// amount of time. +// +// Performance considerations: +// The list of N previously received messages represents the biggest potential performance cost +// to this functionality. We need to check the currently incoming message against each of the +// last N messages. That check needs to be fast, and the maintenance of the data structure +// which holds that data (e.g. container heap usage) needs to be fast. One fairly fast solution +// is to maintain the last N messages as a hash table of string hashes, and so when a new message +// is received, we do an O(1) hash table lookup. But we need to continuously prune the hash +// table, which is an O(n) operation unless we have some kind of priority_queue alongside the +// hash table which tells us how to quickly find the oldest entries in the hash table. A simpler +// solution is to prune the hash table only when it gets beyond N*2 messages. So we only do +// this O(n) pass periodically. +// +class RepeatedMessageManager { + public: + RepeatedMessageManager(); + ~RepeatedMessageManager() = default; + + enum class HandleResult { + Aggregated, // The message was consumed for aggregation (it was a repeat). Don't print it. + Passed // The message didn't appear to be a repeat and should be printed. + }; + + // If the message appears to be a repeat of a recent message then we add it to our repeated + // message database and return HandleResult::Aggregated. If HandleMessage returns Aggreggated + // then the caller should not write the message to the stream. + HandleResult HandleMessage(const char* subsystemName, Level messageLogLevel, const char* stream); + + // This function should be called at least once every maxDeferrableDetectionTimeMs. + // It causes us to look at the list of repeated messages and possibly print an aggregated + // form of any of them that has expired. For example, if the message "hello world" was repeated + // 100 times in the last five seconds, we print a single aggregate message such as: + // "[repeated 100 times] hello world". We also do housekeeping on the recent message list. + // The outputWorker is where any deferred aggregated messages should be written. + void Poll(OutputWorker* outputWorker); + + // Causes messages with the given prefix to not be subject to aggregated deferral. + // This is useful in case you want a specific message to be repeated, regardless of the + // frequency or apparent redundancy it may have. The MessagePrefix needs to be at least + // messagePrefixLength in length, so that it can be matched internally accurately. + // Strings are case-sensitive. + void AddRepeatedMessageException(const char* messagePrefix); + + // Removes messages previously added with AddRepeatedMessageException. + // Strings are case-sensitive. + void RemoveRepeatedMessageException(const char* messagePrefix); + + // Causes messages with the given subsystemName to not be subject to aggregated deferral. + // This is useful in case you want a specific subsystem's message to be repeated, + // regardless of the frequency or apparent redundancy it may have. + // Strings are case-sensitive. + void AddRepeatedMessageSubsystemException(const char* subsystemName); + + // Removes messages previously added with AddRepeatedMessageSubsystemException. + void RemoveRepeatedMessageSubsytemException(const char* subsystemName); + + protected: + // Keep the last messages to see if any of them are repeated. + static const uint32_t recentMessageCount = 40; + + // The number of leading characters in a message which we consider for comparisons. + static const uint32_t messagePrefixLength = 36; + + // If a message is a repeat of a previous message, we still print it in the log a few times + // before we start silencing it and holding it for later aggregation. + static const uint32_t printedRepeatCount = 8; + + // Max number of messages that are held for deferral before we print an aggregate message. + static const uint32_t maxDeferredMessages = 40; + + // If a repeating message wasn't encountered in the last time, + // then we don't consider it repeating any more. + static const uint32_t maxDeferrableDetectionTimeMs = 1000; + + // Every time period, we do a sweep of the repeated message map to + // prune any old entries that don't look like they are repeating any more. + static const uint32_t purgeDeferredMessageTimeMs = 100; + + // String hash used to identify similar messages. + typedef uint32_t PrefixHashType; + + // For our uses we don't want LogTime, which is a calendar time that's hard and slow to work + // with. Instead we want to compare milliseconds in an absolute way. So we define a type that + // is absolute milliseconds which can derived from a LogTime. + typedef int64_t LogTimeMs; + + // Stores a recently generated message. It doesn't store the entire message string, + // as we care only about the first N characters of messages. We store the last M messages + // ever received in a list of RecentMessages. That way we can tell if there was a recent repeat. + // To consider: we don't currently consider the subsystem name as part of the uniqueness of the + // string. We may want or need to do this, but it's very unlikely two strings would be the same + // while coming from separate subsystems. + struct RecentMessage { + LogTimeMs timeMs; // Time that the message was generated. + // Don't need to store the message or message prefix itself, though it may + // help debugging. + }; + typedef std::unordered_map RecentMessageMapType; + + // Represents a message which has been identified as being repeated. This struct allows us to + // know how many times the message was repeated, when it was first seen, etc. + struct RepeatedMessage { + std::string subsystemName; // To consider: Convert to char [16] + Level messageLogLevel; // log level, e.g. Level::Trace. + std::string stream; // The first message of the repeated set. + LogTimeMs initialTimeMs; // Time the message was first seen. + LogTimeMs lastTimeMs; // Time the most recent repeat of the message was seen. + uint32_t aggregatedCount; // Number of times this message was aggregated for later. + uint32_t printedCount; // Number of times this message has been 'printed'; + // aggregate printing counts multiple times towards this. + RepeatedMessage() + : subsystemName(), + messageLogLevel(), + stream(), + initialTimeMs(), + lastTimeMs(), + aggregatedCount(), + printedCount() {} + RepeatedMessage( + const char* subsystemName_, + Level messageLogLevel_, + const char* stream_, + LogTimeMs initialTimeMs_, + LogTimeMs lastTimeMs_, + uint32_t aggregatedCount_) + : subsystemName(subsystemName_), + messageLogLevel(messageLogLevel_), + stream(stream_), + initialTimeMs(initialTimeMs_), + lastTimeMs(lastTimeMs_), + aggregatedCount(aggregatedCount_), + printedCount() {} + }; + typedef std::unordered_map RepeatedMessageMapType; + + // Prints a message that's an aggregate deferred printing. + void PrintDeferredAggregateMessage(OutputWorker* outputWorker, RepeatedMessage& repeatedMessage); + + // Calculates a hash for the given string for at most characters. + static PrefixHashType GetHash(const char* str); + + // Gets the current LogTime in LogTimeMs. + static LogTimeMs GetCurrentLogMillisecondTime(); + + // Converts LogTime to LogTimeMs. + static LogTimeMs LogTimeToMillisecondTime(const LogTime& logTime); + + // Returns end - begin, possibly with some fixup. + static int64_t GetLogMillisecondTimeDifference(LogTimeMs begin, LogTimeMs end); + + protected: + // Mutex to which covers all our member data. + std::recursive_mutex Mutex; + + // Used to protect against re-entrancy. Our Poll function calls external code, and we want to + // prevent there being a problem if that external code unexpectedly calls us back. + bool BusyInWrite; + + // To do: Get a fixed-size node allocator working with this container for low overhead. + RecentMessageMapType RecentMessageMap; + + // To consider: Get a fixed-size node allocator working with this container for low overhead. + RepeatedMessageMapType RepeatedMessageMap; + + // We don't need to store the string, just the string hash. + std::unordered_set RepeatedMessageExceptionSet; + + // We don't need to store the string, just the string hash. + std::unordered_set RepeatedMessageSubsystemExceptionSet; +}; + +// Iterate through the list of channels before the CRT has initialized +#pragma pack(push, 1) +struct ChannelNode { + const char* SubsystemName; // This is always a pointer to a Channel's SubsystemName.Get() + Log_Level_t* Level; + bool* UserOverrodeMinimumOutputLevel; + ChannelNode* Next; +}; +#pragma pack(pop) + +// Export the function to access OutputWorker::Write(). This is used by the Channel class +// to allow writing with OutputWorker possibly in a separate module. +void OutputWorkerOutputFunctionC( + const char* subsystemName, + Log_Level_t messageLogLevel, + const char* stream, + bool relogged, + Write_Option_t option); + +typedef void (*OutputWorkerOutputFunctionType)( + const char* subsystemName, + Log_Level_t messageLogLevel, + const char* stream, + bool relogged, + Write_Option_t option); + +// Shutdown the logging system and release memory +void ShutdownLogging(); + +// Restart the logging system +void RestartLogging(); + +// Log Output Worker Thread +class OutputWorker { + OutputWorker(); // Use GetInstance() to get the singleton instance. + + public: + static OutputWorker* GetInstance(); + + ~OutputWorker(); + + void InstallDefaultOutputPlugins(); + + // Start/stop logging output (started automatically) + void Start(); + void Stop(); + + // Blocks until all log messages before this function call are completed. + void Flush(); + + // Write a log buffer to the output + // relogged indicates that the message is being relogged, which is useful to prevent + // double-logging messages. + + void Write( + const char* subsystemName, + Level messageLogLevel, + const char* stream, + bool relogged, + WriteOption option); + + // Plugin management + void AddPlugin(std::shared_ptr plugin); + void RemovePlugin(std::shared_ptr plugin); + std::shared_ptr GetPlugin(const char* const pluginName); + + // Disable all output + void DisableAllPlugins(); + + // Get the lock used for the channels. + Lock* GetChannelsLock(); + + // Add an exception to the RepeatedMessageManager + void AddRepeatedMessageSubsystemException(const char* subsystemName); + + // Removes messages previously added with AddRepeatedMessageException + void RemoveRepeatedMessageSubsystemException(const char* subsystemName); + + // Sets the set of channels that can write to the given output. + // By default, all outputs are written to by all channels. But if you provide a set of + // channels with this function, then the output is written to only by the given channels. + // A typical use case of this is to associate a given channel 1:1 a given output, + // by combining usage of this function with the SetChannelOutputPlugins function. + // + // Example usage, which sets a 1:1 correspondence between a TimingData channel and a + // single log file for its output: + // ow->SetOutputPluginChannels("TimingDataLog", {"TimingData"}); + // ow->SetChannelOutputPlugins("TimingData", {"TimingDataLog"}); + // or alternatively: + // ow->SetChannelSingleOutput("TimingData", "TimingDataLog"); + // + void SetOutputPluginChannels( + const char* outputPluginName, + const std::vector& channelNames); + + // Sets the set of outputs that a given channel can write to. + void SetChannelOutputPlugins( + const char* channelName, + const std::vector& outputPluginNames); + + // This combines usage of SetOutputPluginChannels and SetChannelOutputPlugins to associate a + // channel to exclusively the given output. No other channels will write to the given output, + // and the channel will write to no other outputs. + void SetChannelSingleOutput(const char* channelName, const char* outputPluginName); + + private: + // Is the logger running in a debugger? + bool IsInDebugger; + + bool DefaultPluginsDisabled; + + // It's here so we know it is valid in the scope of ~OutputWorker + Lock ChannelsLock; + + // Plugins + Lock PluginsLock; + std::set> Plugins; + + // Output -> channel filtering + // This is a case-sensitive map of output name to a set of channel names. + // Normally a given channel write is sent to all output plugins. But we support being explicit + // about the output than that. Behavior: + // If an output isn't present in this map then its writable by all channels. + // If an output is present, then it is writable only by the channels specified by the map. + // Threaded access to this is protected by PluginsLock. + std::unordered_map> OutputPluginChannelFiltering; + + // Channel -> output filtering + // This is a case-sensitive map of channel name to a set of output plugins. + // Normally a given channel write is sent to all output plugins. But we support being explicit + // about the output than that. Behavior: + // If a channel isn't present in this map then the channel is written to all outputs. + // If a channel is present, then it is written only to the outputs specified by the map. + // Threaded access to this is protected by PluginsLock. + std::unordered_map> ChannelOutputPluginFiltering; + + // Worker Log Buffer + struct QueuedLogMessage { + const Name SubsystemName; + const Level MessageLogLevel; + std::string Buffer; + LogTime Time; + QueuedLogMessage* Next; +#if defined(_WIN32) + OvrLogHandle FlushEvent; +#else + // Is this a fake event, just for the purpose of flushing the queue? + bool FlushEvent; +#endif // defined(_WIN32) + + QueuedLogMessage( + const char* subsystemName, + Level messageLogLevel, + const char* stream, + const LogTime& time); + }; + + // Maximum number of logs that we allow in the queue at a time. + // If we go beyond this limit, we keep a count of additional logs that were lost. + static const int WorkQueueLimit = 1000; + + Lock WorkQueueLock; // Lock guarding the work queue + QueuedLogMessage* WorkQueueHead; // Head of linked list of work that is queued + QueuedLogMessage* WorkQueueTail; // Tail of linked list of work that is queued + int WorkQueueSize; // Size of the linked list of queued work + int WorkQueueOverrun; // Number of log messages that exceeded the limit + // The work queue size is used to avoid overwhelming the logging thread, since it takes 1-2 + // milliseconds to log out each message it can easily fall behind a large amount of logs. Lost + // log messages are added to the WorkQueueOverrun count so that they can be reported as "X logs + // were lost". + + inline void WorkQueueAdd(QueuedLogMessage* msg) { + if (WorkQueueTail) { + WorkQueueTail->Next = msg; + } else { + WorkQueueHead = msg; + } + WorkQueueTail = msg; + ++WorkQueueSize; + } + +#if defined(_WIN32) +#define OVR_THREAD_FUNCTION_TYPE DWORD WINAPI +#else +#define OVR_THREAD_FUNCTION_TYPE uint32_t +#endif + + static OVR_THREAD_FUNCTION_TYPE WorkerThreadEntrypoint_(void* worker); + + void WorkerThreadEntrypoint(); + + Lock StartStopLock; +#if defined(_WIN32) + // Event letting the worker thread know the queue is not empty + AutoHandle WorkerWakeEvent; + Terminator WorkerTerminator; + AutoHandle LoggingThread; +#else + std::atomic Terminated; + std::mutex WorkerCvMutex; + std::condition_variable WorkerCv; + std::thread LoggingThread; +#endif // defined(_WIN32) + RepeatedMessageManager RepeatedMessageManagerInstance; + + // Append level and subsystem name to timestamp buffer + // The buffer should point to the ending null terminator of + // the timestamp string. + static void + AppendHeader(char* buffer, size_t bufferBytes, Level level, const char* subsystemName); + + void ProcessQueuedMessages(); + + void + FlushDbgViewLogImmediately(const char* subsystemName, Level messageLogLevel, const char* stream); +}; + +//----------------------------------------------------------------------------- +// ErrorSilencer +// +// This will demote errors to warnings in the log until it goes out of scope. +// Helper class that allows error silencing to be done several function calls +// up the stack and checked down the stack. +class ErrorSilencer { + public: + // Returns a bitfield of SilenceOptions that are currently in effect + static int GetSilenceOptions(); + + // Start silencing errors. + ErrorSilencer(int options = DemoteErrorsToWarnings); + + enum SilenceOptions { + // Error logs will be demoted to the warning log level + DemoteErrorsToWarnings = 1, + + // All Log* methods will be silenced + CompletelySilenceLogs = 2, + + // OVR::MakeError will not assert when errors are set + PreventErrorAsserts = 4, + + // All logs at a level > Debug will be set to Debug level + DemoteToDebug = 8 + }; + + // Stop silencing errors. + ~ErrorSilencer(); + + private: + // Start silencing errors. This is done automatically be the constructor. + void Silence(); + + // Stop silencing errors. This is done automatically be the deconstructor. + void Unsilence(); + + int Options = 0; +}; + +//----------------------------------------------------------------------------- +// Channel +// +// One named logging channel. + +class Channel { + public: + Channel(const char* nameString); + Channel(const Channel& other); + ~Channel(); + + // This is the initial default minimum level for a newly constructed Channel. + const Level DefaultMinimumOutputLevel = Level::Info; + + // Same thing as channel name. + // To do: rename all usage of SubsystemName to ChannelName. + const Name SubsystemName; + + // Deprecated, use SubsystemName.Get() instead + const char* GetName() const { + return SubsystemName.Get(); + } + + // Add an extra prefix to all log messages generated by the channel. + // This function is *not* thread-safe. Logging from another thread while changing + // the prefix can cause crashes. + std::string GetPrefix() const; + void SetPrefix(const std::string& prefix); + + // Set the minimum output level permitted from this channel. + void SetMinimumOutputLevel(Level newLevel); + + // Set the output level temporarily for this session without remembering that setting. + void SetMinimumOutputLevelNoSave(Level newLevel); + + Level GetMinimumOutputLevel() const; + + LOGGING_INLINE bool Active(Level level) const { + return MinimumOutputLevel <= (uint32_t)level; + } + + // Target of doLog function + static void SetOutputWorkerOutputFunction(OutputWorkerOutputFunctionType function) { + OutputWorkerOutputFunction = function; + } + + template + LOGGING_INLINE void Log(Level level, Args&&... args) const { + if (Active(level)) { + doLog(level, std::forward(args)...); + } + } + + template + LOGGING_INLINE void LogError(Args&&... args) const { + if (Active(Level::Error)) { + doLog(Level::Error, std::forward(args)...); + } + } + + template + LOGGING_INLINE void LogWarning(Args&&... args) const { + if (Active(Level::Warning)) { + doLog(Level::Warning, std::forward(args)...); + } + } + + template + LOGGING_INLINE void LogInfo(Args&&... args) const { + if (Active(Level::Info)) { + doLog(Level::Info, std::forward(args)...); + } + } + + template + LOGGING_INLINE void LogDebug(Args&&... args) const { + if (Active(Level::Debug)) { + doLog(Level::Debug, std::forward(args)...); + } + } + + template + LOGGING_INLINE void LogTrace(Args&&... args) const { + if (Active(Level::Trace)) { + doLog(Level::Trace, std::forward(args)...); + } + } + + // printf style log functions + template + LOGGING_INLINE void LogF(Level level, Args&&... args) const { + if (Active(level)) { + doLogF(level, std::forward(args)...); + } + } + + template + LOGGING_INLINE void LogErrorF(Args&&... args) const { + if (Active(Level::Error)) { + doLogF(Level::Error, std::forward(args)...); + } + } + + template + LOGGING_INLINE void LogWarningF(Args&&... args) const { + if (Active(Level::Warning)) { + doLogF(Level::Warning, std::forward(args)...); + } + } + + template + LOGGING_INLINE void LogInfoF(Args&&... args) const { + if (Active(Level::Info)) { + doLogF(Level::Info, std::forward(args)...); + } + } + + template + LOGGING_INLINE void LogDebugF(Args&&... args) const { + if (Active(Level::Debug)) { + doLogF(Level::Debug, std::forward(args)...); + } + } + + template + LOGGING_INLINE void LogTraceF(Args&&... args) const { + if (Active(Level::Trace)) { + doLogF(Level::Trace, std::forward(args)...); + } + } + + // DANGER DANGER DANGER + // This function forces a log message to be recorded even if the log queue is full. + // This is dangerous because the caller can run far ahead of the output writer thread + // and cause a large amount of memory to be allocated and logging tasks can take many + // minutes to flush afterwards. It should only be used when the data is critical. + template + LOGGING_INLINE void DangerousForceLog(Level level, Args&&... args) const { + if (Active(level)) { + int silenceOptions = ErrorSilencer::GetSilenceOptions(); + if (silenceOptions & ErrorSilencer::CompletelySilenceLogs) { + return; + } + + if (level > Level::Debug && (silenceOptions & ErrorSilencer::DemoteToDebug)) { + // Demote to debug + level = Level::Debug; + } else if ( + level == Level::Error && (silenceOptions & ErrorSilencer::DemoteErrorsToWarnings)) { + // Demote to warning + level = Level::Warning; + } + + LogStringBuffer buffer(SubsystemName.Get(), level); + + writeLogBuffer(buffer, Prefix, args...); + + // Submit buffer to logging subsystem + const std::string& tmp = buffer.Stream.str(); + OutputWorkerOutputFunction( + buffer.SubsystemName.Get(), + (Log_Level_t)buffer.MessageLogLevel, + tmp.c_str(), + buffer.Relogged, + (Write_Option_t)WriteOption::DangerouslyIgnoreQueueLimit); + } + } + // DANGER DANGER DANGER + + private: + //------------------------------------------------------------------------- + // Internal Implementation + + Channel() = delete; + Channel(Channel&& other) = delete; + Channel& operator=(const Channel& other) = delete; + Channel& operator=(Channel&& other) = delete; + + friend class Configurator; + + // Used to iterate through a linked list of Channel objects + // A linked list is used to avoid CRT new / delete during startup as this is called from the + // constructor + ChannelNode Node; + void registerNode(); + + // Level at which this channel will log. + Log_Level_t MinimumOutputLevel; + + // Optional prefix + std::string Prefix; + + // So changing Prefix is threadsafe + mutable Lock PrefixLock; + + bool UserOverrodeMinimumOutputLevel; + + // Target of doLog function + static OutputWorkerOutputFunctionType OutputWorkerOutputFunction; + + // Target of OnChannelLevelChange + static void ConfiguratorOnChannelLevelChange( + const char* channelName, + Log_Level_t minimumOutputLevel); + + // Target of Register + static void ConfiguratorRegister(ChannelNode* channelNode); + + // Target of Unregister + static void ConfiguratorUnregister(ChannelNode* channelNode); + + template + LOGGING_INLINE void writeLogBuffer(LogStringBuffer& buffer, T&& arg) const { + LogStringize(buffer, arg); + } + + template + LOGGING_INLINE void writeLogBuffer(LogStringBuffer& buffer, T&& arg, Args&&... args) const { + writeLogBuffer(buffer, arg); + writeLogBuffer(buffer, args...); + } + + // Unroll arguments + template + LOGGING_INLINE void doLog(Level level, Args&&... args) const { + int silenceOptions = ErrorSilencer::GetSilenceOptions(); + if (silenceOptions & ErrorSilencer::CompletelySilenceLogs) { + return; + } + + if (level > Level::Debug && (silenceOptions & ErrorSilencer::DemoteToDebug)) { + // Demote to debug + level = Level::Debug; + } else if (level == Level::Error && (silenceOptions & ErrorSilencer::DemoteErrorsToWarnings)) { + // Demote to warning + level = Level::Warning; + } + + LogStringBuffer buffer(SubsystemName.Get(), level); + + writeLogBuffer(buffer, Prefix, args...); + + // Submit buffer to logging subsystem + const std::string& tmp = buffer.Stream.str(); + OutputWorkerOutputFunction( + buffer.SubsystemName.Get(), + (Log_Level_t)buffer.MessageLogLevel, + tmp.c_str(), + buffer.Relogged, + (Write_Option_t)WriteOption::Default); + } + + // Returns the buffer capacity required to printf the given format+arguments. + // Returns -1 if the format is invalid. + static int GetPrintfLengthV(const char* format, va_list argList) { + int size; + +#if defined( \ + _MSC_VER) // Microsoft doesn't support C99-Standard vsnprintf, so need to use _vscprintf. + size = _vscprintf(format, argList); // Returns the required strlen, or -1 if format error. +#else + size = vsnprintf( + nullptr, 0, format, argList); // Returns the required strlen, or negative if format error. +#endif + + if (size > 0) // If we can 0-terminate the output... + ++size; // Add one to account for terminating null. + else + size = -1; + + return size; + } + + static int GetPrintfLength(const char* format, ...); + + template + LOGGING_INLINE void doLogF(Level level, Args&&... args) const { + int silenceOptions = ErrorSilencer::GetSilenceOptions(); + if (silenceOptions & ErrorSilencer::CompletelySilenceLogs) { + return; + } + + if (level > Level::Debug && (silenceOptions & ErrorSilencer::DemoteToDebug)) { + // Demote to debug + level = Level::Debug; + } else if (level == Level::Error && (silenceOptions & ErrorSilencer::DemoteErrorsToWarnings)) { + // Demote to warning + level = Level::Warning; + } + + LogStringBuffer buffer(SubsystemName.Get(), level); + + char logCharsLocal[1024]; + char* logChars = logCharsLocal; + char* logCharsAllocated = nullptr; + +#if defined(_MSC_VER) + int result = _snprintf_s(logCharsLocal, sizeof(logCharsLocal), _TRUNCATE, args...); +#else +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wformat-nonliteral" +#pragma clang diagnostic ignored "-Wformat-security" +#endif // defined(__clang__) + int result = snprintf(logCharsLocal, sizeof(logCharsLocal), args...); + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif // defined(__clang__) +#endif + + if ((result < 0) || ((size_t)result >= sizeof(logCharsLocal))) { + int requiredSize = GetPrintfLength(args...); + + if ((requiredSize < 0) || (requiredSize > (1024 * 1024))) { + LOGGING_DEBUG_BREAK(); // This call should be converted to the new log system. + return; + } + + logCharsAllocated = new char[requiredSize]; + logChars = logCharsAllocated; + +#if defined(_MSC_VER) + _snprintf_s(logChars, (size_t)requiredSize, _TRUNCATE, args...); +#else +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wformat-nonliteral" +#pragma clang diagnostic ignored "-Wformat-security" +#endif // defined(__clang__) + snprintf(logChars, (size_t)requiredSize, args...); + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif // defined(__clang__) +#endif + } + + writeLogBuffer(buffer, Prefix, logChars); + + // Submit buffer to logging subsystem + const std::string& tmp = buffer.Stream.str(); + OutputWorkerOutputFunction( + buffer.SubsystemName.Get(), + (Log_Level_t)buffer.MessageLogLevel, + tmp.c_str(), + buffer.Relogged, + (Write_Option_t)WriteOption::Default); + + delete[] logCharsAllocated; + } +}; + +//----------------------------------------------------------------------------- +// Log Configurator +// +// Centralized object that can configure and enumerate all the channels. + +class ConfiguratorPlugin { + public: + ConfiguratorPlugin(); + virtual ~ConfiguratorPlugin(); + + // Modify the channel level if it is set, otherwise leave it as-is. + virtual void RestoreChannelLevel(const char* name, Level& level) = 0; + + // Sets the channel level + virtual void SaveChannelLevel(const char* name, Level level) = 0; +}; + +class Configurator { + friend class Channel; + friend class OutputWorker; + + Configurator(); // Call GetInstance() to get the singleton instance. + + public: + // Get singleton instance for logging configurator + static Configurator* GetInstance(); + + ~Configurator(); + + void SetGlobalMinimumLogLevel(Level level); + + inline void SilenceLogging() { + // Set the minimum logging level higher than any actual message. + SetGlobalMinimumLogLevel(Level::Count); + } + + // Sets the ConfiguratorPlugin for this Configurator to use. + void SetPlugin(std::shared_ptr plugin); + + // Get all channels - note channels do not necessarily have unique names + void GetChannels(std::vector>& channels); + + // Set all channels with channelName to level. + // Cann disable a channel by using Level::Disabled. + void SetChannelLevel(const std::string& channelName, Level level); + + // Internal: Invoked through callbacks + void OnChannelLevelChange(const char* channelName, Log_Level_t level); + + // Internal: Load log level for a channel from disk, set all channels with this name to this level + void RestoreChannelLogLevel(const char* channelName); + + // Internal: Load log level for a channel from disk, set this channel to this level + void RestoreChannelLogLevel(ChannelNode* channelNode); + + // Internal: Iterate through all channels and store them + void RestoreAllChannelLogLevels(); + + // Maps to OutputWorker::SetOutputPluginChannels. See that for documentation. + void SetOutputPluginChannels( + const char* outputPluginName, + const std::vector& channelNames); + + // Maps to OutputWorker::SetChannelOutputPlugins. See that for documentation. + void SetChannelOutputPlugins( + const char* channelName, + const std::vector& outputPluginNames); + + // Maps to OutputWorker::SetChannelSingleOutput. See that for documentation. + void SetChannelSingleOutput(const char* channelName, const char* outputPluginName); + + private: + void RestoreAllChannelLogLevelsNoLock(); + + uint32_t GlobalMinimumLogLevel; + std::shared_ptr Plugin; + + void SetChannelLevelNoLock(const std::string& channelName, Level level, bool overrideUser); +}; + +// Convenience function: ovrlog::Flush(); +inline void Flush() { + OutputWorker::GetInstance()->Flush(); +} + +} // namespace ovrlog diff --git a/ovr_sdk_win_23.0.0/Logging/Logging/Logging_OutputPlugins.h b/ovr_sdk_win_23.0.0/Logging/Logging/Logging_OutputPlugins.h new file mode 100644 index 0000000..6a1d726 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/Logging/Logging_OutputPlugins.h @@ -0,0 +1,105 @@ +/************************************************************************************ + +Filename : Logging_OutputPlugins.h +Content : Logging output plugins +Created : Oct 26, 2015 +Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef Logging_OutputPlugins_h +#define Logging_OutputPlugins_h + +#include "Logging/Logging_Library.h" + +namespace ovrlog { + +//----------------------------------------------------------------------------- +// Console +// +// Console window output (colorized) +// Prints at stdout level, even for errors. +// This takes about 3 milliseconds per message in debug mode. +class OutputConsole : public OutputPlugin { + public: + OutputConsole(bool useStdio = false); + ~OutputConsole(); + + // If true then use stdio for output instead of platform-savvy calls. + void SetStdioUsage(bool enable); + + protected: + virtual const char* GetUniquePluginName() override; + virtual void Write(Level level, const char* subsystem, const char* header, const char* utf8msg) + override; + + // If enabled then we use stdio instead of platform-specific calls. By default we + // use direct platform calls because they are lower overhead and because (for Windows) + // they are UTF8-savvy (unlike stdio on Windows). Defaults to false. + bool UseStdio; +}; + +//----------------------------------------------------------------------------- +// DbgView +// +// This is the MSVC / DbgView log +// This takes about 150 microseconds per message in debug mode. + +class OutputDbgView : public OutputPlugin { + public: + OutputDbgView(); + ~OutputDbgView(); + + private: + virtual const char* GetUniquePluginName() override; + virtual void Write(Level level, const char* subsystem, const char* header, const char* utf8msg) + override; +}; + +//----------------------------------------------------------------------------- +// System Application Event Log +// +// Windows Event Viewer Application Log +// This takes about 1 millisecond per message in debug mode. + +class OutputEventLog : public OutputPlugin { + public: + OutputEventLog(); + ~OutputEventLog(); + + private: +#if defined(_WIN32) + typedef HANDLE EventSourceHandle; +#else + typedef void* EventSourceHandle; +#endif + + // Event source handle initialized in constructor and used for logging + EventSourceHandle hEventSource; + Level MinReportEventLevel; + + virtual const char* GetUniquePluginName() override; + virtual void Write(Level level, const char* subsystem, const char* header, const char* utf8msg) + override; +}; + +} // namespace ovrlog + +#endif // Logging_OutputPlugins_h diff --git a/ovr_sdk_win_23.0.0/Logging/Logging/Logging_Tools.h b/ovr_sdk_win_23.0.0/Logging/Logging/Logging_Tools.h new file mode 100644 index 0000000..4b067c4 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/Logging/Logging_Tools.h @@ -0,0 +1,230 @@ +/************************************************************************************ + +Filename : Logging_Tools.h +Content : Tools for Logging +Created : Oct 26, 2015 +Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef Logging_Tools_h +#define Logging_Tools_h + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4265) // disable the virtual destructor warning generated by +#endif + +#include + +//----------------------------------------------------------------------------- +// Platform-specific macros + +#ifdef _MSC_VER +#define LOGGING_INLINE __forceinline +#else +#define LOGGING_INLINE inline +#endif + +#if defined(_DEBUG) || defined(DEBUG) +#define LOGGING_DEBUG +#endif + +#define LOGGING_STRINGIZEIMPL(x) #x +#define LOGGING_STRINGIZE(x) LOGGING_STRINGIZEIMPL(x) + +#if defined(_WIN32) +// It is common practice to define WIN32_LEAN_AND_MEAN to reduce compile times. +// However this then requires us to define our own NTSTATUS data type and other +// irritations throughout our code-base. +#ifndef WIN32_LEAN_AND_MEAN +//#define WIN32_LEAN_AND_MEAN +#endif + +// Prevents from #including , as we use instead. +#ifndef _WINSOCKAPI_ +#define DID_DEFINE_WINSOCKAPI +#define _WINSOCKAPI_ +#endif + +// Prevents from defining min() and max() macro symbols. +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#define WIN +#include +#endif + +// Work around some broken Windows headers: +#ifdef DID_DEFINE_WINSOCKAPI +#undef _WINSOCKAPI_ +#undef DID_DEFINE_WINSOCKAPI +#endif + +#if defined(LOGGING_DEBUG) +#if defined(_MSC_VER) +#include +#define LOGGING_DEBUG_BREAK() __debugbreak() +#else +#define LOGGING_DEBUG_BREAK() \ + { __asm__("int $3\n" : :); } +#endif +#else +#define LOGGING_DEBUG_BREAK() +#endif + +#include +#include + +namespace ovrlog { + +#if defined(_WIN32) +typedef HANDLE OvrLogHandle; +#endif // defined(_WIN32) + +//----------------------------------------------------------------------------- +// Lock +// +// Critical section wrapper. +// +class Lock { + public: + Lock(); + ~Lock(); + + // Returns true if lock could be held. + bool TryEnter(); + + void Enter(); + void Leave(); + + private: +#if defined(_WIN32) + // Until the behavior of std::recursive_mutex is vetted, we use CRITICAL_SECTION on Windows. + CRITICAL_SECTION cs; +#else + std::recursive_mutex m; +#endif +}; + +//----------------------------------------------------------------------------- +// Locker +// +// Scoped lock wrapper. +// To do: Replace this class with direct std::lock usage. +// +class Locker { + public: + Locker(Lock* lock = nullptr); + Locker(Lock& lock); + ~Locker(); + + // Returns true if lock could be held. + bool TrySet(Lock* lock); + bool TrySet(Lock& lock); + + // Lock the given lock. Unlocks previously held lock. + void Set(Lock* lock); + void Set(Lock& lock); + + // Unlock any previously held lock. + void Clear(); + + private: + Lock* TheLock; +}; + +#if defined(_WIN32) +//----------------------------------------------------------------------------- +// AutoHandle +// +// Auto-close wrapper for a HANDLE that is invalid when NULL. +// For example, ::OpenProcess() returns NULL on failure. +class AutoHandle { + public: + AutoHandle(OvrLogHandle handle = nullptr); + ~AutoHandle(); + + void operator=(OvrLogHandle handle); + + OvrLogHandle Get() const { + return TheHandle; + } + + bool IsValid() const { + return TheHandle != nullptr; + } + + void Clear(); + + protected: + OvrLogHandle TheHandle; +}; + +//----------------------------------------------------------------------------- +// Terminator +// +// Helper class that allows for signaled exits to an infinite event wait. +// The main purpose is the WaitOn() function. +class Terminator { + public: + Terminator(); + ~Terminator(); + + bool IsTerminated() const { + return Terminated; + } + + // Setup + bool Initialize(); + + // Flag terminated + void Terminate(); + + // Returns true if the event signaled and false on termination or timeout. + // Call IsTerminated() to differentiate termination from timeout. + // Passing INFINITE for timeout will only return false on termination. + bool WaitOn(OvrLogHandle hEvent, uint32_t timeoutMsec = INFINITE); + + // Returns true if the sleep interval exceeded or false on termination. + bool WaitSleep(int milliseconds); + + private: + // Should we terminate? + std::atomic Terminated; + + // Event to wake up during waits + AutoHandle TerminateEvent; +}; +#endif // defined(_WIN32) + +//----------------------------------------------------------------------------- +// Tools + +bool IsDebuggerAttached(); + +} // namespace ovrlog + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // Logging_Tools_h diff --git a/ovr_sdk_win_23.0.0/Logging/PCSDK_Logging_dependency.props b/ovr_sdk_win_23.0.0/Logging/PCSDK_Logging_dependency.props new file mode 100644 index 0000000..aebdc8a --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/PCSDK_Logging_dependency.props @@ -0,0 +1,21 @@ + + + + + + + $(MSBuildThisFileDirectory);%(AdditionalIncludeDirectories) + + + + + {08ea9e99-1abe-41b3-9498-51a7824bfca5} + false + + + + + + <__PCSDK_Logging_dependency>true + + diff --git a/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging.vcxproj b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging.vcxproj new file mode 100644 index 0000000..6e097e8 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging.vcxproj @@ -0,0 +1,170 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug_DllCrt + Win32 + + + Release_DllCrt + Win32 + + + Debug_DllCrt + x64 + + + Release_DllCrt + x64 + + + + {08ea9e99-1abe-41b3-9498-51a7824bfca5} + Win32Proj + PCSDK_Logging + + + + StaticLibrary + true + v140 + x64 + Unicode + + + StaticLibrary + false + v140 + x64 + true + Unicode + + + StaticLibrary + true + v140 + x64 + Unicode + + + StaticLibrary + false + v140 + x64 + true + Unicode + + + StaticLibrary + true + v140 + x64 + Unicode + + + StaticLibrary + false + v140 + x64 + true + Unicode + + + StaticLibrary + true + v140 + x64 + Unicode + + + StaticLibrary + false + v140 + x64 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging.vcxproj.filters b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging.vcxproj.filters new file mode 100644 index 0000000..5476403 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging.vcxproj.filters @@ -0,0 +1,40 @@ + + + + + + + + + {1131b44d-3c37-4e67-98be-d3820108c671} + + + {8090b7c1-d4a9-450b-ab8c-eeca877db86c} + + + {d213a0aa-e383-41d3-8d35-2e48239d33af} + + + + + Logging + + + Logging + + + Logging + + + + + src + + + src + + + src\internal + + + diff --git a/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging_internal.props b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging_internal.props new file mode 100644 index 0000000..c56a6f0 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2015/PCSDK_Logging_internal.props @@ -0,0 +1,8 @@ + + + + + $(MSBuildThisFileDirectory)\..\..\..\;%(AdditionalIncludeDirectories) + + + diff --git a/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging.vcxproj b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging.vcxproj new file mode 100644 index 0000000..7ae24ea --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging.vcxproj @@ -0,0 +1,171 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug_DllCrt + Win32 + + + Release_DllCrt + Win32 + + + Debug_DllCrt + x64 + + + Release_DllCrt + x64 + + + + {08ea9e99-1abe-41b3-9498-51a7824bfca5} + Win32Proj + PCSDK_Logging + + + + StaticLibrary + true + v141 + x64 + Unicode + + + StaticLibrary + false + v141 + x64 + true + Unicode + + + StaticLibrary + true + v141 + x64 + Unicode + + + StaticLibrary + false + v141 + x64 + true + Unicode + + + StaticLibrary + true + v141 + x64 + Unicode + + + StaticLibrary + false + v141 + x64 + true + Unicode + + + StaticLibrary + true + v141 + x64 + Unicode + + + StaticLibrary + false + v141 + x64 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging.vcxproj.filters b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging.vcxproj.filters new file mode 100644 index 0000000..5ad9ef8 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging.vcxproj.filters @@ -0,0 +1,43 @@ + + + + + + + + + {1131b44d-3c37-4e67-98be-d3820108c671} + + + {8090b7c1-d4a9-450b-ab8c-eeca877db86c} + + + {d213a0aa-e383-41d3-8d35-2e48239d33af} + + + + + Logging + + + Logging + + + Logging + + + Logging + + + + + src + + + src + + + src\internal + + + diff --git a/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging_internal.props b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging_internal.props new file mode 100644 index 0000000..c56a6f0 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/Projects/Windows/VS2017/PCSDK_Logging_internal.props @@ -0,0 +1,8 @@ + + + + + $(MSBuildThisFileDirectory)\..\..\..\;%(AdditionalIncludeDirectories) + + + diff --git a/ovr_sdk_win_23.0.0/Logging/src/Logging_Library.cpp b/ovr_sdk_win_23.0.0/Logging/src/Logging_Library.cpp new file mode 100644 index 0000000..c1f56f1 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/src/Logging_Library.cpp @@ -0,0 +1,1537 @@ +/************************************************************************************ + +Filename : Logging_Library.cpp +Content : Logging system +Created : Oct 26, 2015 +Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Logging/Logging_Library.h" +#include "Logging/Logging_OutputPlugins.h" + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4530) // C++ exception handler used, but unwind semantics are not enabled +#endif // _MSC_VER + +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#endif // _MSC_VER + +#ifndef _WIN32 +#include +#include +#include +#endif // !_WIN32 + +namespace ovrlog { + +//-------------------------------------------------------------------------------------------------- +// LogTime +//-------------------------------------------------------------------------------------------------- + +LogTime GetCurrentLogTime() { +#if defined(_WIN32) + SYSTEMTIME t; + ::GetLocalTime(&t); + return t; +#else + return std::chrono::system_clock::now(); +#endif +} + +//-------------------------------------------------------------------------------------------------- +// RepeatedMessageManager +//-------------------------------------------------------------------------------------------------- + +RepeatedMessageManager::RepeatedMessageManager() + : Mutex(), + BusyInWrite(false), + RecentMessageMap(), + RepeatedMessageMap(), + RepeatedMessageExceptionSet() {} + +void RepeatedMessageManager::PrintDeferredAggregateMessage( + OutputWorker* outputWorker, + RepeatedMessage& repeatedMessage) { + // Don't lock Mutex, as it's expected to already be locked. + + // Add the prefix to repeatedMessage->stream instead of writing it separately because a race + // condition could otherwise cause another message to be printed between the two. + char prefixMessage[64]; // Impossible to overflow below. + size_t prefixLength = snprintf( + prefixMessage, + sizeof(prefixMessage), + "[Aggregated %d times] ", + repeatedMessage.aggregatedCount); + repeatedMessage.stream.insert(0, prefixMessage, prefixLength); + + // We use WriteOption::DangerouslyIgnoreQueueLimit because it is very unlikely that these + // messages could be generated in a runaway fashion. But they are an aggregate and so are more + // important that their non-aggregated versions would be. + BusyInWrite = true; + outputWorker->Write( + repeatedMessage.subsystemName.c_str(), + repeatedMessage.messageLogLevel, + repeatedMessage.stream.c_str(), + false, + WriteOption::DangerouslyIgnoreQueueLimit); + BusyInWrite = false; +} + +RepeatedMessageManager::LogTimeMs RepeatedMessageManager::GetCurrentLogMillisecondTime() { + const LogTime currentLogTime = GetCurrentLogTime(); + const LogTimeMs currentLogTimeMs = LogTimeToMillisecondTime(currentLogTime); + return currentLogTimeMs; +} + +RepeatedMessageManager::LogTimeMs RepeatedMessageManager::LogTimeToMillisecondTime( + const LogTime& logTime) { +#if defined(_WIN32) + // Time is represented by SYSTEMTIME, which is a calendar time, with 1ms granularity. + // We need to quickly subtract two SYSTEMTIMEs, which is hard to do because it contains + // year, month, day, hour, minute, second, millisecond components. We could use the Windows + // SystemTimeToFileTime function to convert SYSTEMTIME to FILETIME, which is an absolute + // time with a single value, but that's an expensive conversion. + LogTimeMs logTimeMs = (logTime.wHour * 3600000) + (logTime.wMinute * 60000) + + (logTime.wSecond * 1000) + logTime.wMilliseconds; + return logTimeMs; +#else + return std::chrono::duration_cast(logTime.time_since_epoch()).count(); +#endif +} + +int64_t RepeatedMessageManager::GetLogMillisecondTimeDifference(LogTimeMs begin, LogTimeMs end) { +#if defined(_WIN32) + if (end >= begin) // If the day didn't roll over between begin and end... + return (end - begin); + return (86400000 + (end - begin)); // Else assume exactly one day rolled over. +#else + return (end - begin); +#endif +} + +RepeatedMessageManager::PrefixHashType RepeatedMessageManager::GetHash(const char* p) { + // Fowler / Noll / Vo (FNV) Hash + // FNV is a great string hash for reduction of collisions, but the cost benefit is high. + // We can get away with a fairly poor string hash here which is very fast. + // + PrefixHashType hash(2166136261U); + const char* pEnd = (p + messagePrefixLength); + while (*p && (p < pEnd)) { + hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24); + hash ^= (uint8_t)*p++; + } + return hash; + + // uint32_t hash(0); // To do: See if this hash is too poor. + // const char* pEnd = (p + messagePrefixLength); + // while(*p && (p < pEnd)) + // hash += (uint8_t)*p++; + // return hash; +} + +RepeatedMessageManager::HandleResult RepeatedMessageManager::HandleMessage( + const char* subsystemName, + Level messageLogLevel, + const char* stream) { + std::lock_guard lock(Mutex); + + if (BusyInWrite) // If we are here due to our own call of OutputWorker::Write from our Poll func.. + return HandleResult::Passed; + + PrefixHashType prefixHash = GetHash(stream); + + // Check to see if we have this particular message in an exception list. + if (RepeatedMessageExceptionSet.find(prefixHash) != RepeatedMessageExceptionSet.end()) { + return HandleResult::Passed; + } + + PrefixHashType subsystemNameHash = GetHash(subsystemName); + if (RepeatedMessageSubsystemExceptionSet.find(subsystemNameHash) != + RepeatedMessageSubsystemExceptionSet.end()) { + return HandleResult::Passed; + } + + // We will need the current time below for all pathways. + const LogTimeMs currentLogTimeMs = GetCurrentLogMillisecondTime(); + + // First look at our repeated messages. This is a container of known repeating messages. + auto itRepeated = RepeatedMessageMap.find(prefixHash); + + if (itRepeated != RepeatedMessageMap.end()) { // If this is a message that's already repeating... + RepeatedMessage& repeatedMessage = itRepeated->second; + + // Assume subsystemName == repeatedMessage->subsystemName, though theoretically it's possible + // that two subsystems generate the same prefix string. Let's worry about that if we see it. + // + // Assume messageLogLevel == repeatedMessage->messageLogLevel for the purposes of handling + // repeated messages. It's possible that a subsystem may generate the same message string + // but with different log levels, but we've never seen that, and it may not be significant + // with respect to handling repeating anyway. Let's worry about that if we see it. + const LogTimeMs logTimeDifferenceMs = + GetLogMillisecondTimeDifference(repeatedMessage.lastTimeMs, currentLogTimeMs); + + if (logTimeDifferenceMs < maxDeferrableDetectionTimeMs) { // If this message was soon after + repeatedMessage.lastTimeMs = currentLogTimeMs; // the last one... + + // We actually print the first few seemingly repeated messages before deferring them. + if (repeatedMessage.printedCount < printedRepeatCount) { + repeatedMessage.printedCount++; + return HandleResult::Passed; + } + + // Else we aggregate it, and won't print it until later with a summary printing. + // If repeatedMessage.aggregatedCount >= maxDeferredMessages, then copy stream to + // repeatedMessage.stream, in order to print the most recent variation of this repeat when + // the aggregated print is done. + if (++repeatedMessage.aggregatedCount >= maxDeferredMessages) + repeatedMessage.stream = stream; + + return HandleResult::Aggregated; + } + // Else the repeated message was old and we don't don't consider this a repeat. + // Don't erase the entry from RepeatedMessageMap here, as we still need to do a final + // print of the aggregated message before removing it. We'll handle that in the Poll function. + } else { + // Else this message wasn't known to be previously repeating, but maybe it's the first repeat + // we are encountering. Check the RecentMessageMap for this. + auto itRecent = RecentMessageMap.find(prefixHash); + + if (itRecent != RecentMessageMap.end()) { // If it looks like a repeat of something recent... + RepeatedMessageMap[prefixHash] = RepeatedMessage( + subsystemName, messageLogLevel, stream, currentLogTimeMs, currentLogTimeMs, 0); + + // No need to keep it in the RecentMessageMap any more, since it's now classified as repeat. + RecentMessageMap.erase(itRecent); + } else { + // Else add it to RecentMessageMap. Old RecentMessageMap entries will be removed by Poll(). + RecentMessageMap[prefixHash] = RecentMessage{currentLogTimeMs}; + } + } + + return HandleResult::Passed; +} + +void RepeatedMessageManager::Poll(OutputWorker* outputWorker) { + std::vector messagesToPrint; + + { + std::lock_guard lock(Mutex); + + if (RecentMessageMap.size() > (recentMessageCount * 2)) { + // Prune the oldest messages out of RecentMessageMap until + // RecentMessageMap.size() == recentMessageCount. Unfortunately, RecentMessageMap is an + // unsorted hash container, so we can't quickly find the oldest N messages. We can solve + // this by doing a copy of iterators to an array, sort, erase first N iterators. A faster + // solution would be to keep a std::queue of iterators that were added to the map, though + // that results in some complicated code. Maybe we'll do that, but let's do the sort + // solution first. + const size_t arrayCapacity = (recentMessageCount * 3); + RecentMessageMapType::iterator itArray[arrayCapacity]; // Avoid memory allocation. + size_t itArraySize = 0; + + for (RecentMessageMapType::iterator it = RecentMessageMap.begin(); + (it != RecentMessageMap.end()) && (itArraySize < arrayCapacity); + ++it) { + itArray[itArraySize++] = it; + } + + std::sort( + itArray, + itArray + itArraySize, // Put the oldest at the end of the array. + [](const RecentMessageMapType::iterator& it1, + const RecentMessageMapType::iterator& it2) -> bool { + return (it2->second.timeMs < it1->second.timeMs); // Sort newest to oldest. + }); + + for (size_t i = 0; i < itArraySize; ++i) + RecentMessageMap.erase(itArray[i]); + } + + // Currently we go through the entire RepeatedMessageMap every time we are here, though we + // have a purgeDeferredMessageTimeMs constant which we have to make this more granular, for + // efficiency purposed. To do. + const LogTimeMs currentLogTimeMs = GetCurrentLogMillisecondTime(); + + for (auto it = RepeatedMessageMap.begin(); it != RepeatedMessageMap.end();) { + RepeatedMessage& repeatedMessage = it->second; + LogTimeMs logTimeDifferenceMs = + GetLogMillisecondTimeDifference(repeatedMessage.lastTimeMs, currentLogTimeMs); + + // If this message hasn't repeated in a while... + if (logTimeDifferenceMs > maxDeferrableDetectionTimeMs) { + // Print an aggregate result for this entry before removing it. + // Since we have already printed the first of a given repeated message, + // we do an aggregate print only if further printings were called for. + if (repeatedMessage.aggregatedCount) { // If there are any aggregated messages deferred... + // This will print the first variation of the string that was encountered. + // We can move the message instead of copy because we won't need it any more after this. + messagesToPrint.emplace_back(std::move(repeatedMessage)); + } + + it = RepeatedMessageMap.erase(it); + continue; + } else if (repeatedMessage.aggregatedCount >= maxDeferredMessages) { + messagesToPrint.emplace_back(repeatedMessage); + repeatedMessage.printedCount += repeatedMessage.aggregatedCount; + repeatedMessage.aggregatedCount = 0; // Reset this for a new round of aggregation. + } + ++it; + } + } // lock + + // We need to print these messages outside our locked Mutex because printing of these is + // calling out to external code which itself has mutexes and thus we need to avoid deadlock. + for (auto& repeatedMessage : messagesToPrint) + PrintDeferredAggregateMessage(outputWorker, repeatedMessage); +} + +void RepeatedMessageManager::AddRepeatedMessageException(const char* messagePrefix) { + std::lock_guard lock(Mutex); + + PrefixHashType prefixHash = GetHash(messagePrefix); + RepeatedMessageExceptionSet.insert(prefixHash); +} + +void RepeatedMessageManager::RemoveRepeatedMessageException(const char* messagePrefix) { + std::lock_guard lock(Mutex); + + PrefixHashType prefixHash = GetHash(messagePrefix); + auto it = RepeatedMessageExceptionSet.find(prefixHash); + if (it != RepeatedMessageExceptionSet.end()) { + RepeatedMessageExceptionSet.erase(it); + } +} + +void RepeatedMessageManager::AddRepeatedMessageSubsystemException(const char* subsystemName) { + std::lock_guard lock(Mutex); + + PrefixHashType subsystemNameHash = GetHash(subsystemName); + RepeatedMessageSubsystemExceptionSet.insert(subsystemNameHash); +} + +void RepeatedMessageManager::RemoveRepeatedMessageSubsytemException(const char* subsystemName) { + std::lock_guard lock(Mutex); + + PrefixHashType subsystemNameHash = GetHash(subsystemName); + auto it = RepeatedMessageSubsystemExceptionSet.find(subsystemNameHash); + if (it != RepeatedMessageExceptionSet.end()) { + RepeatedMessageExceptionSet.erase(it); + } +} + +// Don't use locks or register channels until OutputWorker::Start has been called +// Once called the first time, register all known channels and start using locks +static volatile bool OutputWorkerInstValid = false; +static ChannelNode* ChannelNodeHead = nullptr; +void ChannelRegisterNoLock(ChannelNode* channelNode) { + if (ChannelNodeHead) { + channelNode->Next = ChannelNodeHead; + ChannelNodeHead = channelNode; + } else { + ChannelNodeHead = channelNode; + channelNode->Next = nullptr; + } +} + +void ChannelRegister(ChannelNode* channelNode) { + Locker locker(OutputWorker::GetInstance()->GetChannelsLock()); + ChannelRegisterNoLock(channelNode); + Configurator::GetInstance()->RestoreChannelLogLevel(channelNode); +} + +void ChannelUnregisterNoLock(ChannelNode* channelNode) { + if (channelNode == ChannelNodeHead) { + ChannelNodeHead = channelNode->Next; + return; + } else { + if (ChannelNodeHead != nullptr) { + for (ChannelNode *prev = ChannelNodeHead, *cur = prev->Next; cur != nullptr; + prev = cur, cur = cur->Next) { + if (cur == channelNode) { + prev->Next = channelNode->Next; + return; + } + } + } + // did not find channel to unregister + assert(false); + } +} + +void ChannelUnregister(ChannelNode* channelNode) { + Locker locker(OutputWorker::GetInstance()->GetChannelsLock()); + + ChannelUnregisterNoLock(channelNode); +} + +//----------------------------------------------------------------------------- +// Export Write() as C API so we can use it across DLL boundaries. Not marking it +// as DLL visibile / DLL export. Expect it to be passed to DLLs after they are loaded. +void OutputWorkerOutputFunctionC( + const char* subsystemName, + Log_Level_t messageLogLevel, + const char* stream, + bool relogged, + Write_Option_t option) { + OutputWorker::GetInstance()->Write( + subsystemName, (Level)messageLogLevel, stream, relogged, (WriteOption)option); +} + +//----------------------------------------------------------------------------- +// Channel + +OutputWorkerOutputFunctionType Channel::OutputWorkerOutputFunction = OutputWorkerOutputFunctionC; + +void Channel::ConfiguratorOnChannelLevelChange( + const char* channelName, + Log_Level_t minimumOutputLevel) { + Configurator::GetInstance()->OnChannelLevelChange(channelName, minimumOutputLevel); +} +void Channel::ConfiguratorRegister(ChannelNode* channelNode) { + if (OutputWorkerInstValid == false) + ChannelRegisterNoLock(channelNode); + else + ChannelRegister(channelNode); +} +void Channel::ConfiguratorUnregister(ChannelNode* channelNode) { + if (OutputWorkerInstValid == false) + ChannelUnregisterNoLock(channelNode); + else + ChannelUnregister(channelNode); +} + +//----------------------------------------------------------------------------- +// Shutdown the logging system and release memory +void ShutdownLogging() { + // This function needs to be robust to multiple calls in a row + if (OutputWorkerInstValid) { + ovrlog::OutputWorker::GetInstance()->Stop(); + } +} + +void RestartLogging() { + if (OutputWorkerInstValid) { + ovrlog::OutputWorker::GetInstance()->Start(); + } +} + +//----------------------------------------------------------------------------- +// Log Output Worker Thread + +OutputWorker* OutputWorker::GetInstance() { + static OutputWorker worker; + return &worker; +} + +void OutputWorkerAtExit() { + // This function needs to be robust to multiple calls in a row + ShutdownLogging(); +} + +OutputWorker::OutputWorker() + : IsInDebugger(false), + DefaultPluginsDisabled(false), + PluginsLock(), + Plugins(), + OutputPluginChannelFiltering(), + ChannelOutputPluginFiltering(), + WorkQueueLock(), + WorkQueueOverrun(0), + StartStopLock() +#if defined(_WIN32) + , + WorkerWakeEvent(), + WorkerTerminator(), + LoggingThread() +#else + , + Terminated(true) +#endif // defined(_WIN32) +{ +#if defined(_WIN32) + // Create a worker wake event + WorkerWakeEvent = ::CreateEventW(nullptr, FALSE, FALSE, nullptr); +#endif // defined(_WIN32) + + IsInDebugger = IsDebuggerAttached(); + + InstallDefaultOutputPlugins(); + + OutputWorkerInstValid = true; + + Start(); +} + +OutputWorker::~OutputWorker() { + Stop(); + OutputWorkerInstValid = false; +} + +void OutputWorker::InstallDefaultOutputPlugins() { + // These are the default outputs for ALL applications: + + // If debugger is *not* attached, + if (!IsInDebugger) { + // Enable event log output. This logger is fairly slow, taking about 1 millisecond per log, + // and this is very expensive to flush after each log message for debugging. Since we almost + // never use the Event Log when debugging apps it is better to simply leave it out. +#ifdef OVR_ENABLE_OS_EVENT_LOG + AddPlugin(std::make_shared()); +#endif + + // Do not log to the DbgView output from the worker thread. When a debugger is attached we + // instead flush directly to the DbgView log so that the messages are available at breakpoints. + AddPlugin(std::make_shared()); + } + +#if defined(_WIN32) + // If there is a console window, + if (::GetConsoleWindow() != NULL) { + bool outputToStdout = false; + if (GetEnvironmentVariableW(L"OvrOutputToStdout", NULL, 0) > 0) { + outputToStdout = true; + } + + // Enable the console. This logger takes 3 milliseconds per message, so it is fairly + // slow and should be avoided if it is not needed (ie. console is not shown). + AddPlugin(std::make_shared(outputToStdout)); + } +#endif +} + +void OutputWorker::AddPlugin(std::shared_ptr plugin) { + if (!plugin) { + return; + } + + Locker locker(PluginsLock); + + RemovePlugin(plugin); + + Plugins.insert(plugin); +} + +void OutputWorker::RemovePlugin(std::shared_ptr pluginToRemove) { + if (!pluginToRemove) { + return; + } + + const char* nameOfPluginToRemove = pluginToRemove->GetUniquePluginName(); + + Locker locker(PluginsLock); + + for (auto& existingPlugin : Plugins) { + const char* existingPluginName = existingPlugin->GetUniquePluginName(); + + // If the names match exactly, + if (0 == strcmp(nameOfPluginToRemove, existingPluginName)) { + Plugins.erase(existingPlugin); + break; + } + } +} + +std::shared_ptr OutputWorker::GetPlugin(const char* const pluginName) { + Locker locker(PluginsLock); + + for (auto& existingPlugin : Plugins) { + const char* const existingPluginName = existingPlugin->GetUniquePluginName(); + + // If the names match exactly, + if (0 == strcmp(pluginName, existingPluginName)) { + return existingPlugin; + } + } + + return nullptr; +} + +void OutputWorker::DisableAllPlugins() { + Locker locker(PluginsLock); + + DefaultPluginsDisabled = true; + Plugins.clear(); +} + +Lock* OutputWorker::GetChannelsLock() { + return &ChannelsLock; +} + +void OutputWorker::AddRepeatedMessageSubsystemException(const char* subsystemName) { + return RepeatedMessageManagerInstance.AddRepeatedMessageSubsystemException(subsystemName); +} + +void OutputWorker::RemoveRepeatedMessageSubsystemException(const char* subsystemName) { + return RepeatedMessageManagerInstance.RemoveRepeatedMessageSubsytemException(subsystemName); +} + +void OutputWorker::SetOutputPluginChannels( + const char* outputPluginName, + const std::vector& channelNames) { + Locker locker(PluginsLock); + + if (channelNames.empty()) + OutputPluginChannelFiltering.erase(outputPluginName); + else { + OutputPluginChannelFiltering[outputPluginName].clear(); + OutputPluginChannelFiltering[outputPluginName].insert(channelNames.begin(), channelNames.end()); + } +} + +void OutputWorker::SetChannelOutputPlugins( + const char* channelName, + const std::vector& outputPluginNames) { + Locker locker(PluginsLock); + + if (outputPluginNames.empty()) + OutputPluginChannelFiltering.erase(channelName); + else { + ChannelOutputPluginFiltering[channelName].clear(); + ChannelOutputPluginFiltering[channelName].insert( + outputPluginNames.begin(), outputPluginNames.end()); + } +} + +void OutputWorker::SetChannelSingleOutput(const char* channelName, const char* outputPluginName) { + // We assume a recursive mutex, becasue the called functions also lock this mutex. If the + // mutex wasn't recursive then we would immediately find out because this function would + // deadlock itself. + Locker locker(PluginsLock); + + SetChannelOutputPlugins(channelName, {outputPluginName}); + SetOutputPluginChannels(outputPluginName, {channelName}); +} + +void OutputWorker::Start() { + // Hold start-stop lock to prevent Start() and Stop() from being called at the same time. + Locker startStopLocker(StartStopLock); + + // If already started, +#if defined(_WIN32) + if (LoggingThread.IsValid()) +#else + if (LoggingThread.joinable()) +#endif // defined(_WIN32) + { + return; // Nothing to do! + } + + // RestoreAllChannelLogLevelsNoLock is used to address + // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm Section 6.7 + // RestoreAllChannelLogLevelsNoLock otherwise invokes OutputWorker::GetInstance() whose + // constructor hasn't finished yet + Configurator::GetInstance()->RestoreAllChannelLogLevelsNoLock(); + +#if defined(_WIN32) + if (!WorkerTerminator.Initialize()) { + // Unable to create worker terminator event? + LOGGING_DEBUG_BREAK(); + return; + } + + LoggingThread = ::CreateThread( + nullptr, // No thread security attributes + 0, // Default stack size + &OutputWorker::WorkerThreadEntrypoint_, // Thread entrypoint + this, // This parameter + 0, // No creation flags, start immediately + nullptr); // Do not request thread id + + if (!LoggingThread.IsValid()) { + // Unable to create worker thread? + LOGGING_DEBUG_BREAK(); + return; + } +#else + { + std::unique_lock lock(WorkerCvMutex); + + Terminated = false; + LoggingThread = std::thread(&OutputWorker::WorkerThreadEntrypoint_, this); + + // make sure our thread has started + WorkerCv.wait(lock); + } +#endif // defined(_WIN32) && !defined(OVR_LOGGING_USE_CPP11) + + // Note this may queue more than one OutputWorkerAtExit() call. + // This function needs to be robust to multiple calls in a row + std::atexit(&OutputWorkerAtExit); +} + +void OutputWorker::Stop() { + // This function needs to be robust to multiple calls in a row + + // Hold start-stop lock to prevent Start() and Stop() from being called at the same time. + Locker startStopLocker(StartStopLock); + +#if defined(_WIN32) + if (LoggingThread.IsValid()) { + // Flag termination + WorkerTerminator.Terminate(); + + // Wait for thread to end + ::WaitForSingleObject( + LoggingThread.Get(), // Thread handle + INFINITE); // Wait forever for thread to terminate + + LoggingThread.Clear(); + } +#else + if (LoggingThread.joinable()) { + // Flag termination + Terminated = true; + { + std::unique_lock lock(WorkerCvMutex); + WorkerCv.notify_one(); + } + + LoggingThread.join(); + } +#endif // defined(_WIN32) + + // Hold scoped work queue lock: + { + // This ensures that logs are not printed out of order on Stop(), and that Flush() + // can use the flag to check if a flush has already occurred. + Locker workQueueLock(WorkQueueLock); + + // Finish the last set of queued messages to avoid losing any before Stop() returns. + ProcessQueuedMessages(); + } +} + +static int GetTimestamp(char* buffer, int bufferBytes, const LogTime& logTime) { +#if defined(_WIN32) + // GetDateFormat and GetTimeFormat returns the number of characters written to the + // buffer if successful, including the trailing '\0'; and return 0 on failure. + char dateBuffer[16]; + int dateBufferLength; + int writtenChars = + ::GetDateFormatA(LOCALE_USER_DEFAULT, 0, &logTime, "dd/MM ", dateBuffer, sizeof(dateBuffer)); + + if (writtenChars <= 0) { + // Failure + buffer[0] = '\0'; + return 0; + } + dateBufferLength = (writtenChars - 1); + + char timeBuffer[32]; + int timeBufferLength; + writtenChars = ::GetTimeFormatA( // Intentionally using 'A' version. + LOCALE_USER_DEFAULT, // User locale + 0, // Default flags + &logTime, // Time + "HH:mm:ss", + timeBuffer, // Output buffer + sizeof(timeBuffer)); // Size of buffer in tchars + + if (writtenChars <= 0) { + // Failure + buffer[0] = '\0'; + return 0; + } + timeBufferLength = (writtenChars - 1); + + // Append milliseconds + const char msBuffer[5] = {(char)('.'), + (char)(((logTime.wMilliseconds / 100) % 10) + '0'), + (char)(((logTime.wMilliseconds / 10) % 10) + '0'), + (char)((logTime.wMilliseconds % 10) + '0'), + (char)('\0')}; + + const int writeSum = (dateBufferLength + timeBufferLength + sizeof(msBuffer)); + + if (bufferBytes < writeSum) { + buffer[0] = '\0'; + return 0; + } + +#if defined(_MSC_VER) +#pragma warning(push) // We are guaranteed that strcpy is safe. +#pragma warning(disable : 4996) //'strcpy': This function or variable may be unsafe. +#endif // defined(_MSC_VER) + strcpy(buffer, dateBuffer); + strcpy(buffer + dateBufferLength, timeBuffer); + strcpy(buffer + dateBufferLength + timeBufferLength, msBuffer); +#if defined(_MSC_VER) +#pragma warning(pop) +#endif // defined(_MSC_VER) + + return ( + writeSum - + 1); // -1 because we return the strlen of buffer, and don't include the trailing '\0'. +#else + using namespace std::chrono; + size_t ms = duration_cast(logTime.time_since_epoch()).count() % 1000; + time_t seconds = system_clock::to_time_t(logTime); + + const char msBuffer[5] = {(char)('.'), + (char)(((ms / 100) % 10) + '0'), + (char)(((ms / 10) % 10) + '0'), + (char)((ms % 10) + '0'), + (char)('\0')}; + +#if defined(_MSC_VER) +#pragma warning(push) // We are guaranteed that strcpy is safe. +#pragma warning(disable : 4996) //'strcpy': This function or variable may be unsafe. +#endif // defined(_MSC_VER) + size_t dateTimeBufferLength = + std::strftime(buffer, bufferBytes, "%d/%m %H:%M:%S", std::localtime(&seconds)); + strcpy(buffer + dateTimeBufferLength, msBuffer); +#if defined(_MSC_VER) +#pragma warning(pop) +#endif // defined(_MSC_VER) + + return (int)(dateTimeBufferLength + sizeof(msBuffer) - 1); +#endif // defined(_WIN32) +} + +// Returns number of bytes written to buffer +// Precondition: Buffer is large enough to hold everything, +// so don't bother complaining there isn't enough length checking. +static int GetTimestamp(char* buffer, int bufferBytes) { + LogTime time = GetCurrentLogTime(); + return GetTimestamp(buffer, bufferBytes, time); +} + +void OutputWorker::Flush() { +#if defined(_WIN32) + if (!LoggingThread.IsValid()) +#else + if (!LoggingThread.joinable()) +#endif // defined(_WIN32) + { + LOGGING_DEBUG_BREAK(); // Must be called between Start() and Stop() + return; + } + +#if defined(_WIN32) + AutoHandle flushEvent; +#else + std::unique_lock lock(WorkerCvMutex); +#endif // !defined(_WIN32) + + // Scoped work queue lock: + { + Locker workQueueLock(WorkQueueLock); + + LogStringBuffer buffer("Logging", ovrlog::Level::Info); + LogTime time = GetCurrentLogTime(); + QueuedLogMessage* queuedBuffer = new QueuedLogMessage("Logging", ovrlog::Level::Info, "", time); +#if defined(_WIN32) + // Generate a flush event + flushEvent = ::CreateEventW(nullptr, FALSE, FALSE, nullptr); + queuedBuffer->FlushEvent = flushEvent.Get(); +#else + queuedBuffer->FlushEvent = true; +#endif // defined(_WIN32) + + // Add queued buffer to the end of the work queue + WorkQueueAdd(queuedBuffer); + +#if defined(_WIN32) + // Wake the worker thread + ::SetEvent(WorkerWakeEvent.Get()); +#else + WorkerCv.notify_one(); +#endif // defined(_WIN32) + } + + // Wait until the event signals. + // Since we are guaranteed to never lose log messages, as late as Stop() being called, + // this cannot cause a hang. +#if defined(_WIN32) + ::WaitForSingleObject(flushEvent.Get(), INFINITE); +#else + WorkerCv.wait(lock); +#endif // !defined(_WIN32) +} + +static void WriteAdvanceStrCpy(char*& buffer, size_t& bufferBytes, const char* str) { + // Get length of string to copy into buffer + size_t slen = strlen(str); + + // If the resulting buffer cannot accommodate the string and a null terminator, + if (bufferBytes < slen + 1) { + // Do nothing + return; + } + + // Copy string to buffer + memcpy(buffer, str, slen); + + // Advance buffer by number of bytes copied + buffer += slen; + bufferBytes -= slen; +} + +void OutputWorker::AppendHeader( + char* buffer, + size_t bufferBytes, + Level level, + const char* subsystemName) { + // Writes [SubSystem] to the provided buffer. + + // Based on message log level, + const char* initial = ""; + switch (level) { + case Level::Disabled: + initial = " {DISABLED}["; + break; // This typically should not occur, but we have here for consistency. + case Level::Trace: + initial = " {TRACE} ["; + break; + case Level::Debug: + initial = " {DEBUG} ["; + break; + case Level::Info: + initial = " {INFO} ["; + break; + case Level::Warning: + initial = " {WARNING} ["; + break; + case Level::Error: + initial = " {!ERROR!} ["; + break; + default: + initial = " {???} ["; + break; + } + static_assert(Level::Count == static_cast(6), "Needs updating"); + + WriteAdvanceStrCpy(buffer, bufferBytes, initial); + WriteAdvanceStrCpy(buffer, bufferBytes, subsystemName); + WriteAdvanceStrCpy(buffer, bufferBytes, "] "); + buffer[0] = '\0'; +} + +OVR_THREAD_FUNCTION_TYPE OutputWorker::WorkerThreadEntrypoint_(void* vworker) { + // Invoke thread entry-point + OutputWorker* worker = reinterpret_cast(vworker); + if (worker) { + worker->WorkerThreadEntrypoint(); + } + return 0; +} + +void OutputWorker::ProcessQueuedMessages() { + // Potentially trigger aggregated repeating messages. + RepeatedMessageManagerInstance.Poll(this); + + static const int TempBufferBytes = 1024; // 1 KiB + char HeaderBuffer[TempBufferBytes]; + + QueuedLogMessage* message = nullptr; + + // Pull messages off the queue + int lostCount = 0; + { + Locker locker(WorkQueueLock); + message = WorkQueueHead; + WorkQueueHead = WorkQueueTail = nullptr; + lostCount = WorkQueueOverrun; + WorkQueueOverrun = 0; + WorkQueueSize = 0; + } + + if (message == nullptr) { + // No data to process + return; + } + + // Log output format: + // TIMESTAMP [SubSystem] Message + + // If some messages were lost, + if (lostCount > 0) { + char str[255]; + snprintf( + str, + sizeof(str), + "Lost %i log messages due to queue overrun; try to reduce the amount of logging", + lostCount); + + // Insert at the front of the list + LogTime t = GetCurrentLogTime(); + QueuedLogMessage* queuedMsg = new QueuedLogMessage("Logging", Level::Error, str, t); + queuedMsg->Next = message; + message = queuedMsg; + } + + { + Locker locker(PluginsLock); + + // For each log message, + for (QueuedLogMessage* next; message; message = next) { + // If the message is a flush event, +#if defined(_WIN32) + if (message->FlushEvent != nullptr) +#else + if (message->FlushEvent) +#endif // defined(_WIN32) + { + // Signal it to wake up the waiting Flush() call. +#if defined(_WIN32) + ::SetEvent(message->FlushEvent); +#else + // we are already locked here... + WorkerCv.notify_one(); +#endif // defined(_WIN32) + } else { + std::size_t timestampLength = + GetTimestamp(HeaderBuffer, sizeof(HeaderBuffer), message->Time); + const char* subsystemName = message->SubsystemName.Get(); // a.k.a. channel name. + const char* messageBuffer = message->Buffer.c_str(); + const Level level = message->MessageLogLevel; + + // Construct header on top of timestamp buffer + AppendHeader( + HeaderBuffer + timestampLength, + sizeof(HeaderBuffer) - timestampLength, + level, + subsystemName); + + // Write the output to potentially each output plugin. There's some logic below to check + // for channel writability to output plugins. The large majority of the time the cost of + // the checks will amount to two hash-table lookups of keys that aren't present. For the + // rare cases that they are present, a second lookup into the hash table for a short + // string occurs. + auto itC = ChannelOutputPluginFiltering.find(subsystemName); + + for (auto& pluginIt : Plugins) { + const char* pluginName = pluginIt->GetUniquePluginName(); + bool channelWritesToPlugin = + (itC == ChannelOutputPluginFiltering.end()); // Typically true. + + if (!channelWritesToPlugin) { // 99% of the time we won't need to execute this block. + // In this case the channel filtering map has a customized set of output + // plugins to write to, which are a subset of the entire set. + channelWritesToPlugin = (itC->second.find(pluginName) != itC->second.end()); + } + + // If the channel is set to write to the output plugin, then let's check to see + // if the output plugin enables writes from the channel. + if (channelWritesToPlugin) { // Typically true. + auto itO = OutputPluginChannelFiltering.find(pluginName); + bool pluginAllowsChannel = + (itO == OutputPluginChannelFiltering.end()); // Typically true. + + if (!pluginAllowsChannel) { // 99% of the time we won't need to execute this block. + // In this case the output filtering map has a customized set of channels + // it allows writing from. + pluginAllowsChannel = (itO->second.find(subsystemName) != itO->second.end()); + } + + if (pluginAllowsChannel) + pluginIt->Write(level, subsystemName, HeaderBuffer, messageBuffer); + } + } + } + + next = message->Next; + delete message; + } + } +} + +void OutputWorker::FlushDbgViewLogImmediately( + const char* subsystemName, + Level messageLogLevel, + const char* stream) { + static const int TempBufferBytes = 1024; // 1 KiB + char HeaderBuffer[TempBufferBytes]; + + // Get timestamp string + int timestampLength = GetTimestamp(HeaderBuffer, TempBufferBytes); + if (timestampLength <= 0) { + LOGGING_DEBUG_BREAK(); + return; // Maybe bug in timestamp code? + } + + // Construct log header on top of timestamp buffer + AppendHeader( + HeaderBuffer + timestampLength, + sizeof(HeaderBuffer) - timestampLength, + messageLogLevel, + subsystemName); + + // Build up a single string to send to OutputDebugStringA so it + // all appears on the same line in DbgView. + std::stringstream ss; + ss << HeaderBuffer << stream << "\n"; + +#if defined(_WIN32) + ::OutputDebugStringA(ss.str().c_str()); +#else + fputs(ss.str().c_str(), stderr); +#endif +} + +static void SetThreadName(const char* name) { +#if defined(_WIN32) + DWORD threadId = ::GetCurrentThreadId(); + +// http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx +#pragma pack(push, 8) + struct THREADNAME_INFO { + DWORD dwType; // Must be 0x1000 + LPCSTR szName; // Pointer to name (in user address space) + DWORD dwThreadID; // Thread ID (-1 for caller thread) + DWORD dwFlags; // Reserved for future use; must be zero + }; + union TNIUnion { + THREADNAME_INFO tni; + ULONG_PTR upArray[4]; + }; +#pragma pack(pop) + + TNIUnion tniUnion = {{0x1000, name, threadId, 0}}; + + __try { + RaiseException(0x406D1388, 0, ARRAYSIZE(tniUnion.upArray), tniUnion.upArray); + } __except ( + GetExceptionCode() == 0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER) { + return; + } +#elif defined(__APPLE__) + pthread_setname_np(name); +#else + pthread_setname_np(pthread_self(), name); +#endif +} + +void OutputWorker::WorkerThreadEntrypoint() { +#if !defined(_WIN32) + std::unique_lock lock(WorkerCvMutex); + WorkerCv.notify_one(); +#endif // !defined(_WIN32) + SetThreadName("LoggingOutputWorker"); + +#if defined(_WIN32) + // Lower the priority for logging. + ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_LOWEST); +#else + // Other desktop platforms (e.g. Linux, OSX) don't let you set thread priorities. +#endif // defined(_WIN32) + +#if defined(_WIN32) + while (!WorkerTerminator.IsTerminated()) { + if (WorkerTerminator.WaitOn(WorkerWakeEvent.Get())) { + ProcessQueuedMessages(); + } + } +#else + while (!Terminated.load()) { + WorkerCv.wait(lock); + ProcessQueuedMessages(); + } +#endif // defined(_WIN32) +} + +void OutputWorker::Write( + const char* subsystemName, + Level messageLogLevel, + const char* stream, + bool relogged, + WriteOption option) { + bool dropped = false; // Flag indicates if the message was dropped due to queue overrun + bool needToWakeWorkerThread = false; // Flag indicates if we need to wake the worker thread + + // Add work to queue. + { + Locker locker(WorkQueueLock); + + // Check to see if this message looks like it's repeat message which we want to aggregate + // in order to avoid log spam of the same similar message repeatedly. + if (RepeatedMessageManagerInstance.HandleMessage(subsystemName, messageLogLevel, stream) == + RepeatedMessageManager::HandleResult::Aggregated) { + return; + } + + if (option != WriteOption::DangerouslyIgnoreQueueLimit && WorkQueueSize >= WorkQueueLimit) { + // Record drop + WorkQueueOverrun++; + dropped = true; + } else { + // Add queued buffer to the end of the work queue + LogTime time = GetCurrentLogTime(); + WorkQueueAdd(new QueuedLogMessage(subsystemName, messageLogLevel, stream, time)); + +#if defined(_WIN32) + // Only need to wake the worker thread on the first message + // The SetEvent() call takes 6 microseconds or so + if (WorkQueueSize <= 1) { + needToWakeWorkerThread = true; + } +#else + // WorkerCv.notify_one() will only wake the worker if it is waiting + needToWakeWorkerThread = true; +#endif // defined(_WIN32) + } + } + + if (!dropped && needToWakeWorkerThread) { + // Wake the worker thread +#if defined(_WIN32) + ::SetEvent(WorkerWakeEvent.Get()); +#else + WorkerCv.notify_one(); +#endif + } + + // If this is the first time logging this message, + if (!relogged) { + // If we are in a debugger, + if (IsInDebugger) { + FlushDbgViewLogImmediately(subsystemName, messageLogLevel, stream); + } + } +} + +//----------------------------------------------------------------------------- +// QueuedLogMessage + +OutputWorker::QueuedLogMessage::QueuedLogMessage( + const char* subsystemName, + Level messageLogLevel, + const char* stream, + const LogTime& time) + : SubsystemName(subsystemName), + MessageLogLevel(messageLogLevel), + Buffer(stream), + Time(time), + Next(nullptr), +#if defined(_WIN32) + FlushEvent(nullptr) +#else + FlushEvent(false) +#endif // defined(_WIN32) +{ +} + +void Channel::registerNode() { + Node.SubsystemName = SubsystemName.Get(); + Node.Level = &MinimumOutputLevel; + Node.UserOverrodeMinimumOutputLevel = &UserOverrodeMinimumOutputLevel; + + ConfiguratorRegister(&Node); +} + +Channel::Channel(const char* nameString) + : SubsystemName(nameString), + MinimumOutputLevel((Log_Level_t)DefaultMinimumOutputLevel), + UserOverrodeMinimumOutputLevel(false) { + registerNode(); +} + +Channel::Channel(const Channel& other) + : SubsystemName(other.SubsystemName), + MinimumOutputLevel(other.MinimumOutputLevel), + Prefix(other.GetPrefix()), + UserOverrodeMinimumOutputLevel(other.UserOverrodeMinimumOutputLevel) { + registerNode(); +} + +Channel::~Channel() { + // ...We can get modified from other threads here. + ConfiguratorUnregister(&Node); +} + +std::string Channel::GetPrefix() const { + Locker locker(PrefixLock); + return Prefix; +} + +void Channel::SetPrefix(const std::string& prefix) { + Locker locker(PrefixLock); + Prefix = prefix; +} + +void Channel::SetMinimumOutputLevel(Level newLevel) { + SetMinimumOutputLevelNoSave(newLevel); + + ConfiguratorOnChannelLevelChange(SubsystemName.Get(), MinimumOutputLevel); +} + +void Channel::SetMinimumOutputLevelNoSave(Level newLevel) { + MinimumOutputLevel = (Log_Level_t)newLevel; + UserOverrodeMinimumOutputLevel = true; +} + +Level Channel::GetMinimumOutputLevel() const { + return (Level)MinimumOutputLevel; +} + +int Channel::GetPrintfLength(const char* format, ...) { + va_list argList; + va_start(argList, format); + int size = GetPrintfLengthV(format, argList); + va_end(argList); + return size; +} + +//----------------------------------------------------------------------------- +// Conversion functions + +template <> +void LogStringize(LogStringBuffer& buffer, const wchar_t* const& first) { +#ifdef _WIN32 + + // Use Windows' optimized multi-byte UTF8 conversion function for performance. + // Returns the number of bytes used by the conversion, including the null terminator + // since -1 is passed in for the input string length. + // Returns 0 on failure. + int bytesUsed = ::WideCharToMultiByte( + CP_ACP, // Default code page + 0, // Default flags + first, // String to convert + -1, // Unknown string length + nullptr, // Null while checking length of buffer + 0, // 0 to request the buffer size required + nullptr, // Default default character + nullptr); // Ignore whether or not default character was used + // Setting the last two arguments to null is documented to execute faster via MSDN. + + // If the function succeeded, + if (bytesUsed > 0) { + // Avoid allocating memory if the string is fairly small. + char stackBuffer[128]; + char* dynamicBuffer = nullptr; + char* convertedString = stackBuffer; + if (bytesUsed > (int)sizeof(stackBuffer)) { + // (defensive coding) Add 8 bytes of slop in case of API bugs. + dynamicBuffer = new char[bytesUsed + 8]; + convertedString = dynamicBuffer; + } + + int charsWritten = ::WideCharToMultiByte( + CP_ACP, // Default code page + 0, // Default flags + first, // String to convert + -1, // Unknown string length + convertedString, // Output buffer + bytesUsed, // Request the same number of bytes + nullptr, // Default default character + nullptr); // Ignore whether or not default character was used + // Setting the last two arguments to null is documented to execute faster via MSDN. + + if (charsWritten > 0) { + // Append the converted string. + buffer.Stream << convertedString; + } + + delete[] dynamicBuffer; + } + +#else + + std::wstring_convert> converter; + buffer.Stream << converter.to_bytes(first); + +#endif // _WIN32 +} + +//----------------------------------------------------------------------------- +// ConfiguratorPlugin + +ConfiguratorPlugin::ConfiguratorPlugin() {} + +ConfiguratorPlugin::~ConfiguratorPlugin() {} + +//----------------------------------------------------------------------------- +// Log Configurator + +Configurator::Configurator() : GlobalMinimumLogLevel((Log_Level_t)Level::Debug), Plugin(nullptr) {} + +Configurator* Configurator::GetInstance() { + static Configurator configurator; + return &configurator; +} + +Configurator::~Configurator() {} + +void Configurator::SetGlobalMinimumLogLevel(Level level) { + Locker locker(OutputWorker::GetInstance()->GetChannelsLock()); + + GlobalMinimumLogLevel = (Log_Level_t)level; + + for (ChannelNode* channelNode = ChannelNodeHead; channelNode; channelNode = channelNode->Next) { + *(channelNode->Level) = (ovrlog::Log_Level_t)level; + } +} + +// Should be locked already when calling this function! +void Configurator::RestoreChannelLogLevel(const char* channelName) { + Level level = (Level)GlobalMinimumLogLevel; + + // Look up the log level for this channel if we can + if (Plugin) { + Plugin->RestoreChannelLevel(channelName, level); + } + + const std::string stdChannelName(channelName); + + SetChannelLevelNoLock(stdChannelName, level, false); +} + +void Configurator::RestoreChannelLogLevel(ChannelNode* channelNode) { + Level level = (Level)GlobalMinimumLogLevel; + + // Look up the log level for this channel if we can + if (Plugin) { + Plugin->RestoreChannelLevel(channelNode->SubsystemName, level); + } + + // Don't undo user calls to SetMinimumOutputLevelNoSave() + if (*(channelNode->UserOverrodeMinimumOutputLevel) == false) { + *(channelNode->Level) = (Log_Level_t)level; + } +} + +void Configurator::RestoreAllChannelLogLevels() { + Locker locker(OutputWorker::GetInstance()->GetChannelsLock()); + RestoreAllChannelLogLevelsNoLock(); +} + +void Configurator::RestoreAllChannelLogLevelsNoLock() { + for (ChannelNode* channelNode = ChannelNodeHead; channelNode; channelNode = channelNode->Next) { + RestoreChannelLogLevel(channelNode->SubsystemName); + } +} + +void Configurator::SetPlugin(std::shared_ptr plugin) { + Locker locker(OutputWorker::GetInstance()->GetChannelsLock()); + + Plugin = plugin; + + for (ChannelNode* channelNode = ChannelNodeHead; channelNode; channelNode = channelNode->Next) { + RestoreChannelLogLevel(channelNode->SubsystemName); + } +} +void Configurator::GetChannels(std::vector>& channels) { + channels.clear(); + + Locker locker(OutputWorker::GetInstance()->GetChannelsLock()); + + for (ChannelNode* channelNode = ChannelNodeHead; channelNode; channelNode = channelNode->Next) { + channels.push_back( + std::make_pair(std::string(channelNode->SubsystemName), (Level) * (channelNode->Level))); + } +} +void Configurator::SetChannelLevel(const std::string& channelName, Level level) { + Locker locker(OutputWorker::GetInstance()->GetChannelsLock()); + SetChannelLevelNoLock(channelName, level, true); +} + +// Should be locked already when calling this function! +void Configurator::SetChannelLevelNoLock( + const std::string& channelName, + Level level, + bool overrideUser) { + for (ChannelNode* channelNode = ChannelNodeHead; channelNode; channelNode = channelNode->Next) { + if (std::string(channelNode->SubsystemName) == channelName) { + if (*(channelNode->UserOverrodeMinimumOutputLevel) == false || overrideUser) { + *(channelNode->Level) = (Log_Level_t)level; + + // Purposely no break, channels may have duplicate names + } + } + } +} + +void Configurator::SetOutputPluginChannels( + const char* outputPluginName, + const std::vector& channelNames) { + OutputWorker::GetInstance()->SetOutputPluginChannels(outputPluginName, channelNames); +} + +void Configurator::SetChannelOutputPlugins( + const char* channelName, + const std::vector& outputPluginNames) { + OutputWorker::GetInstance()->SetChannelOutputPlugins(channelName, outputPluginNames); +} + +void Configurator::SetChannelSingleOutput(const char* channelName, const char* outputPluginName) { + OutputWorker::GetInstance()->SetChannelSingleOutput(channelName, outputPluginName); +} + +void Configurator::OnChannelLevelChange(const char* channelName, Log_Level_t minimumOutputLevel) { + Locker locker(OutputWorker::GetInstance()->GetChannelsLock()); + + if (Plugin) { + // Save channel level + Plugin->SaveChannelLevel(channelName, (Level)minimumOutputLevel); + } +} + +//----------------------------------------------------------------------------- +// ErrorSilencer +#if defined(_MSC_VER) +#if (_MSC_VER < 1300) +__declspec(thread) int ThreadErrorSilencedOptions = 0; +#else +#pragma data_seg(".tls$") +__declspec(thread) int ThreadErrorSilencedOptions = 0; +#pragma data_seg(".rwdata") +#endif +#else +thread_local int ThreadErrorSilencedOptions = 0; +#endif + +int ErrorSilencer::GetSilenceOptions() { + return ThreadErrorSilencedOptions; +} + +ErrorSilencer::ErrorSilencer(int options) : Options(options) { + Silence(); +} + +ErrorSilencer::~ErrorSilencer() { + Unsilence(); +} + +void ErrorSilencer::Silence() { + // We do not currently support recursive silencers + assert(!GetSilenceOptions()); + ThreadErrorSilencedOptions = Options; +} + +void ErrorSilencer::Unsilence() { + // We do not currently support recursive silencers + assert(GetSilenceOptions()); + ThreadErrorSilencedOptions = 0; +} + +} // namespace ovrlog + +#ifdef OVR_STRINGIZE +#error "This code must remain independent of LibOVR" +#endif diff --git a/ovr_sdk_win_23.0.0/Logging/src/Logging_OutputPlugins.cpp b/ovr_sdk_win_23.0.0/Logging/src/Logging_OutputPlugins.cpp new file mode 100644 index 0000000..3b6ccc2 --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/src/Logging_OutputPlugins.cpp @@ -0,0 +1,289 @@ +/************************************************************************************ + +Filename : Logging_OutputPlugins.cpp +Content : Logging output plugins +Created : Oct 26, 2015 +Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Logging/Logging_OutputPlugins.h" +#include "Logging/Logging_Tools.h" + +#include +#include + +namespace ovrlog { + +//----------------------------------------------------------------------------- +// Console + +OutputConsole::OutputConsole(bool useStdio) : UseStdio(useStdio) {} + +OutputConsole::~OutputConsole() {} + +void OutputConsole::SetStdioUsage(bool enable) { + UseStdio = enable; +} + +const char* OutputConsole::GetUniquePluginName() { + return "DefaultOutputConsole"; +} + +void OutputConsole::Write( + Level level, + const char* /*subsystem*/, + const char* header, + const char* utf8msg) { +#if defined(_WIN32) + HANDLE hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE); + + // Save current console attributes + CONSOLE_SCREEN_BUFFER_INFO bufInfo{}; + BOOL oldAttrValid = ::GetConsoleScreenBufferInfo(hConsole, &bufInfo); + WORD attr = 0; + + switch (level) { + case Level::Disabled: // Shouldn't occur, but we handle for consistency. + attr |= FOREGROUND_BLUE; + break; + case Level::Trace: + attr |= FOREGROUND_BLUE | FOREGROUND_RED; + break; + case Level::Debug: + attr |= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + break; + case Level::Info: + attr |= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; + break; + case Level::Warning: + attr |= FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; + break; + case Level::Error: + attr |= FOREGROUND_RED | FOREGROUND_INTENSITY; + break; + default: + break; + } + static_assert(Level::Count == static_cast(6), "Needs updating"); + + ::SetConsoleTextAttribute(hConsole, attr & ~FOREGROUND_INTENSITY); + + if (UseStdio) + std::cout << header; + else { + DWORD dwCount; + DWORD headerLength = (DWORD)strlen(header); + + WriteConsoleA(hConsole, header, headerLength, &dwCount, nullptr); + } + + if ((attr & FOREGROUND_INTENSITY) != 0) { + ::SetConsoleTextAttribute(hConsole, attr); + } + + if (UseStdio) + std::cout << utf8msg << std::endl; + else { + DWORD dwCount; + DWORD msgLength = (DWORD)strlen(utf8msg); + + WriteConsoleA(hConsole, utf8msg, msgLength, &dwCount, nullptr); + WriteConsoleA(hConsole, "\n", 1, &dwCount, nullptr); + } + + // Restore original attributes, if saved + if (TRUE == oldAttrValid) { + ::SetConsoleTextAttribute(hConsole, bufInfo.wAttributes); + } +#else + + FILE* output = stdout; + + switch (level) { + case Level::Trace: + break; + case Level::Debug: + break; + case Level::Info: + break; + case Level::Warning: + output = stderr; + fprintf(output, "\e[38;5;255m\e[48;5;208m"); + break; + case Level::Error: + output = stderr; + fprintf(output, "\e[38;5;255m\e[48;5;196m"); + break; + default: + break; + } + + fprintf(output, "%s", header); + fprintf(output, "\e[0m "); + + fprintf(output, "%s\n", utf8msg); +#endif +} + +//----------------------------------------------------------------------------- +// System Application Event Log + +#ifndef OVR_SYSLOG_NAME +#define OVR_SYSLOG_NAME L"OculusVR" +#endif // OVR_SYSLOG_NAME + +OutputEventLog::OutputEventLog() : hEventSource(nullptr), MinReportEventLevel(Level::Error) { +#if defined(_WIN32) + hEventSource = ::RegisterEventSourceW( + nullptr, // No server name + OVR_SYSLOG_NAME); // Syslog event source name +#else + // To do. +#endif + + if (!hEventSource) { + // Unable to register event source + LOGGING_DEBUG_BREAK(); + } +} + +OutputEventLog::~OutputEventLog() {} + +const char* OutputEventLog::GetUniquePluginName() { + return "DefaultOutputEventLog"; +} + +void OutputEventLog::Write( + Level level, + const char* subsystem, + const char* header, + const char* utf8msg) { + (void)subsystem; // unused + + if (level < MinReportEventLevel) { + return; + } + + if (!hEventSource) { + return; + } + +#if defined(_WIN32) + WORD mType = 0; + + switch (level) { + default: + case Level::Disabled: + case Level::Trace: + case Level::Debug: + case Level::Info: + mType = EVENTLOG_INFORMATION_TYPE; + return; // Do not log at this level. + + case Level::Warning: + mType = EVENTLOG_WARNING_TYPE; + break; // Log at this level. + + case Level::Error: + mType = EVENTLOG_ERROR_TYPE; + break; // Log at this level. + } + static_assert(Level::Count == static_cast(6), "Needs updating"); + + const size_t MAX_REPORT_EVENT_A_LEN = 31839; + + std::vector cstrVtr; + cstrVtr.push_back(header); + std::vector splitStrings; + size_t longStringLen = strlen(utf8msg); + if (longStringLen >= MAX_REPORT_EVENT_A_LEN) { + std::string longStr(utf8msg); + for (size_t x = 0; x < longStringLen; x += MAX_REPORT_EVENT_A_LEN) { + size_t remaining = longStringLen - x; + std::string thisSubStr = longStr.substr( + x, (remaining > MAX_REPORT_EVENT_A_LEN) ? MAX_REPORT_EVENT_A_LEN : remaining); + splitStrings.push_back(thisSubStr); + } + + for (size_t i = 0; i < splitStrings.size(); i++) { + cstrVtr.push_back(splitStrings[i].c_str()); + } + } else { + cstrVtr.push_back(utf8msg); + } + + if (!::ReportEventA( + hEventSource, // Event source + mType, // Event log level + 0, // Default category + 0, // Default event id + nullptr, // No security identifier + (WORD)cstrVtr.size(), // Number of strings + 0, // No bytes of event-specific binary data attached + &cstrVtr[0], // String array + nullptr)) // No binary data attached + { + // Unable to write event log + LOGGING_DEBUG_BREAK(); + } +#else + (void)header; + (void)utf8msg; + // To do. +#endif +} + +//----------------------------------------------------------------------------- +// DbgView + +OutputDbgView::OutputDbgView() {} + +OutputDbgView::~OutputDbgView() {} + +const char* OutputDbgView::GetUniquePluginName() { + return "DefaultOutputDbgView"; +} + +void OutputDbgView::Write( + Level level, + const char* subsystem, + const char* header, + const char* utf8msg) { + (void)subsystem; // unused + (void)level; // unused + + // Build up a single string to send to OutputDebugStringA so it + // all appears on the same line in DbgView. + std::stringstream ss; + ss << header << utf8msg << "\n"; + +#if defined(_WIN32) + ::OutputDebugStringA(ss.str().c_str()); +#else + fputs(ss.str().c_str(), stderr); +#endif +} + +} // namespace ovrlog + +#ifdef OVR_STRINGIZE +#error "This code must remain independent of LibOVR" +#endif diff --git a/ovr_sdk_win_23.0.0/Logging/src/Logging_Tools.cpp b/ovr_sdk_win_23.0.0/Logging/src/Logging_Tools.cpp new file mode 100644 index 0000000..ad3d03f --- /dev/null +++ b/ovr_sdk_win_23.0.0/Logging/src/Logging_Tools.cpp @@ -0,0 +1,255 @@ +/************************************************************************************ + +Filename : Logging_Tools.cpp +Content : Tools for Logging +Created : Oct 26, 2015 +Authors : Chris Taylor + +Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved. + +Licensed under the Oculus Master SDK License Version 1.0 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +https://developer.oculus.com/licenses/oculusmastersdk-1.0 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifdef _MSC_VER +#pragma warning(disable : 4530) // C++ exception handler used, but unwind semantics are not enabled +#endif + +#include "Logging/Logging_Tools.h" + +#include +#include + +#if defined(__APPLE__) +#include +#include +#include +#include +#endif + +namespace ovrlog { + +#if defined(_WIN32) +//----------------------------------------------------------------------------- +// Terminator + +Terminator::Terminator() : Terminated(false), TerminateEvent() {} + +Terminator::~Terminator() {} + +bool Terminator::Initialize() { + Terminated = false; + + if (TerminateEvent.IsValid()) { + ::ResetEvent(TerminateEvent.Get()); + return true; + } + + TerminateEvent = ::CreateEventW(nullptr, TRUE, FALSE, nullptr); + + return TerminateEvent.IsValid(); +} + +void Terminator::Terminate() { + Terminated = true; + + if (TerminateEvent.IsValid()) { + ::SetEvent(TerminateEvent.Get()); + } +} + +// Returns true if the event signaled and false on termination. +bool Terminator::WaitOn(OvrLogHandle hEvent, uint32_t timeoutMsec) { + if (Terminated || !TerminateEvent.IsValid()) + return false; + + HANDLE events[2] = {hEvent, TerminateEvent.Get()}; + + DWORD result = ::WaitForMultipleObjects(2, events, FALSE, timeoutMsec); + + if (Terminated) + return false; + + if (result == WAIT_TIMEOUT) + return false; + if (result == WAIT_OBJECT_0) + return true; + + return false; +} + +// Returns true if the sleep interval exceeded or false on termination. +bool Terminator::WaitSleep(int milliseconds) { + if (Terminated || !TerminateEvent.IsValid()) + return false; + + ::WaitForSingleObject(TerminateEvent.Get(), milliseconds); // Ignore return value + + return !Terminated; +} +#endif // defined(_WIN32) + +//----------------------------------------------------------------------------- +// Lock + +Lock::Lock() + : +#if defined(_WIN32) + cs { +} +#else + m() +#endif +{ +#if defined(_WIN32) + static const DWORD kSpinCount = 1000; + ::InitializeCriticalSectionAndSpinCount(&cs, kSpinCount); +#endif +} + +Lock::~Lock() { +#if defined(_WIN32) + ::DeleteCriticalSection(&cs); +#endif +} + +bool Lock::TryEnter() { +#if defined(_WIN32) + return ::TryEnterCriticalSection(&cs) != FALSE; +#else + return m.try_lock(); +#endif +} + +void Lock::Enter() { +#if defined(_WIN32) + ::EnterCriticalSection(&cs); +#else + m.lock(); +#endif +} + +void Lock::Leave() { +#if defined(_WIN32) + ::LeaveCriticalSection(&cs); +#else + m.unlock(); +#endif +} + +//----------------------------------------------------------------------------- +// Locker + +Locker::Locker(Lock* lock) : TheLock(lock) { + if (TheLock) + TheLock->Enter(); +} + +Locker::Locker(Lock& lock) : TheLock(&lock) { + if (TheLock) + TheLock->Enter(); +} + +Locker::~Locker() { + Clear(); +} + +bool Locker::TrySet(Lock* lock) { + Clear(); + + if (!lock || !lock->TryEnter()) + return false; + + TheLock = lock; + return true; +} + +bool Locker::TrySet(Lock& lock) { + return TrySet(&lock); +} + +void Locker::Set(Lock* lock) { + Clear(); + + if (lock) { + lock->Enter(); + TheLock = lock; + } +} + +void Locker::Set(Lock& lock) { + return Set(&lock); +} + +void Locker::Clear() { + if (TheLock) { + TheLock->Leave(); + TheLock = nullptr; + } +} + +#if defined(_WIN32) +//----------------------------------------------------------------------------- +// AutoHandle + +AutoHandle::AutoHandle(OvrLogHandle handle) : TheHandle(handle) {} + +AutoHandle::~AutoHandle() { + Clear(); +} + +void AutoHandle::operator=(OvrLogHandle handle) { + Clear(); + TheHandle = handle; +} + +void AutoHandle::Clear() { + if (TheHandle) { + ::CloseHandle(TheHandle); + TheHandle = nullptr; + } +} +#endif // defined(_WIN32) + +//----------------------------------------------------------------------------- +// Tools + +bool IsDebuggerAttached() { +#if defined(_WIN32) + return ::IsDebuggerPresent() != FALSE; +#elif defined(__APPLE__) + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; + struct kinfo_proc info; + size_t size = sizeof(info); + + info.kp_proc.p_flag = 0; + sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0); + + return ((info.kp_proc.p_flag & P_TRACED) != 0); + +#elif defined(PT_TRACE_ME) && !defined(__android__) + return (ptrace(PT_TRACE_ME, 0, 1, 0) < 0); +#else + // We have some platform-specific code elsewhere. + return false; +#endif +} + +} // namespace ovrlog + +#ifdef OVR_STRINGIZE +#error "This code must remain independent of LibOVR" +#endif diff --git a/ovr_sdk_win_23.0.0/OVRRootPath.props b/ovr_sdk_win_23.0.0/OVRRootPath.props new file mode 100644 index 0000000..db17fc5 --- /dev/null +++ b/ovr_sdk_win_23.0.0/OVRRootPath.props @@ -0,0 +1,32 @@ + + + + + + $(MSBuildThisFileDirectory) + VS2013 + VS2015 + VS2017 + + + + + + $(OVRSDKROOT) + true + + + $(VSDIR) + true + + + diff --git a/ovr_sdk_win_23.0.0/Oculus World Demo.lnk b/ovr_sdk_win_23.0.0/Oculus World Demo.lnk new file mode 100644 index 0000000..13c2a77 Binary files /dev/null and b/ovr_sdk_win_23.0.0/Oculus World Demo.lnk differ diff --git a/ovr_sdk_win_23.0.0/THIRD_PARTY_NOTICES.txt b/ovr_sdk_win_23.0.0/THIRD_PARTY_NOTICES.txt new file mode 100644 index 0000000..2dee191 --- /dev/null +++ b/ovr_sdk_win_23.0.0/THIRD_PARTY_NOTICES.txt @@ -0,0 +1,5712 @@ +THE FOLLOWING SETS FORTH ATTRIBUTION NOTICES FOR THIRD PARTY SOFTWARE THAT MAY BE CONTAINED IN PORTIONS OF THE OCULUS PRODUCT. + +----- + +The following software may be included in this product: cereal. This software contains the following license and notice below: + +Copyright (c) 2014, Randolph Voorhies, Shane Grant + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of cereal nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----- + +The following software may be included in this product: curl. This software contains the following license and notice below: + +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1996 - 2011, Daniel Stenberg, . + +All rights reserved. + +Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. + +----- + +The following software may be included in this product: directx-sdk-samples. This software contains the following license and notice below: + + The MIT License (MIT) + +Copyright (c) 2015 Microsoft Corp + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies +or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----- + +The following software may be included in this product: electron. This software contains the following license and notice below: + +Copyright (c) 2014 GitHub Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----- + +The following software may be included in this product: gflags. This software contains the following license and notice below: + +Copyright (c) 2006, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----- + +The following software may be included in this product: breakpad. This software contains the following license and notice below: + +Copyright (c) 2012, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----- + +The following software may be included in this product: google-glog. This software contains the following license and notice below: + + Copyright (c) 2008, Google Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + A function gettimeofday in utilities.cc is based on + + http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/COPYING&q=GetSystemTimeAsFileTime%20license:bsd + + The license of this code is: + + Copyright (c) 2003-2008, Jouni Malinen and contributors + All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name(s) of the above-listed copyright holder(s) nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +----- + +The following software may be included in this product: gtest. This software contains the following license and notice below: + +Copyright 2005, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Author: wan@google.com (Zhanyong Wan) + +The Google C++ Testing Framework (Google Test) + +----- + +The following software may be included in this product: gtest. This software contains the following license and notice below: + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +----- + +The following software may be included in this product: gyp. This software contains the following license and notice below: + +Copyright (c) 2009 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----- + +The following software may be included in this product: libevent. This software contains the following license and notice below: + +Copyright (c) 2000-2007 Niels Provos +Copyright (c) 2007-2012 Niels Provos and Nick Mathewson + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +============================== + +Portions of Libevent are based on works by others, also made available by them under the three-clause BSD license above. The copyright notices are available in the corresponding source files; the license is as above. Here's a list: + +log.c: + Copyright (c) 2000 Dug Song + Copyright (c) 1993 The Regents of the University of California. + +strlcpy.c: + Copyright (c) 1998 Todd C. Miller + +win32select.c: + Copyright (c) 2003 Michael A. Davis + +evport.c: + Copyright (c) 2007 Sun Microsystems + +ht-internal.h: + Copyright (c) 2002 Christopher Clark + +minheap-internal.h: + Copyright (c) 2006 Maxim Yegorushkin + +----- + +The following software may be included in this product: librsync. You may request a copy of the source code by sending a request to opensource@fb.com. This software contains the following license and notice below: + +Copyright 1999-2016 Martin Pool and other contributors. + +librsync contains the BLAKE2 hash algorithm, written by Samuel Neves and released under the CC0 public domain dedication. + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +^L + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper +mail. + +You should also get your employer (if you work as a programmer) or +your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James +Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + + + + +----- + +The following software may be included in this product: Mozilla CA Cert Store. A copy of the source code may be downloaded from https://curl.haxx.se/docs/caextract.html. This software contains the following license and notice below: + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. + + +----- + + +Base64 +License: WTFPL +Repository: https://github.com/davidchambers/Base64.js +License File: Base64/LICENSE + +abab +License: ISC +Repository: https://github.com/jsdom/abab + +abbrev +License: ISC +Repository: https://github.com/isaacs/abbrev-js +License File: abbrev/LICENSE + +accepts3 +License: MIT +Repository: https://github.com/jshttp/accepts +License File: accepts/LICENSE + +acorn +License: MIT +Repository: https://github.com/ternjs/acorn +License File: acorn/LICENSE + +acorn-globals +License: MIT +Repository: https://github.com/ForbesLindesay/acorn-globals +License File: acorn-globals/LICENSE + +acorn-to-esprima +License: MIT +Repository: https://github.com/babel/acorn-to-esprima +License File: acorn-to-esprima/LICENSE + +align-text +License: MIT +Repository: https://github.com/jonschlinkert/align-text +License File: align-text/LICENSE + +alphanum-sort +License: MIT +Repository: https://github.com/TrySound/alphanum-sort +License File: alphanum-sort/LICENSE + +amdefine +License: BSD-3-Clause AND MIT +Repository: https://github.com/jrburke/amdefine +License File: amdefine/LICENSE + +ansi +License: MIT +Repository: https://github.com/TooTallNate/ansi.js + +ansi-escapes +License: MIT +Repository: https://github.com/sindresorhus/ansi-escapes +License File: ansi-escapes/license + +ansi-green +License: MIT +Repository: https://github.com/jonschlinkert/ansi-green +License File: ansi-green/LICENSE + +ansi-regex +License: MIT +Repository: https://github.com/sindresorhus/ansi-regex + +ansi-regex +License: MIT +Repository: https://github.com/sindresorhus/ansi-regex +License File: webpack-hot-middleware/node_modules/ansi-regex/license + +ansi-regex +License: MIT +Repository: https://github.com/sindresorhus/ansi-regex +License File: ansi-regex/license + +ansi-styles +License: MIT +Repository: https://github.com/sindresorhus/ansi-styles + +ansi-styles +License: MIT +Repository: https://github.com/chalk/ansi-styles +License File: ansi-styles/license + +ansi-wrap +License: MIT +Repository: https://github.com/jonschlinkert/ansi-wrap +License File: ansi-wrap/LICENSE + +anymatch +License: ISC +Repository: https://github.com/es128/anymatch +License File: anymatch/LICENSE + +are-we-there-yet +License: ISC +Repository: https://github.com/iarna/are-we-there-yet + +argparse +License: MIT +Repository: https://github.com/nodeca/argparse +License File: argparse/LICENSE + +arr-diff +License: MIT +Repository: https://github.com/jonschlinkert/arr-diff +License File: arr-diff/LICENSE + +arr-flatten +License: MIT +Repository: https://github.com/jonschlinkert/arr-flatten +License File: arr-flatten/LICENSE + +array-find +License: MIT +Repository: https://github.com/stefanduberg/array-find +License File: array-find/LICENSE + +array-flatten +License: MIT +Repository: https://github.com/blakeembrey/array-flatten +License File: array-flatten/LICENSE + +array-union +License: MIT +Repository: https://github.com/sindresorhus/array-union + +array-uniq +License: MIT +Repository: https://github.com/sindresorhus/array-uniq + +array-unique +License: MIT +Repository: https://github.com/jonschlinkert/array-unique +License File: array-unique/LICENSE + +arrify +License: MIT +Repository: https://github.com/sindresorhus/arrify +License File: arrify/license + +asap +License: MIT +License File: less/node_modules/asap/LICENSE.md + +asap +License: MIT +Repository: https://github.com/kriskowal/asap +License File: asap/LICENSE.md + +asar +License: MIT +Repository: https://github.com/atom/asar +License File: asar/LICENSE + +asn11 +License: MIT +Repository: https://github.com/mcavage/node-asn1 +License File: mksnapshot/node_modules/asn1/LICENSE + +asn1 +License: MIT +Repository: https://github.com/mcavage/node-asn1 +License File: asn1/LICENSE + +assert +License: MIT +Repository: https://github.com/defunctzombie/commonjs-assert +License File: assert/LICENSE + +assert-plus +License: MIT +Repository: https://github.com/mcavage/node-assert-plus + +assert-plus +License: MIT +Repository: https://github.com/mcavage/node-assert-plus + +ast-types2 +License: MIT +Repository: https://github.com/benjamn/ast-types +License File: ast-types/LICENSE + +async0 +License: MIT +Repository: https://github.com/caolan/async +License File: uglify-js/node_modules/async/LICENSE + +async +License: MIT +Repository: https://github.com/caolan/async +License File: mksnapshot/node_modules/async/LICENSE + +async +License: MIT +Repository: https://github.com/caolan/async +License File: async/LICENSE + +async-each +License: MIT +Repository: https://github.com/paulmillr/async-each + +autoprefixer +License: MIT +Repository: https://github.com/postcss/autoprefixer +License File: react-crop/node_modules/autoprefixer/LICENSE + +autoprefixer +License: MIT +Repository: https://github.com/postcss/autoprefixer +License File: autoprefixer/LICENSE + +autoprefixer-core +License: MIT +Repository: https://github.com/postcss/autoprefixer-core +License File: autoprefixer-core/LICENSE + +aws-sign2 +License: Apache +Repository: https://github.com/mikeal/aws-sign +License File: mksnapshot/node_modules/aws-sign2/LICENSE + +aws-sign2 +License: Apache-2.0 +Repository: https://github.com/mikeal/aws-sign +License File: aws-sign2/LICENSE + +babel-cli7 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-cli + +babel-code-frame3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-code-frame + +babel-core6 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-core + +babel-eslint-beta6 +License: MIT +Repository: https://github.com/babel/babel-eslint +License File: babel-eslint/LICENSE + +babel-generator6 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-generator + +babel-helper-bindify-decorators3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-bindify-decorators + +babel-helper-builder-binary-assignment-operator-visitor3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-builder-binary-assignment-operator-visitor + +babel-helper-builder-react-jsx3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-builder-react-jsx + +babel-helper-call-delegate3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-call-delegate + +babel-helper-define-map3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-define-map + +babel-helper-explode-assignable-expression3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-explode-assignable-expression + +babel-helper-explode-class3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-explode-class + +babel-helper-function-name5 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-function-name + +babel-helper-get-function-arity3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-get-function-arity + +babel-helper-hoist-variables3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-hoist-variables + +babel-helper-optimise-call-expression3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-optimise-call-expression + +babel-helper-regex3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-regex + +babel-helper-remap-async-to-generator3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-remap-async-to-generator + +babel-helper-replace-supers3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helper-replace-supers + +babel-helpers3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-helpers + +babel-jest +License: MIT* +Repository: https://github.com/babel/babel-jest +License File: babel-jest/LICENSE + +babel-loader +License: MIT +Repository: https://github.com/babel/babel-loader +License File: babel-loader/LICENSE + +babel-messages8 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-messages + +babel-plugin-check-es2015-constants3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-check-es2015-constants + +babel-plugin-react-transform +License: MIT +Repository: https://github.com/gaearon/babel-plugin-react-transform + +babel-plugin-syntax-async-functions3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-async-functions + +babel-plugin-syntax-class-constructor-call3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-class-constructor-call + +babel-plugin-syntax-class-properties3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-class-properties + +babel-plugin-syntax-decorators3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-decorators + +babel-plugin-syntax-do-expressions3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-do-expressions + +babel-plugin-syntax-exponentiation-operator3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-exponentation-operator + +babel-plugin-syntax-export-extensions3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-export-extensions + +babel-plugin-syntax-flow3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-flow + +babel-plugin-syntax-function-bind3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-function-bind + +babel-plugin-syntax-jsx3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-jsx + +babel-plugin-syntax-object-rest-spread3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-object-rest-spread + +babel-plugin-syntax-trailing-function-commas3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-trailing-function-commas + +babel-plugin-transform-async-to-generator3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-async-to-generator + +babel-plugin-transform-class-constructor-call3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-class-constructor-call + +babel-plugin-transform-class-properties3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-class-properties + +babel-plugin-transform-decorators3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-decorators + +babel-plugin-transform-do-expressions3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-do-expressions + +babel-plugin-transform-es2015-arrow-functions3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-arrow-functions + +babel-plugin-transform-es2015-block-scoped-functions3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-block-scoped-functions + +babel-plugin-transform-es2015-block-scoping3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-block-scoping + +babel-plugin-transform-es2015-classes5 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-classes + +babel-plugin-transform-es2015-computed-properties3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-computed-properties + +babel-plugin-transform-es2015-destructuring5 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-destructuring + +babel-plugin-transform-es2015-for-of3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-for-of + +babel-plugin-transform-es2015-function-name9 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-function-name + +babel-plugin-transform-es2015-literals3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-literals + +babel-plugin-transform-es2015-modules-commonjs6 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-modules-commonjs + +babel-plugin-transform-es2015-object-super3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-object-super + +babel-plugin-transform-es2015-parameters8 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-parameters + +babel-plugin-transform-es2015-shorthand-properties3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-shorthand-properties + +babel-plugin-transform-es2015-spread4 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-spread + +babel-plugin-transform-es2015-sticky-regex3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-sticky-regex + +babel-plugin-transform-es2015-template-literals3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-template-literals + +babel-plugin-transform-es2015-typeof-symbol3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-typeof-symbol + +babel-plugin-transform-es2015-unicode-regex3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-unicode-regex + +babel-plugin-transform-exponentiation-operator3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-exponentiation-operator + +babel-plugin-transform-export-extensions3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-export-extensions + +babel-plugin-transform-flow-strip-types5 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-flow-strip-types + +babel-plugin-transform-function-bind3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-function-bind + +babel-plugin-transform-object-rest-spread3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-object-rest-spread + +babel-plugin-transform-react-display-name3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-display-name + +babel-plugin-transform-react-jsx3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-jsx + +babel-plugin-transform-react-jsx-source3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-source + +babel-plugin-transform-regenerator8 +License: BSD +License File: babel-plugin-transform-regenerator/LICENSE + +babel-plugin-transform-runtime3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-runtime + +babel-plugin-transform-strict-mode3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-strict-mode + +babel-polyfill4 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-polyfill + +babel-preset-es20153 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-preset-es2015 + +babel-preset-react3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-preset-react + +babel-preset-stage-03 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-preset-stage-0 + +babel-preset-stage-13 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-preset-stage-1 + +babel-preset-stage-23 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-preset-stage-2 + +babel-preset-stage-33 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-preset-stage-3 + +babel-regenerator-runtime3 +License: BSD +License File: babel-regenerator-runtime/LICENSE + +babel-register3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-register + +babel-relay-plugin +License: BSD-3-Clause +Repository: https://github.com/facebook/relay +License File: babel-relay-plugin/LICENSE + +babel-runtime4 +License: MIT +Repository: https://github.com/babel/babel + +babel-runtime4 +License: MIT +Repository: https://github.com/babel/babel + +babel-template3 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-template + +babel-traverse9 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-traverse + +babel-traverse6 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-traverse + +babel-types0 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-types + +babel-types4 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babel-types + +babylon0 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babylon +License File: babylon/LICENSE + +babylon6 +License: MIT +Repository: https://github.com/babel/babel/tree/master/packages/babylon +License File: babel-generator/node_modules/babylon/LICENSE + +balanced-match +License: MIT +Repository: https://github.com/juliangruber/balanced-match + +balanced-match +License: MIT +Repository: https://github.com/juliangruber/balanced-match +License File: balanced-match/LICENSE.md + +base62 +License: MIT* +Repository: https://github.com/andrew/base62.js +License File: base62/LICENSE + +base64-js +License: MIT +Repository: https://github.com/beatgammit/base64-js +License File: base64-js/LICENSE.MIT + +big.js +License: MIT +Repository: https://github.com/MikeMcl/big.js +License File: big.js/LICENCE + +bin-check +License: MIT +Repository: https://github.com/kevva/bin-check + +bin-version +License: MIT +Repository: https://github.com/sindresorhus/bin-version +License File: bin-version/license + +bin-version-check +License: MIT +Repository: https://github.com/sindresorhus/bin-version-check + +bin-wrapper +License: MIT +Repository: https://github.com/kevva/bin-wrapper +License File: bin-wrapper/LICENSE.md + +binary +License: MIT +Repository: https://github.com/substack/node-binary + +binary-extensions +License: MIT +Repository: https://github.com/sindresorhus/binary-extensions +License File: binary-extensions/license + +bl +License: MIT +Repository: https://github.com/rvagg/bl +License File: mksnapshot/node_modules/bl/LICENSE.md + +bl +License: MIT +Repository: https://github.com/rvagg/bl +License File: bl/LICENSE.md + +block-stream +License: ISC +Repository: https://github.com/isaacs/block-stream +License File: fsevents/node_modules/block-stream/LICENSE + +bluebird2 +License: MIT +Repository: https://github.com/petkaantonov/bluebird +License File: bluebird/LICENSE + +boom1 +License: BSD-3-Clause +Repository: https://github.com/hapijs/boom +License File: boom/LICENSE + +brace-expansion +License: MIT +Repository: https://github.com/juliangruber/brace-expansion + +braces +License: MIT +Repository: https://github.com/jonschlinkert/braces +License File: braces/LICENSE + +browserify-zlib +License: MIT +Repository: https://github.com/devongovett/browserify-zlib + +browserslist +License: MIT +Repository: https://github.com/ai/browserslist +License File: autoprefixer-core/node_modules/browserslist/LICENSE + +browserslist +License: MIT +Repository: https://github.com/ai/browserslist +License File: browserslist/LICENSE + +bser +License: Apache-2.0 +Repository: https://github.com/facebook/watchman + +buffer +License: MIT +Repository: https://github.com/feross/buffer +License File: buffer/LICENSE + +buffers +License: UNKNOWN +Repository: https://github.com/substack/node-buffers + +builtin-modules +License: MIT +Repository: https://github.com/sindresorhus/builtin-modules +License File: builtin-modules/license + +camelcase +License: MIT +Repository: https://github.com/sindresorhus/camelcase +License File: uglify-js/node_modules/camelcase/license + +camelcase +License: MIT +Repository: https://github.com/sindresorhus/camelcase +License File: camelcase/license + +camelcase-keys +License: MIT +Repository: https://github.com/sindresorhus/camelcase-keys + +camelcase-keys +License: MIT +Repository: https://github.com/sindresorhus/camelcase-keys +License File: camelcase-keys/license + +caniuse-db0000377 +License: CC-BY-4.0 +Repository: https://github.com/Fyrd/caniuse + +caniuse-db0000384 +License: CC-BY-4.0 +Repository: https://github.com/Fyrd/caniuse + +caseless0 +License: Apache-2.0 +Repository: https://github.com/mikeal/caseless +License File: caseless/LICENSE + +caseless +License: BSD +Repository: https://github.com/mikeal/caseless + +center-align +License: MIT +Repository: https://github.com/jonschlinkert/center-align +License File: center-align/LICENSE + +chainsaw +License: MIT/X11 +Repository: https://github.com/substack/node-chainsaw + +chalk +License: MIT +Repository: https://github.com/sindresorhus/chalk + +chalk +License: MIT +Repository: https://github.com/chalk/chalk +License File: chalk/license + +chokidar +License: MIT +Repository: https://github.com/paulmillr/chokidar + +chromium-pickle-js +License: MIT +Repository: https://github.com/atom/node-chromium-pickle-js + +clap0 +License: MIT +Repository: https://github.com/lahmatiy/clap +License File: clap/LICENSE + +classnames +License: MIT +Repository: https://github.com/JedWatson/classnames +License File: classnames/LICENSE + +cli-cursor +License: MIT +Repository: https://github.com/sindresorhus/cli-cursor +License File: cli-cursor/license + +cli-table +License: MIT* + +cli-width +License: ISC +Repository: https://github.com/knownasilya/cli-width +License File: cli-width/LICENSE + +cliui +License: ISC +Repository: https://github.com/bcoe/cliui +License File: uglify-js/node_modules/cliui/LICENSE.txt + +cliui +License: ISC +Repository: https://github.com/bcoe/cliui +License File: cliui/LICENSE.txt + +clone +License: MIT +Repository: https://github.com/pvorb/node-clone +License File: clone/LICENSE + +clone +License: MIT +Repository: https://github.com/pvorb/node-clone +License File: webpack/node_modules/clone/LICENSE + +clone-stats +License: MIT +Repository: https://github.com/hughsk/clone-stats +License File: clone-stats/LICENSE.md + +co +License: MIT +Repository: https://github.com/visionmedia/co + +coa +License: MIT +Repository: https://github.com/veged/coa + +code-point-at +License: MIT +Repository: https://github.com/sindresorhus/code-point-at +License File: code-point-at/license + +color1 +License: MIT +Repository: https://github.com/MoOx/color +License File: color/LICENSE + +color-convert +License: MIT* +Repository: https://github.com/harthur/color-convert +License File: color-convert/LICENSE + +color-name +License: MIT +Repository: https://github.com/dfcreative/color-name +License File: color-name/LICENSE + +color-string +License: MIT +Repository: https://github.com/harthur/color-string +License File: color-string/LICENSE + +colormin +License: MIT +Repository: https://github.com/ben-eb/colormin +License File: colormin/LICENSE-MIT + +colors +License: MIT* +Repository: https://github.com/Marak/colors.js +License File: cli-table/node_modules/colors/MIT-LICENSE.txt + +colors +License: MIT +Repository: https://github.com/Marak/colors.js +License File: colors/LICENSE + +combined-stream +License: MIT* +Repository: https://github.com/felixge/node-combined-stream +License File: mksnapshot/node_modules/combined-stream/License + +combined-stream +License: MIT +Repository: https://github.com/felixge/node-combined-stream +License File: combined-stream/License + +commander +License: MIT* +Repository: https://github.com/visionmedia/commander.js + +commander +License: MIT +Repository: https://github.com/tj/commander.js +License File: seek-bzip/node_modules/commander/LICENSE + +commander +License: MIT +Repository: https://github.com/tj/commander.js +License File: commander/LICENSE + +concat-map +License: MIT +Repository: https://github.com/substack/node-concat-map +License File: concat-map/LICENSE + +concat-stream +License: MIT +Repository: https://github.com/maxogden/concat-stream +License File: concat-stream/LICENSE + +console-browserify +License: MIT +Repository: https://github.com/Raynos/console-browserify +License File: console-browserify/LICENCE + +console-stream +License: MIT +Repository: https://github.com/Raynos/console-stream +License File: console-stream/LICENCE + +constants-browserify +License: MIT +Repository: https://github.com/juliangruber/constants-browserify + +content-disposition +License: MIT +Repository: https://github.com/jshttp/content-disposition +License File: content-disposition/LICENSE + +content-type +License: MIT +Repository: https://github.com/jshttp/content-type +License File: content-type/LICENSE + +convert-source-map +License: MIT +Repository: https://github.com/thlorenz/convert-source-map +License File: convert-source-map/LICENSE + +cookie +License: MIT +Repository: https://github.com/jshttp/cookie +License File: cookie/LICENSE + +cookie-signature +License: MIT +Repository: https://github.com/visionmedia/node-cookie-signature + +core-js +License: MIT +Repository: https://github.com/zloirock/core-js +License File: core-js/LICENSE + +core-util-is +License: MIT +Repository: https://github.com/isaacs/core-util-is +License File: core-util-is/LICENSE + +cover +License: MIT/X11 +Repository: https://github.com/itay/node-cover + +cryptiles +License: BSD-3-Clause +Repository: https://github.com/hapijs/cryptiles +License File: cryptiles/LICENSE + +crypto-browserify +License: MIT +Repository: https://github.com/dominictarr/crypto-browserify +License File: crypto-browserify/LICENSE + +css-color-names +License: MIT +Repository: https://github.com/bahamas10/css-color-names + +css-loader1 +License: MIT +Repository: https://github.com/webpack/css-loader + +css-selector-tokenizer +License: MIT +Repository: https://github.com/css-modules/css-selector-tokenizer + +cssesc +License: MIT +Repository: https://github.com/mathiasbynens/cssesc +License File: cssesc/LICENSE-MIT.txt + +cssnano +License: MIT +Repository: https://github.com/ben-eb/cssnano +License File: cssnano/LICENSE-MIT + +csso +License: MIT +Repository: https://github.com/css/csso +License File: csso/LICENSE + +cssom +License: MIT +Repository: https://github.com/NV/CSSOM +License File: cssom/MIT-LICENSE.txt + +cssstyle0 +License: MIT +Repository: https://github.com/chad3814/CSSStyleDeclaration +License File: cssstyle/MIT-LICENSE.txt + +ctype +License: MIT* +Repository: https://github.com/rmustacc/node-ctype +License File: ctype/LICENSE + +cuint +License: MIT +Repository: https://github.com/pierrec/js-cuint + +d +License: MIT +Repository: https://github.com/medikoo/d +License File: d/LICENCE + +dashdash1 +License: MIT +Repository: https://github.com/trentm/node-dashdash + +data-uri-to-blob +License: MIT + +date-now +License: MIT +Repository: https://github.com/Colingo/date-now +License File: date-now/LICENCE + +debug +License: MIT* +Repository: https://github.com/visionmedia/debug + +debug +License: MIT +Repository: https://github.com/visionmedia/debug + +decamelize +License: MIT +Repository: https://github.com/sindresorhus/decamelize +License File: decamelize/license + +decompress-tar +License: MIT +Repository: https://github.com/kevva/decompress-tar + +decompress-tarbz2 +License: MIT +Repository: https://github.com/kevva/decompress-tarbz2 + +decompress-targz +License: MIT +Repository: https://github.com/kevva/decompress-targz + +decompress-unzip +License: MIT +Repository: https://github.com/kevva/decompress-unzip +License File: decompress-unzip/license + +decompress-zip +License: MIT +Repository: https://github.com/bower/decompress-zip + +deep-equal +License: MIT +Repository: https://github.com/substack/node-deep-equal +License File: deep-equal/LICENSE + +deep-extend1 +License: MIT +Repository: https://github.com/unclechu/node-deep-extend +License File: download/node_modules/deep-extend/LICENSE + +deep-extend +License: MIT +Repository: https://github.com/unclechu/node-deep-extend +License File: deep-extend/LICENSE + +deep-is +License: MIT +Repository: https://github.com/thlorenz/deep-is +License File: deep-is/LICENSE + +defaults +License: MIT +Repository: https://github.com/tmpvar/defaults +License File: defaults/LICENSE + +defined +License: MIT +Repository: https://github.com/substack/defined +License File: defined/LICENSE + +del +License: MIT +Repository: https://github.com/sindresorhus/del +License File: del/license + +delayed-stream +License: MIT* +Repository: https://github.com/felixge/node-delayed-stream +License File: mksnapshot/node_modules/delayed-stream/License + +delayed-stream +License: MIT +Repository: https://github.com/felixge/node-delayed-stream +License File: delayed-stream/License + +delegates +License: MIT +Repository: https://github.com/visionmedia/node-delegates + +depd +License: MIT +Repository: https://github.com/dougwilson/nodejs-depd +License File: depd/LICENSE + +destroy +License: MIT +Repository: https://github.com/stream-utils/destroy + +detect-indent +License: MIT +Repository: https://github.com/sindresorhus/detect-indent +License File: detect-indent/license + +diff +License: BSD-3-Clause +Repository: https://github.com/kpdecker/jsdiff +License File: diff/LICENSE + +doctrine +License: BSD +Repository: https://github.com/eslint/doctrine +License File: doctrine/LICENSE.esprima + +dom-helpers +License: MIT +Repository: https://github.com/jquense/dom-helpers + +dom-walk +License: MIT +Repository: https://github.com/Raynos/dom-walk +License File: dom-walk/LICENCE + +domain-browser +License: MIT +Repository: https://github.com/bevry/domain-browser +License File: domain-browser/LICENSE.md + +download +License: MIT +Repository: https://github.com/kevva/download +License File: download/LICENSE.md + +download-status +License: MIT +Repository: https://github.com/kevva/download-status +License File: download-status/license + +duplexer +License: MIT +Repository: https://github.com/Raynos/duplexer +License File: duplexer/LICENCE + +each-async +License: MIT +Repository: https://github.com/sindresorhus/each-async +License File: each-async/license + +ecc-jsbn +License: MIT +Repository: https://github.com/quartzjer/ecc-jsbn +License File: ecc-jsbn/LICENSE + +ee-first +License: MIT +Repository: https://github.com/jonathanong/ee-first +License File: ee-first/LICENSE + +electron-download +License: BSD-3-Clause +Repository: https://github.com/maxogden/electron-download + +electron-packager +License: BSD-2-Clause +Repository: https://github.com/maxogden/electron-packager +License File: electron-packager/LICENSE + +electron-prebuilt2 +License: MIT +Repository: https://github.com/mafintosh/electron-prebuilt +License File: electron-prebuilt/LICENSE + +end-of-stream +License: MIT +Repository: https://github.com/mafintosh/end-of-stream +License File: end-of-stream/LICENSE + +enhanced-resolve +License: MIT +Repository: https://github.com/webpack/enhanced-resolve + +envify +License: MIT +Repository: https://github.com/hughsk/envify + +errno +License: MIT +Repository: https://github.com/rvagg/node-errno + +error-ex +License: MIT +Repository: https://github.com/qix-/node-error-ex +License File: error-ex/LICENSE + +error-stack-parser +License: Unlicense +Repository: https://github.com/stacktracejs/error-stack-parser +License File: error-stack-parser/LICENSE + +es5-ext11 +License: MIT +Repository: https://github.com/medikoo/es5-ext +License File: es5-ext/LICENSE + +es6-iterator +License: MIT +Repository: https://github.com/medikoo/es6-iterator +License File: es6-iterator/LICENSE + +es6-map +License: MIT +Repository: https://github.com/medikoo/es6-map +License File: es6-map/LICENSE + +es6-promise +License: MIT +Repository: https://github.com/jakearchibald/ES6-Promises +License File: es6-promise/LICENSE + +es6-set +License: MIT +Repository: https://github.com/medikoo/es6-set +License File: es6-set/LICENSE + +es6-symbol +License: MIT +Repository: https://github.com/medikoo/es6-symbol +License File: es6-symbol/LICENSE + +es6-weak-map +License: MIT +Repository: https://github.com/medikoo/es6-weak-map +License File: es6-weak-map/LICENSE + +escape-html +License: MIT +Repository: https://github.com/component/escape-html +License File: escape-html/LICENSE + +escape-string-regexp +License: MIT +Repository: https://github.com/sindresorhus/escape-string-regexp +License File: escape-string-regexp/license + +escodegen +License: BSD-2-Clause +Repository: https://github.com/estools/escodegen +License File: escodegen/LICENSE.source-map + +escope +License: BSD-2-Clause +Repository: https://github.com/estools/escope +License File: escope/LICENSE.BSD + +eslint3 +License: MIT +Repository: https://github.com/eslint/eslint +License File: eslint/LICENSE + +eslint-plugin-flow-vars +License: MIT +Repository: https://github.com/zertosh/eslint-plugin-flow-vars + +eslint-plugin-react1 +License: MIT +Repository: https://github.com/yannickcr/eslint-plugin-react +License File: eslint-plugin-react/LICENSE + +espree +License: BSD +Repository: https://github.com/eslint/espree + +esprima +License: BSD +Repository: https://github.com/ariya/esprima +License File: escodegen/node_modules/esprima/LICENSE.BSD + +esprima +License: BSD-2-Clause +Repository: https://github.com/jquery/esprima +License File: istanbul/node_modules/esprima/LICENSE.BSD + +esprima +License: BSD-2-Clause +Repository: https://github.com/jquery/esprima +License File: esprima/LICENSE.BSD + +esprima-fb.1001.0-dev-harmony-fb +License: BSD +Repository: https://github.com/facebook/esprima + +esprima-fb.1001.0-dev-harmony-fb +License: BSD +Repository: https://github.com/facebook/esprima + +esprima-fb1001.0-dev-harmony-fb +License: BSD +Repository: https://github.com/facebook/esprima + +esrecurse +License: BSD +Repository: https://github.com/estools/esrecurse + +estraverse +License: BSD +Repository: https://github.com/estools/estraverse +License File: escodegen/node_modules/estraverse/LICENSE.BSD + +estraverse +License: BSD +Repository: https://github.com/estools/estraverse +License File: esrecurse/node_modules/estraverse/LICENSE.BSD + +estraverse +License: BSD-2-Clause +Repository: https://github.com/estools/estraverse +License File: estraverse/LICENSE.BSD + +estraverse-fb +License: MIT +Repository: https://github.com/rreverser/estraverse-fb +License File: estraverse-fb/LICENSE + +esutils +License: BSD +Repository: https://github.com/Constellation/esutils +License File: doctrine/node_modules/esutils/LICENSE.BSD + +esutils +License: BSD +Repository: https://github.com/estools/esutils +License File: esutils/LICENSE.BSD + +etag +License: MIT +Repository: https://github.com/jshttp/etag +License File: etag/LICENSE + +event-emitter +License: MIT +Repository: https://github.com/medikoo/event-emitter +License File: event-emitter/LICENSE + +events +License: MIT +Repository: https://github.com/Gozala/events +License File: events/LICENSE + +exec-sh +License: MIT +Repository: https://github.com/tsertkov/exec-sh +License File: exec-sh/LICENSE + +executable +License: MIT +Repository: https://github.com/kevva/executable +License File: executable/license + +exit-hook +License: MIT +Repository: https://github.com/sindresorhus/exit-hook + +expand-brackets +License: MIT +Repository: https://github.com/jonschlinkert/expand-brackets +License File: expand-brackets/LICENSE + +expand-range +License: MIT +Repository: https://github.com/jonschlinkert/expand-range +License File: expand-range/LICENSE + +express3 +License: MIT +Repository: https://github.com/strongloop/express +License File: express/LICENSE + +extend +License: MIT +Repository: https://github.com/justmoon/node-extend +License File: extend/LICENSE + +extglob +License: MIT +Repository: https://github.com/jonschlinkert/extglob +License File: extglob/LICENSE + +extract-zip +License: BSD-2-Clause +Repository: https://github.com/maxogden/extract-zip + +extsprintf +License: MIT* +Repository: https://github.com/davepacheco/node-extsprintf +License File: extsprintf/LICENSE + +fast-levenshtein +License: MIT +Repository: https://github.com/hiddentao/fast-levenshtein +License File: fast-levenshtein/LICENSE.md + +fastparse +License: MIT +Repository: https://github.com/webpack/fastparse + +fb-watchman +License: Apache-2.0 +Repository: https://github.com/facebook/watchman + +fbemitter +License: BSD-3-Clause +Repository: https://github.com/facebook/emitter +License File: fbemitter/LICENSE + +fbjs-alpha.7 +License: BSD-3-Clause +Repository: https://github.com/facebook/fbjs +License File: fbemitter/node_modules/fbjs/LICENSE + +fbjs +License: BSD-3-Clause +Repository: https://github.com/facebook/fbjs +License File: react-relay/node_modules/fbjs/LICENSE + +fbjs +License: BSD-3-Clause +Repository: https://github.com/facebook/fbjs +License File: fbjs/LICENSE + +fd-slicer +License: MIT +Repository: https://github.com/andrewrk/node-fd-slicer +License File: fd-slicer/LICENSE + +figures +License: MIT +Repository: https://github.com/sindresorhus/figures +License File: figures/license + +file-entry-cache +License: MIT +Repository: https://github.com/royriojas/file-entry-cache +License File: file-entry-cache/LICENSE + +file-loader +License: MIT +Repository: https://github.com/webpack/file-loader + +filename-regex +License: MIT +Repository: https://github.com/regexps/filename-regex + +fileset +License: MIT +Repository: https://github.com/mklabs/node-fileset +License File: fileset/LICENSE-MIT + +filesize +License: BSD-3-Clause +Repository: https://github.com/avoidwork/filesize.js +License File: filesize/LICENSE + +fill-range +License: MIT +Repository: https://github.com/jonschlinkert/fill-range +License File: fill-range/LICENSE + +finalhandler +License: MIT +Repository: https://github.com/pillarjs/finalhandler +License File: finalhandler/LICENSE + +find-index +License: MIT +Repository: https://github.com/jsdf/find-index + +find-up +License: MIT +Repository: https://github.com/sindresorhus/find-up +License File: find-up/license + +find-versions +License: MIT +Repository: https://github.com/sindresorhus/find-versions +License File: find-versions/license + +first-chunk-stream +License: MIT +Repository: https://github.com/sindresorhus/first-chunk-stream + +flat-cache0 +License: MIT +Repository: https://github.com/royriojas/flat-cache +License File: flat-cache/LICENSE + +flatten +License: MIT* +Repository: https://github.com/jesusabdullah/node-flatten + +flow-bin0 +License: MIT +Repository: https://github.com/sindresorhus/flow-bin +License File: flow-bin/license + +flux +License: BSD-3-Clause +Repository: https://github.com/facebook/flux +License File: flux/LICENSE + +for-in +License: MIT +Repository: https://github.com/jonschlinkert/for-in +License File: for-in/LICENSE + +for-own +License: MIT +Repository: https://github.com/jonschlinkert/for-own +License File: for-own/LICENSE + +forever-agent +License: Apache-2.0 +Repository: https://github.com/mikeal/forever-agent +License File: forever-agent/LICENSE + +form-data +License: MIT +Repository: https://github.com/felixge/node-form-data +License File: mksnapshot/node_modules/form-data/License + +form-data-rc3 +License: MIT +Repository: https://github.com/form-data/form-data +License File: form-data/License + +forwarded +License: MIT +Repository: https://github.com/jshttp/forwarded +License File: forwarded/LICENSE + +fresh +License: MIT +Repository: https://github.com/jshttp/fresh +License File: fresh/LICENSE + +fs-extra2 +License: MIT +Repository: https://github.com/jprichardson/node-fs-extra +License File: mksnapshot/node_modules/fs-extra/LICENSE + +fs-extra4 +License: MIT +Repository: https://github.com/jprichardson/node-fs-extra +License File: react-crop/node_modules/fs-extra/LICENSE + +fs-extra3 +License: MIT +Repository: https://github.com/jprichardson/node-fs-extra +License File: fs-extra/LICENSE + +fs-readdir-recursive +License: MIT +Repository: https://github.com/fs-utils/fs-readdir-recursive +License File: fs-readdir-recursive/LICENSE + +fsevents +License: MIT +Repository: https://github.com/strongloop/fsevents +License File: fsevents/LICENSE + +fstream +License: ISC +Repository: https://github.com/isaacs/fstream +License File: fsevents/node_modules/fstream/LICENSE + +fstream-ignore +License: ISC +Repository: https://github.com/isaacs/fstream-ignore +License File: fsevents/node_modules/fstream-ignore/LICENSE + +gather-stream +License: ISC +Repository: https://github.com/natevw/gather-stream + +gauge +License: ISC +Repository: https://github.com/iarna/gauge +License File: fsevents/node_modules/gauge/LICENSE + +gaze +License: MIT +Repository: https://github.com/shama/gaze +License File: gaze/LICENSE-MIT + +generate-function +License: MIT +Repository: https://github.com/mafintosh/generate-function + +generate-object-property +License: MIT +Repository: https://github.com/mafintosh/generate-object-property +License File: generate-object-property/LICENSE + +get-stdin +License: MIT +Repository: https://github.com/sindresorhus/get-stdin + +get-stdin +License: MIT +Repository: https://github.com/sindresorhus/get-stdin + +glob1 +License: BSD +Repository: https://github.com/isaacs/node-glob +License File: globule/node_modules/glob/LICENSE + +glob +License: ISC +Repository: https://github.com/isaacs/node-glob +License File: glob-stream/node_modules/glob/LICENSE + +glob5 +License: ISC +Repository: https://github.com/isaacs/node-glob +License File: babel-cli/node_modules/glob/LICENSE + +glob +License: ISC +Repository: https://github.com/isaacs/node-glob +License File: del/node_modules/glob/LICENSE + +glob-base +License: MIT +Repository: https://github.com/jonschlinkert/glob-base +License File: glob-base/LICENSE + +glob-parent +License: ISC +Repository: https://github.com/es128/glob-parent +License File: glob-parent/LICENSE + +glob-stream8 +License: MIT +Repository: https://github.com/wearefractal/glob-stream +License File: glob-stream/LICENSE + +glob-watcher +License: MIT +Repository: https://github.com/wearefractal/glob-watcher +License File: glob-watcher/LICENSE + +glob2base2 +License: MIT +Repository: https://github.com/wearefractal/glob2base +License File: glob2base/LICENSE + +global +License: MIT +Repository: https://github.com/Raynos/global +License File: global/LICENCE + +globals0 +License: MIT +Repository: https://github.com/sindresorhus/globals +License File: globals/license + +globby +License: MIT +Repository: https://github.com/sindresorhus/globby +License File: globby/license + +globby +License: MIT +Repository: https://github.com/sindresorhus/globby +License File: del/node_modules/globby/license + +globule +License: MIT +Repository: https://github.com/cowboy/node-globule +License File: globule/LICENSE-MIT + +graceful-fs +License: BSD +Repository: https://github.com/isaacs/node-graceful-fs +License File: globule/node_modules/graceful-fs/LICENSE + +graceful-fs +License: ISC +Repository: https://github.com/isaacs/node-graceful-fs +License File: decompress-zip/node_modules/graceful-fs/LICENSE + +graceful-fs +License: ISC +Repository: https://github.com/isaacs/node-graceful-fs +License File: graceful-fs/LICENSE + +graceful-readlink +License: MIT +Repository: https://github.com/zhiyelee/graceful-readlink +License File: graceful-readlink/LICENSE + +graphql3 +License: BSD-3-Clause +Repository: https://github.com/graphql/graphql-js +License File: graphql/LICENSE + +gulp-rename +License: MIT +Repository: https://github.com/hparra/gulp-rename + +handlebars +License: MIT +Repository: https://github.com/wycats/handlebars.js +License File: handlebars/LICENSE + +har-validator +License: ISC +Repository: https://github.com/ahmadnassri/har-validator +License File: mksnapshot/node_modules/har-validator/LICENSE + +har-validator +License: ISC +Repository: https://github.com/ahmadnassri/har-validator +License File: har-validator/LICENSE + +has-ansi +License: MIT +Repository: https://github.com/sindresorhus/has-ansi + +has-ansi +License: MIT +Repository: https://github.com/sindresorhus/has-ansi +License File: has-ansi/license + +has-flag +License: MIT +Repository: https://github.com/sindresorhus/has-flag +License File: has-flag/license + +has-own +License: MIT +Repository: https://github.com/pebble/has-own +License File: has-own/LICENSE + +has-unicode +License: ISC +Repository: https://github.com/iarna/has-unicode +License File: fsevents/node_modules/has-unicode/LICENSE + +hawk +License: BSD +Repository: https://github.com/hueniverse/hawk +License File: mksnapshot/node_modules/hawk/LICENSE + +hawk +License: BSD-3-Clause +Repository: https://github.com/hueniverse/hawk +License File: hawk/LICENSE + +history0 +License: MIT +Repository: https://github.com/rackt/history +License File: history/LICENSE.md + +hoek3 +License: BSD-3-Clause +Repository: https://github.com/hapijs/hoek +License File: hoek/LICENSE + +home-or-tmp +License: MIT +Repository: https://github.com/sindresorhus/home-or-tmp +License File: home-or-tmp/license + +home-path +License: MIT +Repository: https://github.com/75lb/home-path +License File: home-path/LICENSE + +hosted-git-info +License: ISC +Repository: https://github.com/npm/hosted-git-info +License File: hosted-git-info/LICENSE + +http-browserify +License: MIT/X11 +Repository: https://github.com/substack/http-browserify +License File: http-browserify/LICENSE + +http-errors +License: MIT +Repository: https://github.com/jshttp/http-errors +License File: http-errors/LICENSE + +http-signature1 +License: MIT +Repository: https://github.com/joyent/node-http-signature +License File: mksnapshot/node_modules/http-signature/LICENSE + +http-signature +License: MIT +Repository: https://github.com/joyent/node-http-signature +License File: http-signature/LICENSE + +https-browserify +License: MIT +Repository: https://github.com/substack/https-browserify +License File: https-browserify/LICENSE + +icss-replace-symbols +License: ISC +Repository: https://github.com/css-modules/icss-replace-symbols + +ieee754 +License: MIT +Repository: https://github.com/feross/ieee754 +License File: ieee754/LICENSE + +image-size +License: MIT +Repository: https://github.com/netroy/image-size +License File: image-size/LICENSE + +immutable +License: BSD-3-Clause +Repository: https://github.com/facebook/immutable-js +License File: immutable/LICENSE + +indent-string +License: MIT +Repository: https://github.com/sindresorhus/indent-string +License File: download/node_modules/indent-string/license + +indent-string +License: MIT +Repository: https://github.com/sindresorhus/indent-string +License File: indent-string/license + +indexes-of +License: MIT +Repository: https://github.com/dominictarr/indexes-of +License File: indexes-of/LICENSE + +indexof +License: MIT* + +inflight +License: ISC +Repository: https://github.com/isaacs/inflight +License File: inflight/LICENSE + +inherit +License: MIT +Repository: https://github.com/dfilatov/node-inherit + +inherits +License: ISC* +Repository: https://github.com/isaacs/inherits +License File: globule/node_modules/inherits/LICENSE + +inherits +License: ISC +Repository: https://github.com/isaacs/inherits +License File: inherits/LICENSE + +ini +License: ISC +Repository: https://github.com/isaacs/ini +License File: ini/LICENSE + +inquirer1 +License: MIT +Repository: https://github.com/sboudrias/Inquirer.js + +interpret +License: MIT +Repository: https://github.com/tkellen/node-interpret +License File: interpret/LICENSE + +invariant +License: BSD-3-Clause +Repository: https://github.com/zertosh/invariant + +invert-kv +License: MIT +Repository: https://github.com/sindresorhus/invert-kv + +ip-regex +License: MIT +Repository: https://github.com/sindresorhus/ip-regex +License File: ip-regex/license + +ipaddr.js +License: MIT +Repository: https://github.com/whitequark/ipaddr.js +License File: ipaddr.js/LICENSE + +is-absolute +License: MIT +Repository: https://github.com/jonschlinkert/is-absolute +License File: is-absolute/LICENSE + +is-absolute-url +License: MIT +Repository: https://github.com/sindresorhus/is-absolute-url +License File: is-absolute-url/license + +is-arrayish +License: MIT +Repository: https://github.com/qix-/node-is-arrayish +License File: is-arrayish/LICENSE + +is-binary-path +License: MIT +Repository: https://github.com/sindresorhus/is-binary-path +License File: is-binary-path/license + +is-buffer +License: MIT +Repository: https://github.com/feross/is-buffer +License File: is-buffer/LICENSE + +is-builtin-module +License: MIT +Repository: https://github.com/sindresorhus/is-builtin-module +License File: is-builtin-module/license + +is-bzip2 +License: MIT +Repository: https://github.com/kevva/is-bzip2 + +is-dotfile +License: MIT +Repository: https://github.com/jonschlinkert/is-dotfile +License File: is-dotfile/LICENSE + +is-equal-shallow +License: MIT +Repository: https://github.com/jonschlinkert/is-equal-shallow +License File: is-equal-shallow/LICENSE + +is-extendable +License: MIT +Repository: https://github.com/jonschlinkert/is-extendable +License File: is-extendable/LICENSE + +is-extglob +License: MIT +Repository: https://github.com/jonschlinkert/is-extglob +License File: is-extglob/LICENSE + +is-finite +License: MIT +Repository: https://github.com/sindresorhus/is-finite +License File: is-finite/license + +is-fullwidth-code-point +License: MIT +Repository: https://github.com/sindresorhus/is-fullwidth-code-point +License File: is-fullwidth-code-point/license + +is-glob +License: MIT +Repository: https://github.com/jonschlinkert/is-glob +License File: is-glob/LICENSE + +is-gzip +License: MIT +Repository: https://github.com/kevva/is-gzip + +is-integer +License: WTFPL +Repository: https://github.com/parshap/js-is-integer +License File: is-integer/LICENSE + +is-my-json-valid3 +License: MIT +Repository: https://github.com/mafintosh/is-my-json-valid +License File: is-my-json-valid/LICENSE + +is-natural-number +License: MIT +Repository: https://github.com/shinnn/is-natural-number.js +License File: is-natural-number/LICENSE + +is-number +License: MIT +Repository: https://github.com/jonschlinkert/is-number +License File: is-number/LICENSE + +is-path-cwd +License: MIT +Repository: https://github.com/sindresorhus/is-path-cwd + +is-path-global +License: MIT +Repository: https://github.com/kevva/is-path-global +License File: is-path-global/license + +is-path-in-cwd +License: MIT +Repository: https://github.com/sindresorhus/is-path-in-cwd + +is-path-inside +License: MIT +Repository: https://github.com/sindresorhus/is-path-inside + +is-plain-obj +License: MIT +Repository: https://github.com/sindresorhus/is-plain-obj +License File: is-plain-obj/license + +is-primitive +License: MIT +Repository: https://github.com/jonschlinkert/is-primitive +License File: is-primitive/LICENSE + +is-property +License: MIT +Repository: https://github.com/mikolalysenko/is-property +License File: is-property/LICENSE + +is-relative +License: MIT +Repository: https://github.com/jonschlinkert/is-relative +License File: is-relative/LICENSE-MIT + +is-resolvable +License: MIT +Repository: https://github.com/shinnn/is-resolvable +License File: is-resolvable/LICENSE + +is-svg +License: MIT +Repository: https://github.com/sindresorhus/is-svg +License File: is-svg/license + +is-tar +License: MIT +Repository: https://github.com/kevva/is-tar + +is-typedarray +License: MIT +Repository: https://github.com/hughsk/is-typedarray +License File: is-typedarray/LICENSE.md + +is-utf8 +License: BSD +Repository: https://github.com/wayfind/is-utf8 + +is-zip +License: MIT +Repository: https://github.com/kevva/is-zip + +isarray +License: MIT +Repository: https://github.com/juliangruber/isarray + +isarray +License: MIT +Repository: https://github.com/juliangruber/isarray + +isobject +License: MIT +Repository: https://github.com/jonschlinkert/isobject +License File: isobject/LICENSE + +isstream +License: MIT +Repository: https://github.com/rvagg/isstream +License File: isstream/LICENSE.md + +istanbul2 +License: BSD-3-Clause +Repository: https://github.com/gotwarlost/istanbul +License File: istanbul/LICENSE + +jest-cli +License: BSD-3-Clause +Repository: https://github.com/facebook/jest +License File: jest-cli/LICENSE + +jodid25519 +License: MIT +Repository: https://github.com/meganz/jodid25519 +License File: jodid25519/LICENSE + +js-base64 +License: BSD +Repository: https://github.com/dankogai/js-base64 +License File: js-base64/LICENSE.md + +js-tokens +License: MIT +Repository: https://github.com/lydell/js-tokens +License File: js-tokens/LICENSE + +js-yaml +License: MIT +Repository: https://github.com/nodeca/js-yaml +License File: eslint/node_modules/js-yaml/LICENSE + +js-yaml +License: MIT +Repository: https://github.com/nodeca/js-yaml +License File: js-yaml/LICENSE + +jsbn +License: BSD +Repository: https://github.com/andyperlitch/jsbn +License File: jsbn/LICENSE + +jsdom +License: MIT +Repository: https://github.com/tmpvar/jsdom +License File: jsdom/LICENSE.txt + +jsesc +License: MIT +Repository: https://github.com/mathiasbynens/jsesc +License File: jsesc/LICENSE-MIT.txt + +json-schema +licenses +│ 0: AFLv2.1 +│ 1: BSD +Repository: https://github.com/kriszyp/json-schema + +json-stable-stringify +License: MIT +Repository: https://github.com/substack/json-stable-stringify +License File: json-stable-stringify/LICENSE + +json-stringify-safe +License: ISC +Repository: https://github.com/isaacs/json-stringify-safe +License File: json-stringify-safe/LICENSE + +json5 +License: MIT +Repository: https://github.com/aseemk/json5 + +jsonfile +License: MIT +Repository: https://github.com/jprichardson/node-jsonfile +License File: jsonfile/LICENSE + +jsonify +License: Public Domain +Repository: https://github.com/substack/jsonify + +jsonpointer +License: MIT +Repository: https://github.com/janl/node-jsonpointer + +jsprim +License: MIT +Repository: https://github.com/davepacheco/node-jsprim +License File: jsprim/LICENSE + +jstransform0 +License: Apache-2.0 +Repository: https://github.com/facebook/jstransform +License File: jstransform/LICENSE + +kind-of +License: MIT +Repository: https://github.com/jonschlinkert/kind-of +License File: align-text/node_modules/kind-of/LICENSE + +kind-of +License: MIT +Repository: https://github.com/jonschlinkert/kind-of +License File: kind-of/LICENSE + +klaw +License: MIT +Repository: https://github.com/jprichardson/node-klaw + +lazy-cache +License: MIT +Repository: https://github.com/jonschlinkert/lazy-cache +License File: lazy-cache/LICENSE + +lcid +License: MIT +Repository: https://github.com/sindresorhus/lcid +License File: lcid/license + +left-pad +License: BSD +Repository: https://github.com/azer/left-pad + +less +License: Apache-2.0 +Repository: https://github.com/less/less.js +License File: less/LICENSE + +less-loader +License: MIT +Repository: https://github.com/webpack/less-loader +License File: less-loader/LICENSE + +levn +License: MIT +Repository: https://github.com/gkz/levn +License File: levn/LICENSE + +line-numbers +License: MIT +Repository: https://github.com/lydell/line-numbers +License File: line-numbers/LICENSE + +lnfs +License: MIT +Repository: https://github.com/kevva/lnfs +License File: lnfs/license + +load-json-file +License: MIT +Repository: https://github.com/sindresorhus/load-json-file +License File: load-json-file/license + +loader-utils2 +License: MIT +Repository: https://github.com/webpack/loader-utils +License File: loader-utils/LICENSE + +lodash +License: MIT +Repository: https://github.com/lodash/lodash +License File: globule/node_modules/lodash/LICENSE.txt + +lodash1 +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash/LICENSE + +lodash._arraycopy +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._arraycopy/LICENSE.txt + +lodash._arrayeach +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._arrayeach/LICENSE.txt + +lodash._arraymap +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._arraymap/LICENSE.txt + +lodash._baseassign +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._baseassign/LICENSE.txt + +lodash._baseclone +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._baseclone/LICENSE + +lodash._basecopy +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._basecopy/LICENSE.txt + +lodash._basedifference +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._basedifference/LICENSE + +lodash._baseflatten +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._baseflatten/LICENSE + +lodash._basefor +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._basefor/LICENSE.txt + +lodash._baseindexof +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._baseindexof/LICENSE.txt + +lodash._basetostring +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._basetostring/LICENSE + +lodash._bindcallback +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._bindcallback/LICENSE.txt + +lodash._cacheindexof +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._cacheindexof/LICENSE.txt + +lodash._createassigner +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._createassigner/LICENSE.txt + +lodash._createcache +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._createcache/LICENSE + +lodash._createcompounder +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._createcompounder/LICENSE.txt + +lodash._createpadding +License: MIT +Repository: https://github.com/lodash/lodash +License File: fsevents/node_modules/lodash._createpadding/LICENSE + +lodash._getnative +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._getnative/LICENSE + +lodash._isiterateecall +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._isiterateecall/LICENSE.txt + +lodash._pickbyarray +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._pickbyarray/LICENSE.txt + +lodash._pickbycallback +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash._pickbycallback/LICENSE.txt + +lodash.assign +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.assign/LICENSE.txt + +lodash.camelcase +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.camelcase/LICENSE.txt + +lodash.clonedeep +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.clonedeep/LICENSE + +lodash.deburr +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.deburr/LICENSE.txt + +lodash.isarguments +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.isarguments/LICENSE + +lodash.isarray +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.isarray/LICENSE + +lodash.isplainobject +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.isplainobject/LICENSE + +lodash.istypedarray +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.istypedarray/LICENSE.txt + +lodash.keys +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.keys/LICENSE + +lodash.keysin +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.keysin/LICENSE.txt + +lodash.merge +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.merge/LICENSE + +lodash.omit +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.omit/LICENSE.txt + +lodash.pad +License: MIT +Repository: https://github.com/lodash/lodash +License File: fsevents/node_modules/lodash.pad/LICENSE + +lodash.padleft +License: MIT +Repository: https://github.com/lodash/lodash +License File: fsevents/node_modules/lodash.padleft/LICENSE.txt + +lodash.padright +License: MIT +Repository: https://github.com/lodash/lodash +License File: fsevents/node_modules/lodash.padright/LICENSE.txt + +lodash.pick +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.pick/LICENSE.txt + +lodash.repeat +License: MIT +Repository: https://github.com/lodash/lodash +License File: fsevents/node_modules/lodash.repeat/LICENSE + +lodash.restparam +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.restparam/LICENSE.txt + +lodash.toplainobject +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.toplainobject/LICENSE.txt + +lodash.words +License: MIT +Repository: https://github.com/lodash/lodash +License File: lodash.words/LICENSE + +log-symbols +License: MIT +Repository: https://github.com/sindresorhus/log-symbols +License File: log-symbols/license + +logalot +License: MIT +Repository: https://github.com/imagemin/logalot +License File: logalot/LICENSE.md + +longest +License: MIT +Repository: https://github.com/jonschlinkert/longest +License File: longest/LICENSE + +loose-envify +License: MIT +Repository: https://github.com/zertosh/loose-envify + +loud-rejection +License: MIT +Repository: https://github.com/sindresorhus/loud-rejection +License File: loud-rejection/license + +lpad +License: MIT +Repository: https://github.com/sindresorhus/lpad +License File: lpad/license + +lpad-align +License: MIT +Repository: https://github.com/kevva/lpad-align +License File: lpad-align/license + +lru-cache +License: ISC +Repository: https://github.com/isaacs/node-lru-cache +License File: lru-cache/LICENSE + +makeerror1 +License: BSD-3-Clause +Repository: https://github.com/daaku/nodejs-makeerror +License File: makeerror/license + +map-obj +License: MIT +Repository: https://github.com/sindresorhus/map-obj +License File: map-obj/license + +media-typer +License: MIT +Repository: https://github.com/jshttp/media-typer +License File: media-typer/LICENSE + +memory-fs +License: MIT +Repository: https://github.com/webpack/memory-fs + +memory-fs +License: MIT +Repository: https://github.com/webpack/memory-fs + +meow +License: MIT +Repository: https://github.com/sindresorhus/meow +License File: download/node_modules/meow/license + +meow +License: MIT +Repository: https://github.com/sindresorhus/meow +License File: meow/license + +merge +License: MIT +Repository: https://github.com/yeikos/js.merge +License File: merge/LICENSE + +merge-descriptors +License: MIT +Repository: https://github.com/component/merge-descriptors +License File: merge-descriptors/LICENSE + +methods +License: MIT +Repository: https://github.com/jshttp/methods +License File: methods/LICENSE + +micromatch +License: MIT +Repository: https://github.com/jonschlinkert/micromatch +License File: micromatch/LICENSE + +mime +License: MIT +Repository: https://github.com/broofa/node-mime +License File: mime/LICENSE + +mime-db0 +License: MIT +Repository: https://github.com/jshttp/mime-db +License File: mksnapshot/node_modules/mime-db/LICENSE + +mime-db0 +License: MIT +Repository: https://github.com/jshttp/mime-db +License File: fsevents/node_modules/mime-db/LICENSE + +mime-db0 +License: MIT +Repository: https://github.com/jshttp/mime-db +License File: mime-db/LICENSE + +mime-types4 +License: MIT +Repository: https://github.com/jshttp/mime-types +License File: mksnapshot/node_modules/mime-types/LICENSE + +mime-types +License: MIT +Repository: https://github.com/jshttp/mime-types +License File: fsevents/node_modules/mime-types/LICENSE + +mime-types +License: MIT +Repository: https://github.com/jshttp/mime-types +License File: mime-types/LICENSE + +min-document0 +License: MIT +Repository: https://github.com/Raynos/min-document +License File: min-document/LICENCE + +minimatch4 +License: MIT +Repository: https://github.com/isaacs/minimatch +License File: globule/node_modules/minimatch/LICENSE + +minimatch0 +License: ISC +Repository: https://github.com/isaacs/minimatch +License File: minimatch/LICENSE + +minimatch +License: MIT +Repository: https://github.com/isaacs/minimatch +License File: asar/node_modules/minimatch/LICENSE + +minimatch +License: ISC +Repository: https://github.com/isaacs/minimatch +License File: eslint/node_modules/minimatch/LICENSE + +minimist0 +License: MIT +Repository: https://github.com/substack/minimist +License File: optimist/node_modules/minimist/LICENSE + +minimist +License: MIT +Repository: https://github.com/substack/minimist +License File: mkdirp/node_modules/minimist/LICENSE + +minimist +License: MIT +Repository: https://github.com/substack/minimist +License File: minimist/LICENSE + +mkdirp +License: MIT +Repository: https://github.com/substack/node-mkdirp +License File: extract-zip/node_modules/mkdirp/LICENSE + +mkdirp +License: MIT +Repository: https://github.com/substack/node-mkdirp +License File: mkdirp/LICENSE + +mkpath +License: MIT +Repository: https://github.com/jrajav/mkpath +License File: mkpath/LICENSE + +mksnapshot +License: MIT +Repository: https://github.com/atom/node-mksnapshot +License File: mksnapshot/LICENSE.md + +ms +License: MIT* +Repository: https://github.com/guille/ms.js +License File: ms/LICENSE + +mute-stream +License: ISC +Repository: https://github.com/isaacs/mute-stream +License File: mute-stream/LICENSE + +mv +License: MIT +Repository: https://github.com/andrewrk/node-mv +License File: mv/LICENSE + +nan +License: MIT +Repository: https://github.com/nodejs/nan +License File: nan/LICENSE.md + +ncp +License: MIT +Repository: https://github.com/AvianFlu/ncp +License File: ncp/LICENSE.md + +negotiator +License: MIT +Repository: https://github.com/jshttp/negotiator +License File: negotiator/LICENSE + +neo-async +License: MIT +Repository: https://github.com/suguru03/neo-async +License File: neo-async/LICENSE + +node-haste +License: Apache* +Repository: https://github.com/facebook/node-haste +License File: node-haste/LICENSE + +node-int64 +License: MIT +Repository: https://github.com/broofa/node-int64 +License File: node-int64/LICENSE + +node-libs-browser +License: MIT +Repository: https://github.com/webpack/node-libs-browser + +node-pre-gyp7 +License: BSD +Repository: https://github.com/mapbox/node-pre-gyp +License File: fsevents/node_modules/node-pre-gyp/LICENSE + +node-uuid +License: MIT +Repository: https://github.com/broofa/node-uuid +License File: node-uuid/LICENSE.md + +nopt0 +License: MIT +Repository: https://github.com/isaacs/nopt +License File: touch/node_modules/nopt/LICENSE + +nopt +License: ISC +Repository: https://github.com/npm/nopt +License File: nopt/LICENSE + +normalize-package-data +License: BSD-2-Clause +Repository: https://github.com/npm/normalize-package-data +License File: normalize-package-data/LICENSE + +normalize-path +License: MIT +Repository: https://github.com/jonschlinkert/normalize-path +License File: normalize-path/LICENSE + +normalize-range +License: MIT +Repository: https://github.com/jamestalmage/normalize-range +License File: normalize-range/license + +normalize-url +License: MIT +Repository: https://github.com/sindresorhus/normalize-url +License File: normalize-url/license + +npm-installed +License: MIT +Repository: https://github.com/kevva/npm-installed + +npm-path +License: MIT +Repository: https://github.com/timoxley/npm-path +License File: npm-path/LICENSE + +npm-which +License: MIT +Repository: https://github.com/timoxley/npm-which +License File: npm-which/LICENSE + +npmlog +License: ISC +Repository: https://github.com/npm/npmlog +License File: fsevents/node_modules/npmlog/LICENSE + +nugget +License: BSD +Repository: https://github.com/maxogden/nugget + +num2fraction +License: MIT +Repository: https://github.com/yisibl/num2fraction +License File: num2fraction/LICENSE + +number-is-nan +License: MIT +Repository: https://github.com/sindresorhus/number-is-nan +License File: number-is-nan/license + +nwmatcher +License: MIT +Repository: https://github.com/dperini/nwmatcher +License File: nwmatcher/LICENSE + +oauth-sign +License: Apache* +Repository: https://github.com/mikeal/oauth-sign +License File: mksnapshot/node_modules/oauth-sign/LICENSE + +oauth-sign +License: Apache-2.0 +Repository: https://github.com/mikeal/oauth-sign +License File: oauth-sign/LICENSE + +object-assign +License: MIT +Repository: https://github.com/sindresorhus/object-assign +License File: download-status/node_modules/object-assign/license + +object-assign +License: MIT +Repository: https://github.com/sindresorhus/object-assign +License File: object-assign/license + +object-keys +License: MIT +Repository: https://github.com/ljharb/object-keys + +object.omit +License: MIT +Repository: https://github.com/jonschlinkert/object.omit +License File: object.omit/LICENSE + +oculus-client +License: UNKNOWN + +on-finished +License: MIT +Repository: https://github.com/jshttp/on-finished +License File: on-finished/LICENSE + +once +License: BSD +Repository: https://github.com/isaacs/once +License File: fsevents/node_modules/once/LICENSE + +once +License: ISC +Repository: https://github.com/isaacs/once +License File: once/LICENSE + +onetime +License: MIT +Repository: https://github.com/sindresorhus/onetime + +optimist +License: MIT/X11 +Repository: https://github.com/substack/node-optimist +License File: optimist/LICENSE + +optionator +License: MIT +Repository: https://github.com/gkz/optionator +License File: escodegen/node_modules/optionator/LICENSE + +optionator +License: MIT +Repository: https://github.com/gkz/optionator +License File: optionator/LICENSE + +ordered-read-streams +License: MIT +Repository: https://github.com/armed/ordered-read-streams +License File: ordered-read-streams/LICENSE + +os-browserify +License: MIT +Repository: https://github.com/drewyoung1/os-browserify +License File: os-browserify/LICENSE + +os-filter-obj +License: MIT +Repository: https://github.com/kevva/os-filter-obj +License File: os-filter-obj/license + +os-homedir +License: MIT +Repository: https://github.com/sindresorhus/os-homedir +License File: os-homedir/license + +os-locale +License: MIT +Repository: https://github.com/sindresorhus/os-locale +License File: os-locale/license + +os-shim +License: MIT +Repository: https://github.com/h2non/node-os-shim +License File: os-shim/LICENSE + +os-tmpdir +License: MIT +Repository: https://github.com/sindresorhus/os-tmpdir +License File: os-tmpdir/license + +output-file-sync +License: MIT +Repository: https://github.com/shinnn/output-file-sync +License File: output-file-sync/LICENSE + +pako +License: MIT +Repository: https://github.com/nodeca/pako +License File: pako/LICENSE + +parse-glob +License: MIT +Repository: https://github.com/jonschlinkert/parse-glob +License File: parse-glob/LICENSE + +parse-json +License: MIT +Repository: https://github.com/sindresorhus/parse-json +License File: parse-json/license + +parse5 +License: MIT +Repository: https://github.com/inikulin/parse5 +License File: parse5/LICENSE + +parseurl +License: MIT +Repository: https://github.com/expressjs/parseurl +License File: parseurl/LICENSE + +path-browserify +License: MIT +Repository: https://github.com/substack/path-browserify +License File: path-browserify/LICENSE + +path-exists +License: MIT +Repository: https://github.com/sindresorhus/path-exists +License File: path-exists/license + +path-exists +License: MIT +Repository: https://github.com/sindresorhus/path-exists +License File: find-up/node_modules/path-exists/license + +path-is-absolute +License: MIT +Repository: https://github.com/sindresorhus/path-is-absolute +License File: path-is-absolute/license + +path-is-inside +License: WTFPL +Repository: https://github.com/domenic/path-is-inside +License File: path-is-inside/LICENSE.txt + +path-to-regexp +License: MIT +Repository: https://github.com/component/path-to-regexp +License File: path-to-regexp/LICENSE + +path-type +License: MIT +Repository: https://github.com/sindresorhus/path-type +License File: path-type/license + +pbkdf2-compat +License: MIT +Repository: https://github.com/dcousens/pbkdf2-compat +License File: pbkdf2-compat/LICENSE + +pend +License: MIT +Repository: https://github.com/andrewrk/node-pend +License File: pend/LICENSE + +pify +License: MIT +Repository: https://github.com/sindresorhus/pify +License File: pify/license + +pinkie +License: MIT +Repository: https://github.com/floatdrop/pinkie +License File: pinkie/license + +pinkie-promise +License: MIT +Repository: https://github.com/floatdrop/pinkie-promise +License File: pinkie-promise/license + +plist +License: MIT +Repository: https://github.com/TooTallNate/node-plist +License File: plist/LICENSE + +postcss6 +License: MIT +Repository: https://github.com/postcss/postcss +License File: autoprefixer-core/node_modules/postcss/LICENSE + +postcss3 +License: MIT +Repository: https://github.com/postcss/postcss +License File: postcss/LICENSE + +postcss-calc +License: MIT +Repository: https://github.com/postcss/postcss-calc +License File: postcss-calc/LICENSE + +postcss-cli +License: MIT +Repository: https://github.com/code42day/postcss-cli + +postcss-colormin +License: MIT +Repository: https://github.com/ben-eb/postcss-colormin +License File: postcss-colormin/LICENSE-MIT + +postcss-convert-values +License: MIT +Repository: https://github.com/ben-eb/postcss-convert-values +License File: postcss-convert-values/LICENSE-MIT + +postcss-discard-comments +License: MIT +Repository: https://github.com/ben-eb/postcss-discard-comments +License File: postcss-discard-comments/LICENSE-MIT + +postcss-discard-duplicates +License: MIT +Repository: https://github.com/ben-eb/postcss-discard-duplicates +License File: postcss-discard-duplicates/LICENSE-MIT + +postcss-discard-empty +License: MIT +Repository: https://github.com/ben-eb/postcss-discard-empty +License File: postcss-discard-empty/LICENSE-MIT + +postcss-discard-unused +License: MIT +Repository: https://github.com/ben-eb/postcss-discard-unused +License File: postcss-discard-unused/LICENSE-MIT + +postcss-filter-plugins +License: MIT +Repository: https://github.com/postcss/postcss-filter-plugins +License File: postcss-filter-plugins/LICENSE-MIT + +postcss-merge-idents +License: MIT +Repository: https://github.com/ben-eb/postcss-merge-idents +License File: postcss-merge-idents/LICENSE-MIT + +postcss-merge-longhand +License: MIT +Repository: https://github.com/ben-eb/postcss-merge-longhand +License File: postcss-merge-longhand/LICENSE-MIT + +postcss-merge-rules +License: MIT +Repository: https://github.com/ben-eb/postcss-merge-rules +License File: postcss-merge-rules/LICENSE-MIT + +postcss-message-helpers +License: MIT +Repository: https://github.com/MoOx/postcss-message-helpers +License File: postcss-message-helpers/LICENSE + +postcss-minify-font-values +License: MIT +Repository: https://github.com/TrySound/postcss-minify-font-values +License File: postcss-minify-font-values/LICENSE + +postcss-minify-gradients +License: MIT +Repository: https://github.com/ben-eb/postcss-minify-gradients +License File: postcss-minify-gradients/LICENSE-MIT + +postcss-minify-params +License: MIT +Repository: https://github.com/trysound/postcss-minify-params +License File: postcss-minify-params/LICENSE + +postcss-minify-selectors +License: MIT +Repository: https://github.com/ben-eb/postcss-minify-selectors +License File: postcss-minify-selectors/LICENSE-MIT + +postcss-modules-extract-imports +License: ISC +Repository: https://github.com/css-modules/postcss-modules-extract-imports + +postcss-modules-local-by-default +License: MIT +Repository: https://github.com/css-modules/postcss-modules-local-by-default +License File: postcss-modules-local-by-default/LICENSE + +postcss-modules-scope +License: ISC +Repository: https://github.com/geelen/postcss-modules-scope + +postcss-modules-values +License: ISC +Repository: https://github.com/css-modules/postcss-modules-constants + +postcss-normalize-charset +License: MIT +Repository: https://github.com/trysound/postcss-charset +License File: postcss-normalize-charset/LICENSE + +postcss-normalize-url +License: MIT +Repository: https://github.com/ben-eb/postcss-normalize-url +License File: postcss-normalize-url/LICENSE-MIT + +postcss-ordered-values +License: MIT +Repository: https://github.com/ben-eb/postcss-ordered-values +License File: postcss-ordered-values/LICENSE-MIT + +postcss-reduce-idents +License: MIT +Repository: https://github.com/ben-eb/postcss-reduce-idents +License File: postcss-reduce-idents/LICENSE-MIT + +postcss-reduce-transforms +License: MIT +Repository: https://github.com/ben-eb/postcss-reduce-transforms +License File: postcss-reduce-transforms/LICENSE-MIT + +postcss-selector-parser +License: MIT +Repository: https://github.com/postcss/postcss-selector-parser +License File: postcss-selector-parser/LICENSE-MIT + +postcss-svgo +License: MIT +Repository: https://github.com/ben-eb/postcss-svgo +License File: postcss-svgo/LICENSE-MIT + +postcss-unique-selectors +License: MIT +Repository: https://github.com/ben-eb/postcss-unique-selectors +License File: postcss-unique-selectors/LICENSE-MIT + +postcss-value-parser +License: MIT +Repository: https://github.com/TrySound/postcss-value-parser +License File: postcss-value-parser/LICENSE + +postcss-zindex +License: MIT +Repository: https://github.com/ben-eb/postcss-zindex +License File: postcss-zindex/LICENSE-MIT + +prelude-ls +License: MIT +Repository: https://github.com/gkz/prelude-ls +License File: prelude-ls/LICENSE + +prepend-http +License: MIT +Repository: https://github.com/sindresorhus/prepend-http +License File: prepend-http/license + +preserve +License: MIT +Repository: https://github.com/jonschlinkert/preserve +License File: preserve/LICENSE + +pretty-bytes +License: MIT +Repository: https://github.com/sindresorhus/pretty-bytes +License File: pretty-bytes/license + +private +License: MIT +Repository: https://github.com/benjamn/private +License File: private/LICENSE + +process2 +License: MIT +Repository: https://github.com/shtylman/node-process +License File: process/LICENSE + +process +License: MIT* +Repository: https://github.com/shtylman/node-process +License File: global/node_modules/process/LICENSE + +process-nextick-args +License: MIT +Repository: https://github.com/calvinmetcalf/process-nextick-args +License File: process-nextick-args/license.md + +progress +License: MIT* +Repository: https://github.com/visionmedia/node-progress +License File: progress/LICENSE + +progress-stream +License: BSD-2-Clause +Repository: https://github.com/freeall/progress-stream +License File: progress-stream/LICENSE + +promise +License: MIT +Repository: https://github.com/then/promise +License File: less/node_modules/promise/LICENSE + +promise +License: MIT +Repository: https://github.com/then/promise +License File: promise/LICENSE + +proxy-addr0 +License: MIT +Repository: https://github.com/jshttp/proxy-addr +License File: proxy-addr/LICENSE + +prr +License: MIT +Repository: https://github.com/rvagg/prr +License File: prr/LICENSE + +punycode +License: MIT +Repository: https://github.com/bestiejs/punycode.js +License File: url/node_modules/punycode/LICENSE-MIT.txt + +punycode +License: MIT +Repository: https://github.com/bestiejs/punycode.js +License File: punycode/LICENSE-MIT.txt + +q +License: MIT +Repository: https://github.com/kriskowal/q +License File: q/LICENSE + +qs +License: BSD +Repository: https://github.com/hapijs/qs +License File: mksnapshot/node_modules/qs/LICENSE + +qs +License: BSD-3-Clause +Repository: https://github.com/hapijs/qs +License File: express/node_modules/qs/LICENSE + +qs +License: BSD-3-Clause +Repository: https://github.com/hapijs/qs +License File: qs/LICENSE + +query-string +License: MIT +Repository: https://github.com/sindresorhus/query-string +License File: query-string/license + +querystring +License: MIT +Repository: https://github.com/Gozala/querystring +License File: querystring/License.md + +querystring-es3 +License: MIT +Repository: https://github.com/mike-spainhower/querystring +License File: querystring-es3/License.md + +randomatic +License: MIT +Repository: https://github.com/jonschlinkert/randomatic +License File: randomatic/LICENSE + +range-parser +License: MIT +Repository: https://github.com/jshttp/range-parser +License File: range-parser/LICENSE + +rc +licenses +│ 0: Apache2 +│ 1: BSD +│ 2: MIT +Repository: https://github.com/dominictarr/rc +License File: download/node_modules/rc/LICENSE.MIT + +rc +License: (BSD-2-Clause OR MIT OR Apache-2.0) +Repository: https://github.com/dominictarr/rc +License File: rc/LICENSE.MIT + +rcedit +License: MIT +Repository: https://github.com/atom/node-rcedit +License File: rcedit/LICENSE + +react5 +License: BSD-3-Clause +Repository: https://github.com/facebook/react +License File: react/LICENSE + +react-addons-test-utils5 +License: BSD-3-Clause +Repository: https://github.com/facebook/react +License File: react-addons-test-utils/LICENSE + +react-crop +License: MIT +Repository: https://github.com/instructure-react/react-crop + +react-deep-force-update +License: MIT +Repository: https://github.com/gaearon/react-deep-force-update +License File: react-deep-force-update/LICENSE.md + +react-dom5 +License: BSD-3-Clause +Repository: https://github.com/facebook/react +License File: react-dom/LICENSE + +react-overlays +License: MIT +Repository: https://github.com/react-bootstrap/react-overlays +License File: react-overlays/LICENSE + +react-prop-types +License: MIT +Repository: https://github.com/react-bootstrap/react-prop-types +License File: react-prop-types/LICENSE + +react-proxy +License: MIT +Repository: https://github.com/gaearon/react-proxy + +react-relay +License: BSD-3-Clause +Repository: https://github.com/facebook/relay +License File: react-relay/LICENSE + +react-router +License: MIT +Repository: https://github.com/rackt/react-router +License File: react-router/LICENSE.md + +react-router-relay +License: MIT +Repository: https://github.com/relay-tools/react-router-relay +License File: react-router-relay/LICENSE.md + +react-static-container +License: BSD-3-Clause +Repository: https://github.com/reactjs/react-static-container +License File: react-static-container/LICENSE + +react-transform-catch-errors +License: MIT +Repository: https://github.com/gaearon/react-transform-catch-errors + +react-transform-hmr +License: MIT +Repository: https://github.com/gaearon/react-transform-hmr + +read-file-stdin +License: MIT +Repository: https://github.com/ianstormtaylor/read-file-stdin + +read-json-sync +License: MIT +Repository: https://github.com/shinnn/read-json-sync +License File: read-json-sync/LICENSE + +read-pkg +License: MIT +Repository: https://github.com/sindresorhus/read-pkg +License File: read-pkg/license + +read-pkg-up +License: MIT +Repository: https://github.com/sindresorhus/read-pkg-up +License File: read-pkg-up/license + +readable-stream3 +License: MIT +Repository: https://github.com/isaacs/readable-stream +License File: mksnapshot/node_modules/readable-stream/LICENSE + +readable-stream3 +License: MIT +Repository: https://github.com/isaacs/readable-stream +License File: decompress-zip/node_modules/readable-stream/LICENSE + +readable-stream +License: MIT +Repository: https://github.com/nodejs/readable-stream +License File: readable-stream/LICENSE + +readdirp +License: MIT +Repository: https://github.com/thlorenz/readdirp +License File: readdirp/LICENSE + +readline2 +License: MIT +Repository: https://github.com/sboudrias/readline2 + +recast39 +License: MIT +Repository: https://github.com/benjamn/recast +License File: recast/LICENSE + +redbox-react +License: MIT +Repository: https://github.com/KeywordBrain/redbox-react +License File: redbox-react/LICENSE.md + +redent +License: MIT +Repository: https://github.com/sindresorhus/redent +License File: redent/license + +reduce-css-calc +License: MIT +Repository: https://github.com/MoOx/reduce-css-calc +License File: reduce-css-calc/LICENSE + +reduce-function-call +License: MIT +Repository: https://github.com/MoOx/reduce-function-call +License File: reduce-function-call/LICENSE + +regenerate +License: MIT +Repository: https://github.com/mathiasbynens/regenerate +License File: regenerate/LICENSE-MIT.txt + +regex-cache +License: MIT +Repository: https://github.com/jonschlinkert/regex-cache +License File: regex-cache/LICENSE + +regexpu +License: MIT +Repository: https://github.com/mathiasbynens/regexpu +License File: regexpu/LICENSE-MIT.txt + +regjsgen +License: MIT +Repository: https://github.com/d10/regjsgen +License File: regjsgen/LICENSE.txt + +regjsparser +License: BSD +Repository: https://github.com/jviereck/regjsparser +License File: regjsparser/LICENSE.BSD + +repeat-element +License: MIT +Repository: https://github.com/jonschlinkert/repeat-element +License File: repeat-element/LICENSE + +repeat-string +License: MIT +Repository: https://github.com/jonschlinkert/repeat-string +License File: repeat-string/LICENSE + +repeating +License: MIT +Repository: https://github.com/sindresorhus/repeating +License File: repeating/license + +repeating +License: MIT +Repository: https://github.com/sindresorhus/repeating +License File: indent-string/node_modules/repeating/license + +request0 +License: Apache-2.0 +Repository: https://github.com/request/request +License File: mksnapshot/node_modules/request/LICENSE + +request0 +License: Apache-2.0 +Repository: https://github.com/request/request +License File: request/LICENSE + +resolve +License: MIT +Repository: https://github.com/substack/node-resolve +License File: resolve/LICENSE + +restore-cursor +License: MIT +Repository: https://github.com/sindresorhus/restore-cursor +License File: restore-cursor/license + +right-align +License: MIT +Repository: https://github.com/jonschlinkert/right-align +License File: right-align/LICENSE + +rimraf +License: MIT +Repository: https://github.com/isaacs/rimraf +License File: fsevents/node_modules/tar-pack/node_modules/rimraf/LICENSE + +rimraf +License: ISC +Repository: https://github.com/isaacs/rimraf +License File: rimraf/LICENSE + +ripemd160 +License: UNKNOWN +Repository: https://github.com/cryptocoinjs/ripemd160 + +run-async +License: MIT +Repository: https://github.com/SBoudrias/run-async +License File: run-async/LICENSE + +run-series +License: MIT +Repository: https://github.com/feross/run-series +License File: run-series/LICENSE + +rx-lite +License: Apache License, Version 2.0 +Repository: https://github.com/Reactive-Extensions/RxJS + +sane +License: MIT +Repository: https://github.com/amasad/sane + +sax +License: ISC +Repository: https://github.com/isaacs/sax-js +License File: sax/LICENSE-W3C.html + +seek-bzip +License: MIT +Repository: https://github.com/cscott/seek-bzip + +semver +License: ISC +Repository: https://github.com/npm/node-semver +License File: semver/LICENSE + +semver +License: ISC +Repository: https://github.com/npm/node-semver +License File: semver-truncate/node_modules/semver/LICENSE + +semver-regex +License: MIT +Repository: https://github.com/sindresorhus/semver-regex + +semver-truncate +License: MIT +Repository: https://github.com/sindresorhus/semver-truncate +License File: semver-truncate/license + +send0 +License: MIT +Repository: https://github.com/pillarjs/send +License File: send/LICENSE + +serve-static0 +License: MIT +Repository: https://github.com/expressjs/serve-static +License File: serve-static/LICENSE + +set-immediate-shim +License: MIT +Repository: https://github.com/sindresorhus/set-immediate-shim + +sha.js +License: MIT +Repository: https://github.com/dominictarr/sha.js +License File: sha.js/LICENSE + +shebang-regex +License: MIT +Repository: https://github.com/sindresorhus/shebang-regex +License File: shebang-regex/license + +shelljs +License: BSD* +Repository: https://github.com/arturadib/shelljs +License File: shelljs/LICENSE + +sigmund +License: ISC +Repository: https://github.com/isaacs/sigmund +License File: sigmund/LICENSE + +signal-exit +License: ISC +Repository: https://github.com/bcoe/signal-exit +License File: signal-exit/LICENSE.txt + +single-line-log +License: MIT* +Repository: https://github.com/freeall/single-line-log + +slash +License: MIT +Repository: https://github.com/sindresorhus/slash + +sntp +License: BSD +Repository: https://github.com/hueniverse/sntp +License File: sntp/LICENSE + +sort-keys +License: MIT +Repository: https://github.com/sindresorhus/sort-keys +License File: sort-keys/license + +source-list-map +License: MIT +Repository: https://github.com/webpack/source-list-map + +source-map1 +License: BSD +Repository: https://github.com/mozilla/source-map +License File: jstransform/node_modules/source-map/LICENSE + +source-map2 +License: BSD +Repository: https://github.com/mozilla/source-map +License File: source-map-support/node_modules/source-map/LICENSE + +source-map +License: BSD +Repository: https://github.com/mozilla/source-map +License File: escodegen/node_modules/source-map/LICENSE + +source-map +License: BSD-3-Clause +Repository: https://github.com/mozilla/source-map + +source-map +License: BSD-3-Clause +Repository: https://github.com/mozilla/source-map + +source-map-support0 +License: MIT +Repository: https://github.com/evanw/node-source-map-support +License File: source-map-support/LICENSE.md + +spawn-sync4 +License: MIT +Repository: https://github.com/ForbesLindesay/spawn-sync +License File: spawn-sync/LICENSE + +spdx-correct +License: Apache-2.0 +Repository: https://github.com/kemitchell/spdx-correct.js +License File: spdx-correct/LICENSE + +spdx-exceptions +License: CC-BY-3.0 +Repository: https://github.com/kemitchell/spdx-exceptions.json + +spdx-expression-parse +License: (MIT AND CC-BY-3.0) +Repository: https://github.com/kemitchell/spdx-expression-parse.js +License File: spdx-expression-parse/LICENSE + +spdx-license-ids +License: Unlicense +Repository: https://github.com/shinnn/spdx-license-ids +License File: spdx-license-ids/spdx-license-ids.json + +speedometer +License: MIT* +Repository: https://github.com/mafintosh/speedometer +License File: speedometer/LICENSE + +sprintf-js +License: BSD-3-Clause +Repository: https://github.com/alexei/sprintf.js +License File: sprintf-js/LICENSE + +squeak +License: MIT +Repository: https://github.com/kevva/squeak +License File: squeak/license + +sshpk +License: MIT +Repository: https://github.com/arekinath/node-sshpk +License File: fsevents/node_modules/sshpk/LICENSE + +sshpk +License: MIT +Repository: https://github.com/arekinath/node-sshpk +License File: sshpk/LICENSE + +stackframe +License: SEE LICENSE IN LICENSE +Repository: https://github.com/stacktracejs/stackframe +License File: stackframe/LICENSE + +statuses +License: MIT +Repository: https://github.com/jshttp/statuses +License File: statuses/LICENSE + +stream-browserify +License: MIT +Repository: https://github.com/substack/stream-browserify +License File: stream-browserify/LICENSE + +stream-combiner +License: MIT +Repository: https://github.com/dominictarr/stream-combiner +License File: stream-combiner/LICENSE + +strict-uri-encode +License: MIT +Repository: https://github.com/kevva/strict-uri-encode +License File: strict-uri-encode/license + +string-width +License: MIT +Repository: https://github.com/sindresorhus/string-width +License File: string-width/license + +string_decoder31 +License: MIT +Repository: https://github.com/rvagg/string_decoder +License File: string_decoder/LICENSE + +stringstream +License: MIT +Repository: https://github.com/mhart/StringStream +License File: stringstream/LICENSE.txt + +strip-ansi +License: MIT +Repository: https://github.com/sindresorhus/strip-ansi + +strip-ansi +License: MIT +Repository: https://github.com/sindresorhus/strip-ansi + +strip-ansi +License: MIT +Repository: https://github.com/sindresorhus/strip-ansi +License File: strip-ansi/license + +strip-bom +License: MIT +Repository: https://github.com/sindresorhus/strip-bom + +strip-bom +License: MIT +Repository: https://github.com/sindresorhus/strip-bom +License File: strip-bom/license + +strip-dirs +License: MIT +Repository: https://github.com/shinnn/node-strip-dirs +License File: strip-dirs/LICENSE + +strip-dirs +License: MIT +Repository: https://github.com/shinnn/node-strip-dirs +License File: decompress-targz/node_modules/strip-dirs/LICENSE + +strip-indent +License: MIT +Repository: https://github.com/sindresorhus/strip-indent +License File: strip-indent/license + +strip-json-comments +License: MIT +Repository: https://github.com/sindresorhus/strip-json-comments + +strip-json-comments +License: MIT +Repository: https://github.com/sindresorhus/strip-json-comments +License File: strip-json-comments/license + +style-loader0 +License: MIT +Repository: https://github.com/webpack/style-loader + +success-symbol +License: MIT +Repository: https://github.com/jonschlinkert/success-symbol +License File: success-symbol/LICENSE + +sum-up +License: MIT +Repository: https://github.com/shinnn/sum-up +License File: sum-up/LICENSE + +supports-color +License: MIT +Repository: https://github.com/sindresorhus/supports-color + +supports-color +License: MIT +Repository: https://github.com/chalk/supports-color +License File: supports-color/license + +supports-color +License: MIT +Repository: https://github.com/chalk/supports-color +License File: postcss/node_modules/supports-color/license + +svgo +License: MIT +Repository: https://github.com/svg/svgo +License File: svgo/LICENSE + +symbol-tree +License: MIT +Repository: https://github.com/jsdom/js-symbol-tree +License File: symbol-tree/LICENSE + +tapable0 +License: MIT +Repository: https://github.com/webpack/tapable + +tar +License: ISC +Repository: https://github.com/isaacs/node-tar +License File: fsevents/node_modules/tar/LICENSE + +tar-pack +License: BSD +Repository: https://github.com/ForbesLindesay/tar-pack +License File: fsevents/node_modules/tar-pack/LICENSE + +tar-stream +License: MIT +Repository: https://github.com/%3Amafintosh/tar-stream +License File: tar-stream/LICENSE + +tar-stream +License: MIT +Repository: https://github.com/mafintosh/tar-stream +License File: decompress-targz/node_modules/tar-stream/LICENSE + +text-table +License: MIT +Repository: https://github.com/substack/text-table +License File: text-table/LICENSE + +throttleit +License: MIT +Repository: https://github.com/component/throttle + +through +License: MIT +Repository: https://github.com/dominictarr/through +License File: through/LICENSE.MIT + +through2 +License: MIT +Repository: https://github.com/rvagg/through2 +License File: through2/LICENSE + +through2 +License: MIT +Repository: https://github.com/rvagg/through2 +License File: decompress-tar/node_modules/through2/LICENSE + +timers-browserify +License: MIT +Repository: https://github.com/jryans/timers-browserify +License File: timers-browserify/LICENSE.md + +tmpl +License: BSD-3-Clause +Repository: https://github.com/daaku/nodejs-tmpl +License File: tmpl/license + +to-fast-properties +License: MIT +Repository: https://github.com/sindresorhus/to-fast-properties +License File: to-fast-properties/license + +touch +License: ISC +Repository: https://github.com/isaacs/node-touch +License File: touch/LICENSE + +tough-cookie +License: BSD-3-Clause +Repository: https://github.com/SalesforceEng/tough-cookie +License File: tough-cookie/LICENSE + +tr46 +License: MIT +Repository: https://github.com/Sebmaster/tr46.js + +traverse +License: MIT/X11 +Repository: https://github.com/substack/js-traverse +License File: traverse/LICENSE + +trim-newlines +License: MIT +Repository: https://github.com/sindresorhus/trim-newlines +License File: trim-newlines/license + +trim-right +License: MIT +Repository: https://github.com/sindresorhus/trim-right +License File: trim-right/license + +tryit +License: MIT +Repository: https://github.com/HenrikJoreteg/tryit + +tty-browserify +License: MIT +Repository: https://github.com/substack/tty-browserify +License File: tty-browserify/LICENSE + +tunnel-agent +License: Apache* +Repository: https://github.com/mikeal/tunnel-agent +License File: fsevents/node_modules/tunnel-agent/LICENSE + +tunnel-agent +License: Apache-2.0 +Repository: https://github.com/mikeal/tunnel-agent +License File: tunnel-agent/LICENSE + +tweetnacl2 +License: CC0-1.0 +Repository: https://github.com/dchest/tweetnacl-js + +type-check +License: MIT +Repository: https://github.com/gkz/type-check +License File: type-check/LICENSE + +type-is0 +License: MIT +Repository: https://github.com/jshttp/type-is +License File: type-is/LICENSE + +typedarray +License: MIT +Repository: https://github.com/substack/typedarray +License File: typedarray/LICENSE + +ua-parser-js0 +licenses +│ 0: GPLv2 +│ 1: MIT +Repository: https://github.com/faisalman/ua-parser-js + +uglify-js +License: BSD-2-Clause +Repository: https://github.com/mishoo/UglifyJS2 +License File: uglify-js/LICENSE + +uglify-to-browserify +License: MIT +Repository: https://github.com/ForbesLindesay/uglify-to-browserify +License File: uglify-to-browserify/LICENSE + +uid-number +License: BSD +Repository: https://github.com/isaacs/uid-number +License File: fsevents/node_modules/uid-number/LICENCE + +underscore +License: MIT* +Repository: https://github.com/documentcloud/underscore +License File: underscore/LICENSE + +underscore.string +License: MIT +Repository: https://github.com/epeli/underscore.string + +uniq +License: MIT +Repository: https://github.com/mikolalysenko/uniq +License File: uniq/LICENSE + +uniqid +License: MIT +Repository: https://github.com/adamhalasz/uniqid + +uniqs +License: MIT +Repository: https://github.com/fgnass/uniqs + +unique-stream +License: BSD +Repository: https://github.com/eugeneware/unique-stream +License File: unique-stream/LICENSE + +unpipe +License: MIT +Repository: https://github.com/stream-utils/unpipe +License File: unpipe/LICENSE + +url3 +License: MIT +Repository: https://github.com/defunctzombie/node-url +License File: url/LICENSE + +url-regex +License: MIT +Repository: https://github.com/kevva/url-regex +License File: url-regex/license + +user-home +License: MIT +Repository: https://github.com/sindresorhus/user-home +License File: user-home/license + +user-home +License: MIT +Repository: https://github.com/sindresorhus/user-home +License File: eslint/node_modules/user-home/license + +util3 +License: MIT +Repository: https://github.com/defunctzombie/node-util +License File: util/LICENSE + +util-deprecate +License: MIT +Repository: https://github.com/TooTallNate/util-deprecate +License File: util-deprecate/LICENSE + +utils-merge +License: MIT +Repository: https://github.com/jaredhanson/utils-merge +License File: utils-merge/LICENSE + +v8flags0 +License: MIT +Repository: https://github.com/tkellen/node-v8flags +License File: v8flags/LICENSE + +validate-npm-package-license +License: Apache-2.0 +Repository: https://github.com/kemitchell/validate-npm-package-license.js +License File: validate-npm-package-license/LICENSE + +vary +License: MIT +Repository: https://github.com/jshttp/vary +License File: vary/LICENSE + +verror +License: MIT* +Repository: https://github.com/davepacheco/node-verror +License File: verror/LICENSE + +vinyl +License: MIT +Repository: https://github.com/wearefractal/vinyl +License File: vinyl/LICENSE + +vinyl-fs4 +License: MIT +Repository: https://github.com/wearefractal/vinyl-fs +License File: vinyl-fs/LICENSE + +vm-browserify +License: MIT +Repository: https://github.com/substack/vm-browserify +License File: vm-browserify/LICENSE + +walker +License: Apache-2.0 +Repository: https://github.com/daaku/nodejs-walker +License File: walker/LICENSE + +ware +License: MIT +Repository: https://github.com/segmentio/ware + +warning +License: BSD-2-Clause +Repository: https://github.com/r3dm/warning +License File: warning/LICENSE.md + +watch0 +License: Apache* +Repository: https://github.com/mikeal/watch +License File: watch/LICENSE + +watchpack +License: MIT +Repository: https://github.com/webpack/watchpack + +webidl-conversions +License: BSD-2-Clause +Repository: https://github.com/jsdom/webidl-conversions +License File: webidl-conversions/LICENSE.md + +webpack9 +License: MIT +Repository: https://github.com/webpack/webpack +License File: webpack/LICENSE + +webpack-core +License: MIT +Repository: https://github.com/webpack/core + +webpack-dev-middleware +License: MIT +Repository: https://github.com/webpack/webpack-dev-middleware + +webpack-hot-middleware +License: MIT +Repository: https://github.com/glenjamin/webpack-hot-middleware + +webpack-target-electron-renderer +License: MIT +Repository: https://github.com/chentsulin/webpack-target-electron-renderer +License File: webpack-target-electron-renderer/LICENSE + +whatwg-fetch +License: MIT +Repository: https://github.com/github/fetch +License File: whatwg-fetch/LICENSE + +whatwg-url-compat +License: MIT +Repository: https://github.com/jsdom/whatwg-url +License File: whatwg-url-compat/LICENSE.txt + +whet.extend +License: MIT +Repository: https://github.com/Meettya/whet.extend +License File: whet.extend/LICENSE + +which +License: ISC +Repository: https://github.com/isaacs/node-which +License File: cover/node_modules/which/LICENSE + +which +License: ISC +Repository: https://github.com/isaacs/node-which +License File: which/LICENSE + +window-size +License: MIT +Repository: https://github.com/jonschlinkert/window-size +License File: uglify-js/node_modules/window-size/LICENSE-MIT + +window-size +License: MIT +Repository: https://github.com/jonschlinkert/window-size +License File: window-size/LICENSE + +wordwrap +License: MIT/X11 +Repository: https://github.com/substack/node-wordwrap + +wordwrap +License: MIT +Repository: https://github.com/substack/node-wordwrap +License File: wordwrap/LICENSE + +wordwrap +License: MIT +Repository: https://github.com/substack/node-wordwrap +License File: istanbul/node_modules/wordwrap/LICENSE + +worker-farm +License: MIT +Repository: https://github.com/rvagg/node-worker-farm +License File: worker-farm/LICENSE.md + +wrap-ansi +License: MIT +Repository: https://github.com/chalk/wrap-ansi +License File: wrap-ansi/license + +wrap-fn +License: MIT* +Repository: https://github.com/matthewmueller/wrap-fn + +wrappy +License: ISC +Repository: https://github.com/npm/wrappy +License File: wrappy/LICENSE + +write +License: MIT +Repository: https://github.com/jonschlinkert/write +License File: write/LICENSE + +xml-escape +License: MIT License +Repository: https://github.com/miketheprogrammer/xml-escape +License File: xml-escape/LICENSE + +xml-name-validator +License: WTFPL +Repository: https://github.com/jsdom/xml-name-validator +License File: xml-name-validator/LICENSE.txt + +xmlbuilder +License: MIT +Repository: https://github.com/oozcitak/xmlbuilder-js +License File: xmlbuilder/LICENSE + +xmldom9 +License: MIT +Repository: https://github.com/jindw/xmldom +License File: xmldom/LICENSE + +xtend +License: MIT +Repository: https://github.com/Raynos/xtend +License File: through2/node_modules/xtend/LICENCE + +xtend +License: MIT +Repository: https://github.com/Raynos/xtend +License File: xtend/LICENCE + +y18n +License: ISC +Repository: https://github.com/bcoe/y18n + +yargs0 +License: MIT +Repository: https://github.com/bcoe/yargs +License File: uglify-js/node_modules/yargs/LICENSE + +yargs0 +License: MIT +Repository: https://github.com/bcoe/yargs +License File: yargs/LICENSE + +yauzl +License: MIT +Repository: https://github.com/thejoshwolfe/yauzl +License File: yauzl/LICENSE + +----- + +The following software may be included in this product: OpenSSL. This software contains the following license and notice below: + + + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + + /* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + + /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + + + +----- + +The following software may be included in this product: protobuf. This software contains the following license and notice below: + +Copyright 2008, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----- + +The following software may be included in this product: WiX Toolset. This software contains the following license and notice below: + +Copyright (c) 2004, Outercurve Foundation + +Microsoft Reciprocal License (MS-RL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + + Definitions + + The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + + A "contribution" is the original software, or any additions or changes to the software. + + A "contributor" is any person that distributes its contribution under this license. + + "Licensed patents" are a contributor's patent claims that read directly on its contribution. + + Grant of Rights + + (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + + (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + + Conditions and Limitations + + (A) Reciprocal Grants- For any file you distribute that contains code from the software (in source code or binary format), you must provide recipients the source code to that file along with a copy of this license, which license will govern that file. You may license other files that are entirely your own work and do not contain code from the software under any terms you choose. + + (B) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + + (C) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + + (D) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + + (E) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + + (F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. + +----- + +The following software may be included in this product: Virtual Gamepad Emulation Driver (ViGEm). This software contains the following license and notice below: + +/* +MIT License + +Copyright (c) 2016 Benjamin "Nefarius" Höglinger + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +----- + +The following software may be included in this product: IconExtractor/IconUtil for .NET. This software contains the following license and notice below: + +/* + * IconExtractor/IconUtil for .NET + * Copyright (C) 2014 Tsuda Kageyu. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +------ + +The following software may be included in this product: Color Thief .NET. This software contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2015 Kos + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/ovr_sdk_win_23.0.0/Windows10SDKPaths.props b/ovr_sdk_win_23.0.0/Windows10SDKPaths.props new file mode 100644 index 0000000..8f8bada --- /dev/null +++ b/ovr_sdk_win_23.0.0/Windows10SDKPaths.props @@ -0,0 +1,41 @@ + + + + + + + C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\km;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt;$(Win10SDK_IncPath) + C:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\km;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\ucrt;$(Win10SDK_IncPath) + C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\km;C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\ucrt;$(Win10SDK_IncPath) + C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\km;C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\ucrt;$(Win10SDK_IncPath) + C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\km;C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(Win10SDK_IncPath) + + C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\km\x86;$(Win10SDK_LibPathx86) + C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10586.0\um\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10586.0\km\x86;$(Win10SDK_LibPathx86) + C:\Program Files (x86)\Windows Kits\10\Lib\10.0.14393.0\um\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.14393.0\km\x86;$(Win10SDK_LibPathx86) + C:\Program Files (x86)\Windows Kits\10\Lib\10.0.15063.0\um\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.15063.0\km\x86;$(Win10SDK_LibPathx86) + C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\km\x86;$(Win10SDK_LibPathx86) + + C:\Program Files (x64)\Windows Kits\10\Lib\10.0.10240.0\um\x64;C:\Program Files (x64)\Windows Kits\10\Lib\10.0.10240.0\km\x64;$(Win10SDK_LibPathx64) + C:\Program Files (x64)\Windows Kits\10\Lib\10.0.10586.0\um\x64;C:\Program Files (x64)\Windows Kits\10\Lib\10.0.10586.0\km\x64;$(Win10SDK_LibPathx64) + C:\Program Files (x64)\Windows Kits\10\Lib\10.0.14393.0\um\x64;C:\Program Files (x64)\Windows Kits\10\Lib\10.0.14393.0\km\x64;$(Win10SDK_LibPathx64) + C:\Program Files (x64)\Windows Kits\10\Lib\10.0.15063.0\um\x64;C:\Program Files (x64)\Windows Kits\10\Lib\10.0.15063.0\km\x64;$(Win10SDK_LibPathx64) + C:\Program Files (x64)\Windows Kits\10\Lib\10.0.16299.0\um\x64;C:\Program Files (x64)\Windows Kits\10\Lib\10.0.16299.0\km\x64;$(Win10SDK_LibPathx64) + + + + + + $(Win10SDK_IncPath) + true + + + $(Win10SDK_LibPathx86) + true + + + $(Win10SDK_LibPathx64) + true + + + diff --git a/ovr_sdk_win_23.0.0/common.props b/ovr_sdk_win_23.0.0/common.props new file mode 100644 index 0000000..5e7f0be --- /dev/null +++ b/ovr_sdk_win_23.0.0/common.props @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/steamvr b/steamvr index b72abce..4c85abc 160000 --- a/steamvr +++ b/steamvr @@ -1 +1 @@ -Subproject commit b72abcebff7e6c6c70ce8ac8f6a09b70d44397e2 +Subproject commit 4c85abcb7f7f1f02adaf3812018c99fc593bc341 diff --git a/tobii.streamengine.native.2.2.2.363/.gitignore b/tobii.streamengine.native.2.2.2.363/.gitignore new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/tobii.streamengine.native.2.2.2.363/.gitignore @@ -0,0 +1 @@ +* diff --git a/tobii.streamengine.native.2.2.2.363/.gitkeep b/tobii.streamengine.native.2.2.2.363/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tobii.streamengine.native.2.2.2.363/URL.txt b/tobii.streamengine.native.2.2.2.363/URL.txt new file mode 100644 index 0000000..b0dddd8 --- /dev/null +++ b/tobii.streamengine.native.2.2.2.363/URL.txt @@ -0,0 +1,3 @@ +https://www.nuget.org/packages/Tobii.StreamEngine.Native/ + +tobii.streamengine.native.2.2.2.363.nupkg diff --git a/trackhat-c-library-driver b/trackhat-c-library-driver index a98c635..e290382 160000 --- a/trackhat-c-library-driver +++ b/trackhat-c-library-driver @@ -1 +1 @@ -Subproject commit a98c635d3ac37ef4febdb12626be7dbaf995129a +Subproject commit e2903828c76e9f6b897d8f071bae2b0f73242808 -- cgit v1.2.3