diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-11-07 16:29:54 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-11-07 16:29:54 +0100 |
commit | ab6683fdb2805f0f041bda7eccde49be661c5bfa (patch) | |
tree | 753c339ce12c01a5d0811a1da5749288b28c8a2f /ovr_sdk_win_23.0.0/LibOVRKernel/Src | |
parent | e660703009de3f5229d30214867595c2c687b74d (diff) |
foo
Diffstat (limited to 'ovr_sdk_win_23.0.0/LibOVRKernel/Src')
89 files changed, 64573 insertions, 0 deletions
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 <assert.h> +#include <stdio.h> +#include <string.h> +#include <string> + +#if defined(_WIN32) +#pragma comment(lib, "opengl32.lib") +#elif defined(__APPLE__) +#include <AvailabilityMacros.h> +#include <dlfcn.h> +#include <stdlib.h> +#include <string.h> +#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<const char*, bool>. + // 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 <OpenGL/gl3.h>) 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 <Windows.h> 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<const char*, bool>. + 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 <stddef.h> + +// Windows headers +// <wingdi.h> Windows-specific OpenGL 1.1 interfaces. Long ago this was <GL/wgl.h>. +// <GL/gl.h> OpenGL 1.1 interface. +// <GL/glext.h> OpenGL 1.2+ compatibility profile and extension interfaces. Not +// provided by Microsoft. +// <GL/wglext.h> Windows-specific extension interfaces. Not provided by Microsoft. +// <GL/glcorearb.h> 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/gl.h> OpenGL 1.1 interface. +// <OpenGL/glext.h> OpenGL 1.2+ compatibility profile and extension interfaces. +// <OpenGL/gl3.h> Includes only interfaces supported in a core OpenGL 3.1 implementations +// plus a few related extensions. +// <OpenGL/gl3ext.h> Includes extensions supported in a core OpenGL 3.1 implementation. +// <OpenGL/OpenGL.h> Apple-specific OpenGL interfaces. +// <OpenGL/NSOpenGL.h> Apple-specific OpenGL interfaces. +// +// Linux headers +// <GL/gl.h> OpenGL 1.1 interface. +// <GL/glext.h> OpenGL 1.2+ compatibility profile and extension interfaces. +// <GL/glx.h> X Windows-specific OpenGL interfaces. +// <GL/glxext.h> X Windows 1.3+ API and GLX extension interfaces. +// <GL/glcorearb.h> 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 <OpenGL/gl.h> +#define __GL_H__ // Disable future #includes of Microsoft's <GL/gl.h> +#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 <stdint.h> + +#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 <wingdi.h> +#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 <wingdi.h> 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 <OpenGL/OpenGL.h> +#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 <X11/Xlib.h> +#include <X11/Xmd.h> +#include <X11/Xutil.h> + +// 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 <Windows.h> 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 <string.h> +#include "OVR_Types.h" +#if defined(_MSC_VER) +#include <intrin.h> +#pragma intrinsic(_BitScanForward) +#pragma intrinsic(_BitScanReverse) +#if defined(_M_AMD64) +#pragma intrinsic(_BitScanForward64) +#pragma intrinsic(_BitScanReverse64) +#endif +#elif defined(__GNUC__) || defined(__clang__) +#include <x86intrin.h> +#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<int32_t>(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<int64_t>(x) < 0) + break; + n++; + x <<= 1; + } + return n; +#endif +} + +//----------------------------------------------------------------------------------- +// ***** Operator extensions + +template <typename T> +OVR_FORCE_INLINE void Swap(T& a, T& b) { + T temp(a); + a = b; + b = temp; +} + +// ***** min/max are not implemented in Visual Studio 6 standard STL + +template <typename T> +OVR_FORCE_INLINE const T Min(const T a, const T b) { + return (a < b) ? a : b; +} + +template <typename T> +OVR_FORCE_INLINE const T Max(const T a, const T b) { + return (b < a) ? a : b; +} + +template <typename T> +OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal) { + return Max<T>(minVal, Min<T>(v, maxVal)); +} + +template <typename T> +OVR_FORCE_INLINE int Chop(T f) { + return (int)f; +} + +template <typename T> +OVR_FORCE_INLINE T Lerp(T a, T b, T f) { + return (b - a) * f + a; +} + +// Smooth transition between 0..1 that has 0 first derivative at 0 and 1. +template <typename T> +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 <typename T> +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 <typename T> +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 <typename T> +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 <typename T> +OVR_FORCE_INLINE const T Abs(const T v) { + return (v >= 0) ? v : -v; +} + +//----------------------------------------------------------------------------------- +// ***** OperatorLess +// +template <class T> +struct OperatorLess { + static bool Compare(const T& a, const T& b) { + return a < b; + } +}; + +//----------------------------------------------------------------------------------- +// ***** QuickSortSliced +// +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. +// The range is specified with start, end, where "end" is exclusive! +// The comparison predicate must be specified. +template <class Array, class Less> +void QuickSortSliced(Array& arr, 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 <class Array> +void QuickSortSliced(Array& arr, size_t start, size_t end) { + typedef typename Array::ValueType ValueType; + QuickSortSliced(arr, start, end, OperatorLess<ValueType>::Compare); +} + +// Same as corresponding G_QuickSortSliced but with checking array limits to avoid +// crash in the case of wrong comparator functor. +template <class Array, class Less> +bool QuickSortSlicedSafe(Array& arr, 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 <class Array> +bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end) { + typedef typename Array::ValueType ValueType; + return QuickSortSlicedSafe(arr, start, end, OperatorLess<ValueType>::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** QuickSort +// +// Sort an array Array, ArrayPaged, ArrayUnsafe. +// The array must have GetSize() function. +// The comparison predicate must be specified. +template <class Array, class Less> +void QuickSort(Array& arr, Less less) { + QuickSortSliced(arr, 0, arr.GetSize(), less); +} + +// checks for boundaries +template <class Array, class Less> +bool QuickSortSafe(Array& arr, Less less) { + return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less); +} + +//----------------------------------------------------------------------------------- +// ***** QuickSort +// +// Sort an array Array, ArrayPaged, ArrayUnsafe. +// The array must have GetSize() function. +// The data type must have a defined "<" operator. +template <class Array> +void QuickSort(Array& arr) { + typedef typename Array::ValueType ValueType; + QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); +} + +template <class Array> +bool QuickSortSafe(Array& arr) { + typedef typename Array::ValueType ValueType; + return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** InsertionSortSliced +// +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. +// The range is specified with start, end, where "end" is exclusive! +// The comparison predicate must be specified. +// Unlike Quick Sort, the Insertion Sort works much slower in average, +// but may be much faster on almost sorted arrays. Besides, it guarantees +// that the elements will not be swapped if not necessary. For example, +// an array with all equal elements will remain "untouched", while +// Quick Sort will considerably shuffle the elements in this case. +template <class Array, class Less> +void InsertionSortSliced(Array& arr, 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 <class Array> +void InsertionSortSliced(Array& arr, size_t start, size_t end) { + typedef typename Array::ValueType ValueType; + InsertionSortSliced(arr, start, end, OperatorLess<ValueType>::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** InsertionSort +// +// Sort an array Array, ArrayPaged, ArrayUnsafe. +// The array must have GetSize() function. +// The comparison predicate must be specified. + +template <class Array, class Less> +void InsertionSort(Array& arr, Less less) { + InsertionSortSliced(arr, 0, arr.GetSize(), less); +} + +//----------------------------------------------------------------------------------- +// ***** InsertionSort +// +// Sort an array Array, ArrayPaged, ArrayUnsafe. +// The array must have GetSize() function. +// The data type must have a defined "<" operator. +template <class Array> +void InsertionSort(Array& arr) { + typedef typename Array::ValueType ValueType; + InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** 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 <class Array> +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 <class Array, class Value, class Less> +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 <class Array, class Value> +size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) { + return LowerBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** LowerBoundSized +// +template <class Array, class Value> +size_t LowerBoundSized(const Array& arr, size_t size, const Value& val) { + return LowerBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** LowerBound +// +template <class Array, class Value, class Less> +size_t LowerBound(const Array& arr, const Value& val, Less less) { + return LowerBoundSliced(arr, 0, arr.GetSize(), val, less); +} + +//----------------------------------------------------------------------------------- +// ***** LowerBound +// +template <class Array, class Value> +size_t LowerBound(const Array& arr, const Value& val) { + return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** UpperBoundSliced +// +template <class Array, class Value, class Less> +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 <class Array, class Value> +size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) { + return UpperBoundSliced(arr, start, end, val, OperatorLess<Value>::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** UpperBoundSized +// +template <class Array, class Value> +size_t UpperBoundSized(const Array& arr, size_t size, const Value& val) { + return UpperBoundSliced(arr, 0, size, val, OperatorLess<Value>::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** UpperBound +// +template <class Array, class Value, class Less> +size_t UpperBound(const Array& arr, const Value& val, Less less) { + return UpperBoundSliced(arr, 0, arr.GetSize(), val, less); +} + +//----------------------------------------------------------------------------------- +// ***** UpperBound +// +template <class Array, class Value> +size_t UpperBound(const Array& arr, const Value& val) { + return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess<Value>::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** ReverseArray +// +template <class Array> +void ReverseArray(Array& arr) { + intptr_t from = 0; + intptr_t to = arr.GetSize() - 1; + while (from < to) { + Swap(arr[from], arr[to]); + ++from; + --to; + } +} + +// ***** AppendArray +// +template <class CDst, class CSrc> +void AppendArray(CDst& dst, const CSrc& src) { + 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 T> +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 T> +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 <const unsigned bitCount> +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 <typename T> +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 <typename T> +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 <typename T> +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 <typename T> +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 <typename T> +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 <typename T> +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 <typename T> +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 <stdio.h> +#include <stdlib.h> +#include <algorithm> +#include <exception> +#include <memory> +#include <sstream> +#include "OVR_Alg.h" +#include "OVR_DebugHelp.h" +#include "OVR_Std.h" +#include "Util/Util_SystemInfo.h" + +#if defined(_MSC_VER) +#include <crtdbg.h> +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 <execinfo.h> +#include <sys/mman.h> +#include <unistd.h> +#include <chrono> +#if defined(__APPLE__) +#include <malloc/malloc.h> +#else +#include <malloc.h> +#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<const CrtMemBlockHeader*>(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<int>(0xFEDCBABC); + +static void* block_from_header(void* header) { + return (static_cast<CrtMemBlockHeader*>(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<CrtMemBlockHeader*>(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 <crtdbg.h> +#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 + // -> + // <impl> + // + // 2) static CRT (release builds): + // E8 88 1F 00 00 call malloc + // -> + // <impl> + // + // 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. + // -> + // <impl> + // + // 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<void*>(reinterpret_cast<uintptr_t>(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<void*>(reinterpret_cast<uintptr_t>(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<std::chrono::nanoseconds>(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<char*>(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<Instruction>::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<void*>(p)); +#elif defined(__APPLE__) + return malloc_size(p); +#else + return malloc_usable_size(const_cast<void*>(p)); +#endif +} + +size_t DefaultHeap::GetAllocAlignedSize(const void* p, size_t align) const { +#if defined(_MSC_VER) + return _aligned_msize(const_cast<void*>(p), align, 0); +#elif defined(__APPLE__) + OVR_UNUSED(align); + return malloc_size(p); +#else + OVR_UNUSED(align); + return malloc_usable_size(const_cast<void*>(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<void*>(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<void*>(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<void*>(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<void*>(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 <typename Pointer> +Pointer AlignPointerUp(Pointer p, size_t alignment) { + return reinterpret_cast<Pointer>( + ((reinterpret_cast<size_t>(p) + (alignment - 1)) & ~(alignment - 1))); +} + +template <typename Pointer> +Pointer AlignPointerDown(Pointer p, size_t alignment) { + return reinterpret_cast<Pointer>(reinterpret_cast<size_t>(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<void*>(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<size_t>(p); + size_t valuePos = (value - SizeStorageSize); + size_t* pSize = reinterpret_cast<size_t*>(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<uint8_t*>(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<size_t>(pPageMemory) + + (blockSize - PageSize); // pageEnd points to the beginning of the final guard page. + const size_t userPosition = AlignSizeDown(pageEnd - userSize, userAlignment); + pUserPosition = reinterpret_cast<uint8_t*>(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<uint8_t*>(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<size_t>(pPageMemory) + SizeStorageSize; + const size_t userPosition = AlignSizeUp(lowestPossiblePos, userAlignment); + pUserPosition = reinterpret_cast<uint8_t*>(userPosition); + OVR_ASSERT((userPosition + userSize) <= (reinterpret_cast<size_t>(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 = "<filepath> [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<std::string>& 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<Context*>(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>&, 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>&, 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>&, 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 <string.h> +#include <atomic> +#include <exception> +#include <map> +#include <new> +#include <string> +#include <unordered_map> +#include <vector> +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 <class T> +OVR_FORCE_INLINE T* Construct(void* p) { + return ::new (p) T(); +} + +template <class T> +OVR_FORCE_INLINE T* Construct(void* p, const T& source) { + return ::new (p) T(source); +} + +// Same as above, but allows for a different type of constructor. +template <class T, class S> +OVR_FORCE_INLINE T* ConstructAlt(void* p, const S& source) { + return ::new (p) T(source); +} + +template <class T, class S1, class S2> +OVR_FORCE_INLINE T* ConstructAlt(void* p, const S1& src1, const S2& src2) { + return ::new (p) T(src1, src2); +} + +// 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 <class T> +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<T>(pdata); + } +} + +template <class T> +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<T>(pdata, source); + } +} + +template <class T> +OVR_FORCE_INLINE void Destruct(T* pobj) { + pobj->~T(); + OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning. +} + +template <class T> +OVR_FORCE_INLINE void DestructArray(T* pobj, 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<int, StdAllocatorSysMem<int>> IntArray; +// typedef basic_string<char, char_traits<char>, StdAllocatorSysMem<char>> CharString; +// typedef list<int, StdAllocatorSysMem<int>> IntList; +// typedef map<int, long, less<int>, StdAllocatorSysMem<int>> IntMap; +// typedef multimap<int, long, less<int>, StdAllocatorSysMem<int>> IntMultiMap; +// typedef set<int, less<int>, StdAllocatorSysMem<int>> IntSet; +// typedef multiset<int, less<int>, StdAllocatorSysMem<int>> IntMultiSet; +// typedef unordered_map<int, long, hash<int>, equal_to<int>, StdAllocatorSysMem<int>> +// IntHashMap; +// typedef unordered_multimap<int, long, hash<int>, equal_to<int>, StdAllocatorSysMem<int>> +// IntHashMultiMap; +// typedef unordered_set<int, hash<int>, equal_to<int>, StdAllocatorSysMem<int>> IntHashSet; +// typedef unordered_multiset<int, hash<int>, equal_to<int>, StdAllocatorSysMem<int>> +// IntHashMultiSet; +// typedef deque<int, StdAllocatorSysMem<int>> IntDequeue; +// typedef queue<int, deque<int, StdAllocatorSysMem<int>> > IntQueue; +// +template <class T> +class StdAllocatorSysMem { + public: + typedef StdAllocatorSysMem<T> 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 <class Other> + struct rebind { + typedef StdAllocatorSysMem<Other> 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 <class Other> + StdAllocatorSysMem(const StdAllocatorSysMem<Other>&) {} + + template <class Other> + this_type& operator=(const StdAllocatorSysMem<Other>&) { + 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 <class U, class... Types> + void construct(U* pU, Types&&... args) const { + ::new ((void*)pU) U(std::forward<Types>(args)...); + } + + template <class U> + 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<void*, StdAllocatorSysMem<void*>> SysAllocatedPointerVector; +typedef std::basic_string<char, std::char_traits<char>, StdAllocatorSysMem<char>> + SysAllocatedString; +typedef std::vector<SysAllocatedString, StdAllocatorSysMem<SysAllocatedString>> + 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<const void*>, // map is slower but in debug builds we can read its sorted contents + // easier. + StdAllocatorSysMem<std::pair<const void* const, AllocMetadata>>> + TrackedAllocMap; +#else + typedef std::unordered_map< + const void*, + AllocMetadata, + std::hash<const void*>, + std::equal_to<const void*>, + StdAllocatorSysMem<std::pair<const void* const, AllocMetadata>>> + TrackedAllocMap; +#endif + + // Per-thread tag stack + typedef std::vector<const char*, StdAllocatorSysMem<const char*>> ConstCharVector; +#if defined(OVR_BUILD_DEBUG) + typedef std::map< + AllocatorThreadId, + ConstCharVector, + std::less<AllocatorThreadId>, + StdAllocatorSysMem<std::pair<const AllocatorThreadId, ConstCharVector>>> + ThreadIdToTagVectorMap; +#else + typedef std::unordered_map< + AllocatorThreadId, + ConstCharVector, + std::hash<AllocatorThreadId>, + std::equal_to<AllocatorThreadId>, + StdAllocatorSysMem<std::pair<const AllocatorThreadId, ConstCharVector>>> + 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 <string> case-insensitive. has means +// substring check. Line ==,<,<=,>,>= <integer> Time +// ==,<,<=,>,>= <integer>[s] time in nanoseconds (or seconds if followed by s). A +// negative time means relative to now. Count ==,<,<=,>,>= <integer> +// A negative count means to return the last nth allocation(s). AllocSize (or just Size) +// ==,<,<=,>,>= <integer> BlockSize ==,<,<=,>,>= <integer> Tag +// ==,has <string> case insensitive. has means substring check. ThreadId +// ==,<,<=,>,>= <integer> <,<=,>,>= are usually useless but provided for consistency +// with other integer types. ThreadName ==,has <string> 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<std::string>& 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>&, 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>&, 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>&, 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) +/// { +/// // <use 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<char*>(alloca((size) + OVR_MALLOCA_ID_SIZE)), OVR_MALLOCA_ALLOCA_ID) \ + : OVR::malloca_SetId( \ + static_cast<char*>(new char[(size) + OVR_MALLOCA_ID_SIZE]), OVR_MALLOCA_MALLOC_ID)) + +inline void* malloca_SetId(char* p, uint32_t id) { + if (p) { + *reinterpret_cast<uint32_t*>(p) = id; + p = reinterpret_cast<char*>(p) + OVR_MALLOCA_ID_SIZE; + } + + return p; +} +#endif + +#if !defined(OVR_freea) +#define OVR_freea(p) OVR::freea_Impl(reinterpret_cast<char*>(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<uint32_t*>(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) +/// { +/// // <use pWidgetArray> +/// OVR_deletea(Widget, pWidgetArray); +/// } +/// } +/// +#if !defined(OVR_newa) +#define OVR_newa(T, count) \ + OVR::newa_Impl<T>(static_cast<char*>(OVR_malloca(count * sizeof(T))), count) +#endif + +template <class T> +T* newa_Impl(char* pTArray, size_t count) { + if (pTArray) { + OVR::ConstructArray<T>(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<uint32_t*>((reinterpret_cast<char*>(pTArray) - OVR_MALLOCA_ID_SIZE))[1] = + (uint32_t)count; + } + return reinterpret_cast<T*>(pTArray); +} + +#if !defined(OVR_deletea) +#define OVR_deletea(T, pTArray) OVR::deletea_Impl<T>(pTArray) +#endif + +template <class T> +void deletea_Impl(T* pTArray) { + if (pTArray) { + uint32_t count = + reinterpret_cast<uint32_t*>((reinterpret_cast<char*>(pTArray) - OVR_MALLOCA_ID_SIZE))[1]; + OVR::DestructArray<T>(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 <int MinCapacity = 0, int Granularity = 4, bool NeverShrink = false> +struct ArrayConstPolicy { + typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType; + + ArrayConstPolicy() : Capacity(0) {} + ArrayConstPolicy(const SelfType&) : Capacity(0) {} + + 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 <class T, class Allocator, class SizePolicy> +struct ArrayDataBase { + typedef T ValueType; + typedef Allocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayDataBase<T, Allocator, SizePolicy> SelfType; + + ArrayDataBase() : Data(0), Size(0), Policy() {} + + ArrayDataBase(const SizePolicy& p) : Data(0), Size(0), Policy(p) {} + + ~ArrayDataBase() { + 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 <class T, class Allocator, class SizePolicy> +struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy> { + typedef T ValueType; + typedef Allocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType; + typedef ArrayData<T, Allocator, SizePolicy> SelfType; + + ArrayData() : BaseType() {} + + ArrayData(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 <class S> + void PushBackAlt(const S& val) { + BaseType::ResizeNoConstruct(this->Size + 1); + Allocator::ConstructAlt(this->Data + this->Size - 1, val); + } + + // Append the given data to the array. + void Append(const ValueType other[], 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 <class T, class Allocator, class SizePolicy> +struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy> { + typedef T ValueType; + typedef Allocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType; + typedef ArrayDataCC<T, Allocator, SizePolicy> SelfType; + + ArrayDataCC(const ValueType& defval) : BaseType(), DefaultValue(defval) {} + + ArrayDataCC(const ValueType& defval, 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 <class S> + void PushBackAlt(const S& val) { + BaseType::ResizeNoConstruct(this->Size + 1); + Allocator::ConstructAlt(this->Data + this->Size - 1, val); + } + + // Append the given data to the array. + void Append(const ValueType other[], 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 ArrayData> +class ArrayBase { + public: + typedef typename ArrayData::ValueType ValueType; + typedef typename ArrayData::AllocatorType AllocatorType; + typedef typename ArrayData::SizePolicyType SizePolicyType; + typedef ArrayBase<ArrayData> SelfType; + +#undef new + OVR_MEMORY_REDEFINE_NEW(ArrayBase) +// Redefine operator 'new' if necessary. +#if defined(OVR_DEFINE_NEW) +#define new OVR_DEFINE_NEW +#endif + + ArrayBase() : Data() {} + ArrayBase(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 <class S> + 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 T, class SizePolicy = ArrayDefaultPolicy> +class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy>> { + public: + typedef T ValueType; + typedef ContainerAllocator<T> AllocatorType; + typedef SizePolicy SizePolicyType; + typedef Array<T, SizePolicy> SelfType; + typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy>> BaseType; + + Array() : BaseType() {} + 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 T, class SizePolicy = ArrayDefaultPolicy> +class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy>> { + public: + typedef T ValueType; + typedef ContainerAllocator_POD<T> AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayPOD<T, SizePolicy> SelfType; + typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy>> BaseType; + + ArrayPOD() : BaseType() {} + 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 T, class SizePolicy = ArrayDefaultPolicy> +class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy>> { + public: + typedef T ValueType; + typedef ContainerAllocator_CPP<T> AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayCPP<T, SizePolicy> SelfType; + typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy>> BaseType; + + ArrayCPP() : BaseType() {} + 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 T, class SizePolicy = ArrayDefaultPolicy> +class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy>> { + public: + typedef T ValueType; + typedef ContainerAllocator<T> AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayCC<T, SizePolicy> SelfType; + typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy>> BaseType; + + ArrayCC(const ValueType& defval) : BaseType(defval) {} + ArrayCC(const ValueType& defval, 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 <synchapi.h> +#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 <atomic> + +// Include System thread functionality. +#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) +#include "OVR_Win32_IncludeWindows.h" +#else +#include <pthread.h> +#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 T> +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 DelegateT> +class CallbackEmitter : public NewOverrideBase { + public: + CallbackEmitter(); + ~CallbackEmitter(); + + // Add a listener. + bool AddListener(CallbackListener<DelegateT>* 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 <class Param1> + void Call(Param1* p1) { + Emitter->Call(p1); + } + template <class Param1> + void Call(Param1& p1) { + Emitter->Call(p1); + } + template <class Param1, class Param2> + void Call(Param1* p1, Param2* p2) { + Emitter->Call(p1, p2); + } + template <class Param1, class Param2> + void Call(Param1& p1, Param2& p2) { + Emitter->Call(p1, p2); + } + template <class Param1, class Param2, class Param3> + void Call(Param1* p1, Param2* p2, Param3* p3) { + Emitter->Call(p1, p2, p3); + } + template <class Param1, class Param2, class Param3> + 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<FloatingCallbackEmitter<DelegateT>> 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 DelegateT> +class CallbackListener : public NewOverrideBase { + friend class CallbackEmitter<DelegateT>; + + 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<FloatingCallbackListener<DelegateT>> FloatingListener; + + // Reference to the associated emitter. + Ptr<FloatingCallbackEmitter<DelegateT>> FloatingEmitter; + + DelegateT Handler; +}; + +//----------------------------------------------------------------------------- +// Template Implementation: CallbackEmitter + +template <class DelegateT> +CallbackEmitter<DelegateT>::CallbackEmitter() { + Emitter = *new FloatingCallbackEmitter<DelegateT>; +} + +template <class DelegateT> +CallbackEmitter<DelegateT>::~CallbackEmitter() { + Emitter->Shutdown(); + // Emitter goes out of scope here. +} + +template <class DelegateT> +bool CallbackEmitter<DelegateT>::AddListener(CallbackListener<DelegateT>* 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<DelegateT>(listener->Handler); + listener->FloatingEmitter = Emitter.GetPtr(); + + // The remaining input checks are performed inside. + return Emitter->AddListener(listener->FloatingListener); +} + +template <class DelegateT> +int CallbackEmitter<DelegateT>::GetListenerCount() const { + return Emitter->Listeners.GetSizeI(); +} + +template <class DelegateT> +void CallbackEmitter<DelegateT>::Shutdown() { + Emitter->Shutdown(); +} + +//----------------------------------------------------------------------------- +// Template Implementation: CallbackListener + +template <class DelegateT> +CallbackListener<DelegateT>::CallbackListener() { + // Listener is null until a handler is set. +} + +template <class DelegateT> +CallbackListener<DelegateT>::~CallbackListener() { + Cancel(); +} + +template <class DelegateT> +void CallbackListener<DelegateT>::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 <class DelegateT> +void CallbackListener<DelegateT>::SetHandler(DelegateT handler) { + Cancel(); + + Handler = handler; +} + +template <class DelegateT> +bool CallbackListener<DelegateT>::IsListening() const { + if (!FloatingListener.GetPtr()) { + return false; + } + + return FloatingListener->IsValid(); +} + +//----------------------------------------------------------------------------- +// CallbackHash +// +// A hash containing CallbackEmitters +template <class DelegateT> +class CallbackHash : public NewOverrideBase { + typedef Hash<String, CallbackEmitter<DelegateT>*, String::HashFunctor> HashTable; + + public: + ~CallbackHash() { + Clear(); + } + + void Clear() { + for (auto ii = Table.Begin(); ii != Table.End(); ++ii) { + delete ii->Second; + } + + Table.Clear(); + } + + CallbackEmitter<DelegateT>* GetKey(String key) { + CallbackEmitter<DelegateT>** emitter = Table.Get(key); + if (emitter) { + return *emitter; + } + return nullptr; + } + + void AddListener(String key, CallbackListener<DelegateT>* listener) { + CallbackEmitter<DelegateT>** pEmitter = Table.Get(key); + CallbackEmitter<DelegateT>* emitter = nullptr; + + if (!pEmitter) { + emitter = new CallbackEmitter<DelegateT>; + Table.Add(key, emitter); + } else { + emitter = *pEmitter; + } + + emitter->AddListener(listener); + } + + void RemoveKey(String key) { + CallbackEmitter<DelegateT>** 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 <atomic> +#endif + +namespace OVR { + +template <class DelegateT> +class FloatingCallbackEmitter; // Floating emitter object +template <class DelegateT> +class CallbackEmitter; +template <class DelegateT> +class FloatingCallbackListener; // Floating listener object +template <class DelegateT> +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 DelegateT> +class FloatingCallbackEmitter : public CallbackEmitterBase, + public RefCountBase<FloatingCallbackEmitter<DelegateT>> { + friend class CallbackEmitter<DelegateT>; + + FloatingCallbackEmitter() + : IsShutdown(false), +#if !defined(OVR_CC_MSVC) || (OVR_CC_VERSION > 1600) // Newer than VS2010 + ListenersExist(false), +#endif + DirtyListenersCache(0) { + } + + public: + typedef Array<Ptr<FloatingCallbackListener<DelegateT>>> ListenerPtrArray; + + ~FloatingCallbackEmitter() { + OVR_ASSERT(Listeners.GetSizeI() == 0); + // ListenersCache will be emptied here. + } + + bool AddListener(FloatingCallbackListener<DelegateT>* 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<DelegateT>* listener); + + public: + void Call(); + + template <class Param1> + void Call(Param1* p1); + + template <class Param1> + void Call(Param1& p1); + + template <class Param1, class Param2> + void Call(Param1* p1, Param2* p2); + + template <class Param1, class Param2> + void Call(Param1& p1, Param2& p2); + + template <class Param1, class Param2, class Param3> + void Call(Param1* p1, Param2* p2, Param3* p3); + + template <class Param1, class Param2, class Param3> + 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<bool> ListenersExist; +#endif + + // Is the cache dirty? This avoids locking and memory allocation in steady state. + std::atomic<uint32_t> 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<DelegateT>* 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 DelegateT> +class FloatingCallbackListener : public RefCountBase<FloatingCallbackListener<DelegateT>> { + 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 <class DelegateT> +bool FloatingCallbackEmitter<DelegateT>::AddListener( + FloatingCallbackListener<DelegateT>* 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 <class DelegateT> +void FloatingCallbackEmitter<DelegateT>::OnListenerCancel( + FloatingCallbackListener<DelegateT>* 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 <class DelegateT> +void FloatingCallbackEmitter<DelegateT>::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 <class DelegateT> +void FloatingCallbackEmitter<DelegateT>::Call() { + OVR_EMITTER_CALL_BODY(()) +} + +template <class DelegateT> +template <class Param1> +void FloatingCallbackEmitter<DelegateT>::Call(Param1* p1) { + OVR_EMITTER_CALL_BODY((p1)) +} + +template <class DelegateT> +template <class Param1> +void FloatingCallbackEmitter<DelegateT>::Call(Param1& p1) { + OVR_EMITTER_CALL_BODY((p1)) +} + +template <class DelegateT> +template <class Param1, class Param2> +void FloatingCallbackEmitter<DelegateT>::Call(Param1* p1, Param2* p2) { + OVR_EMITTER_CALL_BODY((p1, p2)) +} + +template <class DelegateT> +template <class Param1, class Param2> +void FloatingCallbackEmitter<DelegateT>::Call(Param1& p1, Param2& p2) { + OVR_EMITTER_CALL_BODY((p1, p2)) +} + +template <class DelegateT> +template <class Param1, class Param2, class Param3> +void FloatingCallbackEmitter<DelegateT>::Call(Param1* p1, Param2* p2, Param3* p3) { + OVR_EMITTER_CALL_BODY((p1, p2, p3)) +} + +template <class DelegateT> +template <class Param1, class Param2, class Param3> +void FloatingCallbackEmitter<DelegateT>::Call(Param1& p1, Param2& p2, Param3& p3) { + OVR_EMITTER_CALL_BODY((p1, p2, p3)) +} + +#undef OVR_EMITTER_CALL_BODY + +//----------------------------------------------------------------------------- +// Template Implementation: FloatingCallbackListener + +template <class DelegateT> +FloatingCallbackListener<DelegateT>::FloatingCallbackListener(DelegateT handler) + : Handler(handler) { + OVR_ASSERT(Handler.IsValid()); +} + +template <class DelegateT> +FloatingCallbackListener<DelegateT>::~FloatingCallbackListener() { + OVR_ASSERT(!Handler.IsValid()); +} + +template <class DelegateT> +void FloatingCallbackListener<DelegateT>::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) +// <code> +// 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) +// <code> +// 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) +// <code> +// 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) +// <code> +// +#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() +// <code> +// 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 <typeinfo> +// int x = std::dynamic_cast<int>(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<LocalClass> 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 <stdalign.h> + +#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 <typename T> +// 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<char>); // 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 <string.h> +#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 T> +class ConstructorPOD { + public: + static void Construct(void*) {} + + static void Construct(void* p, const T& source) { + *(T*)p = source; + } + + // Same as above, but allows for a different type of constructor. + template <class S> + static void ConstructAlt(void* p, const S& source) { + *(T*)p = source; + } + + static void ConstructArray(void*, 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 T> +class ConstructorMov { + public: + static void Construct(void* p) { + OVR::Construct<T>(p); + } + + static void Construct(void* p, const T& source) { + OVR::Construct<T>(p, source); + } + + // Same as above, but allows for a different type of constructor. + template <class S> + static void ConstructAlt(void* p, const S& source) { + OVR::ConstructAlt<T, S>(p, source); + } + + static void ConstructArray(void* p, 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 T> +class ConstructorCPP { + public: + static void Construct(void* p) { + OVR::Construct<T>(p); + } + + static void Construct(void* p, const T& source) { + OVR::Construct<T>(p, source); + } + + // Same as above, but allows for a different type of constructor. + template <class S> + static void ConstructAlt(void* p, const S& source) { + OVR::ConstructAlt<T, S>(p, source); + } + + static void ConstructArray(void* p, 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 <class T> +struct ContainerAllocator_POD : ContainerAllocatorBase, ConstructorPOD<T> {}; +template <class T> +struct ContainerAllocator : ContainerAllocatorBase, ConstructorMov<T> {}; +template <class T> +struct ContainerAllocator_CPP : ContainerAllocatorBase, ConstructorCPP<T> {}; + +} // 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 <Windows.h> +#include <type_traits> + +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 <typename T, typename = std::enable_if_t<std::is_function_v<T>>> + operator T*() const { + return reinterpret_cast<T*>(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 <stdlib.h> +#include <time.h> +#include <algorithm> + +#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 <DbgHelp.h> +#include <ObjBase.h> +#include <Psapi.h> +#include <ShlObj.h> +#include <TlHelp32.h> +#include <Wbemcli.h> +#include <Wbemidl.h> +#include <WinNT.h> +#include <WinVer.h> +#include <atlbase.h> +#include <comutil.h> +#include <process.h> +#include <share.h> +#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 <unistd.h> +#include "sys/stat.h" +#if defined(OVR_OS_ANDROID) +#include <linux/sysctl.h> +#else +#include <sys/sysctl.h> +#endif +#include <libgen.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <sys/ptrace.h> +#include <sys/types.h> +#include <sys/utsname.h> +#include <sys/wait.h> +#if !defined(OVR_OS_ANDROID) +#include <execinfo.h> +#endif +#include <cxxabi.h> +//#include <libunwind.h> // Can't use this until we can ensure that we have an installed version of +// it. +#endif + +#if defined(OVR_OS_MAC) +#include <mach-o/dyld.h> // _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<unsigned long long>(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<void*>(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<uint8_t*>(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<uint8_t*>(pFunction) + 1, sizeof(int32_t)); + pSavedFunction->FunctionImplementation = + reinterpret_cast<uint8_t*>(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<uint8_t*>(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<uint8_t*>(pFunction) + 1, sizeof(int32_t)); + pSavedFunction->FunctionImplementation = + reinterpret_cast<uint8_t*>(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<uint8_t*>(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<uint8_t*>(pFunction) + 1, sizeof(int32_t)); + pSavedFunction->FunctionImplementation = + reinterpret_cast<uint8_t*>(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 <rel32> + 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<const uint8_t*>(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<int*>((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<void**>(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<uint64_t*>(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 += "<Unable to read backtrace>\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<ExceptionHandler*>(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<signed long>(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<unsigned long>(EXCEPTION_ACCESS_VIOLATION)) || + (exceptionInfo.exceptionRecord.ExceptionCode == + static_cast<unsigned long>(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<unsigned long>(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<signed long>(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<DWORD>(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<unsigned int>(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 <name> <handle> <id> +// 0 <module> <address> <function> <file>:<line> +// 1 <module> <address> <function> <file>:<line> +// . . . +// +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("<Unable to read backtrace>\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<decltype(&::VerQueryValueW)>( + 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"<none>"); + + 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<const MinidumpCallbackContext*>(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<size_t>( + 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 <file path> + // 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 <stdio.h> +#include <time.h> + +#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) +#include "OVR_Win32_IncludeWindows.h" +#elif defined(OVR_OS_APPLE) || defined(OVR_OS_LINUX) +#include <pthread.h> +#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<int> 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<uint32_t> 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<void, int> MyDelegate; + MyDelegate d; + + Point the delegate to a member function: + d.SetMember<A, &A::TestFunctionA>(&a); + d = MyDelegate::FromMember<A, &A::TestFunctionA>(&a); + + Point the delegate to a const member function: + d.SetConstMember<C, &C::TestFunctionA>(&c); + d = MyDelegate::FromConstMember<C, &C::TestFunctionA>(&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 ret_type> +class Delegate0 { + typedef ret_type (*StubPointer)(void*); + typedef Delegate0<ret_type> this_type; + + void* _object; + StubPointer _stub; + + inline Delegate0(void* object, StubPointer stub) { + _object = object; + _stub = stub; + } + + // Stubs + + template <ret_type (*F)()> + static inline ret_type FreeStub(void* /*object*/) { + return (F)(); + } + + template <class T, ret_type (T::*F)()> + static inline ret_type MemberStub(void* object) { + T* p = static_cast<T*>(object); + return (p->*F)(); + } + + template <class T, ret_type (T::*F)() const> + static inline ret_type ConstMemberStub(void* object) { + T* p = static_cast<T*>(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 <ret_type (*F)()> + static inline this_type FromFree() { + return this_type(0, &FreeStub<F>); + } + + template <class T, ret_type (T::*F)()> + static inline this_type FromMember(T* object) { + return this_type(object, &MemberStub<T, F>); + } + + template <class T, ret_type (T::*F)() const> + static inline this_type FromConstMember(T const* object) { + return this_type(const_cast<T*>(object), &ConstMemberStub<T, F>); + } + + // In-place assignment to a different function + + template <ret_type (*F)()> + inline void SetFree() { + *this = FromFree<F>(); + } + + template <class T, ret_type (T::*F)()> + inline void SetMember(T* object) { + *this = FromMember<T, F>(object); + } + + template <class T, ret_type (T::*F)() const> + inline void SetConstMember(T const* object) { + *this = FromConstMember<T, F>(object); + } +}; + +template <class ret_type, class arg1_type> +class Delegate1 { + typedef ret_type (*StubPointer)(void*, arg1_type); + typedef Delegate1<ret_type, arg1_type> this_type; + + void* _object; + StubPointer _stub; + + inline Delegate1(void* object, StubPointer stub) { + _object = object; + _stub = stub; + } + + // Stubs + + template <ret_type (*F)(arg1_type)> + static inline ret_type FreeStub(void* /*object*/, arg1_type a1) { + return (F)(a1); + } + + template <class T, ret_type (T::*F)(arg1_type)> + static inline ret_type MemberStub(void* object, arg1_type a1) { + T* p = static_cast<T*>(object); + return (p->*F)(a1); + } + + template <class T, ret_type (T::*F)(arg1_type) const> + static inline ret_type ConstMemberStub(void* object, arg1_type a1) { + T* p = static_cast<T*>(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 <ret_type (*F)(arg1_type)> + static inline this_type FromFree() { + return this_type(0, &FreeStub<F>); + } + + template <class T, ret_type (T::*F)(arg1_type)> + static inline this_type FromMember(T* object) { + return this_type(object, &MemberStub<T, F>); + } + + template <class T, ret_type (T::*F)(arg1_type) const> + static inline this_type FromConstMember(T const* object) { + return this_type(const_cast<T*>(object), &ConstMemberStub<T, F>); + } + + // In-place assignment to a different function + + template <ret_type (*F)(arg1_type)> + inline void SetFree() { + *this = FromFree<F>(); + } + + template <class T, ret_type (T::*F)(arg1_type)> + inline void SetMember(T* object) { + *this = FromMember<T, F>(object); + } + + template <class T, ret_type (T::*F)(arg1_type) const> + inline void SetConstMember(T const* object) { + *this = FromConstMember<T, F>(object); + } +}; + +template <class ret_type, class arg1_type, class arg2_type> +class Delegate2 { + typedef ret_type (*StubPointer)(void*, arg1_type, arg2_type); + typedef Delegate2<ret_type, arg1_type, arg2_type> this_type; + + void* _object; + StubPointer _stub; + + inline Delegate2(void* object, StubPointer stub) { + _object = object; + _stub = stub; + } + + // Stubs + + template <ret_type (*F)(arg1_type, arg2_type)> + static inline ret_type FreeStub(void* /*object*/, arg1_type a1, arg2_type a2) { + return (F)(a1, a2); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type)> + static inline ret_type MemberStub(void* object, arg1_type a1, arg2_type a2) { + T* p = static_cast<T*>(object); + return (p->*F)(a1, a2); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type) const> + static inline ret_type ConstMemberStub(void* object, arg1_type a1, arg2_type a2) { + T* p = static_cast<T*>(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 <ret_type (*F)(arg1_type, arg2_type)> + static inline this_type FromFree() { + return this_type(0, &FreeStub<F>); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type)> + static inline this_type FromMember(T* object) { + return this_type(object, &MemberStub<T, F>); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type) const> + static inline this_type FromConstMember(T const* object) { + return this_type(const_cast<T*>(object), &ConstMemberStub<T, F>); + } + + // In-place assignment to a different function + + template <ret_type (*F)(arg1_type, arg2_type)> + inline void SetFree() { + *this = FromFree<F>(); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type)> + inline void SetMember(T* object) { + *this = FromMember<T, F>(object); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type) const> + inline void SetConstMember(T const* object) { + *this = FromConstMember<T, F>(object); + } +}; + +template <class ret_type, class arg1_type, class arg2_type, class arg3_type> +class Delegate3 { + typedef ret_type (*StubPointer)(void*, arg1_type, arg2_type, arg3_type); + typedef Delegate3<ret_type, arg1_type, arg2_type, arg3_type> this_type; + + void* _object; + StubPointer _stub; + + inline Delegate3(void* object, StubPointer stub) { + _object = object; + _stub = stub; + } + + // Stubs + + template <ret_type (*F)(arg1_type, arg2_type, arg3_type)> + static inline ret_type FreeStub(void* /*object*/, arg1_type a1, arg2_type a2, arg3_type a3) { + return (F)(a1, a2, a3); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)> + static inline ret_type MemberStub(void* object, arg1_type a1, arg2_type a2, arg3_type a3) { + T* p = static_cast<T*>(object); + return (p->*F)(a1, a2, a3); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const> + static inline ret_type ConstMemberStub(void* object, arg1_type a1, arg2_type a2, arg3_type a3) { + T* p = static_cast<T*>(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 <ret_type (*F)(arg1_type, arg2_type, arg3_type)> + static inline this_type FromFree() { + return this_type(0, &FreeStub<F>); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)> + static inline this_type FromMember(T* object) { + return this_type(object, &MemberStub<T, F>); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const> + static inline this_type FromConstMember(T const* object) { + return this_type(const_cast<T*>(object), &ConstMemberStub<T, F>); + } + + // In-place assignment to a different function + + template <ret_type (*F)(arg1_type, arg2_type, arg3_type)> + inline void SetFree() { + *this = FromFree<F>(); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)> + inline void SetMember(T* object) { + *this = FromMember<T, F>(object); + } + + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const> + inline void SetConstMember(T const* object) { + *this = FromConstMember<T, F>(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 Elem, class Allocator = ContainerAllocator<Elem>> +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 Elem, class Allocator = ContainerAllocator<Elem>> +class InPlaceMutableDeque : public Deque<Elem, Allocator> { + typedef Deque<Elem, Allocator> 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 Elem, class Allocator = ContainerAllocator<Elem>> +class CircularBuffer : public InPlaceMutableDeque<Elem, Allocator> { + typedef InPlaceMutableDeque<Elem, Allocator> 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 <class Elem, class Allocator> +Deque<Elem, Allocator>::Deque(int capacity) + : Capacity(capacity), Beginning(0), End(0), ElemCount(0) { + Data = (Elem*)Allocator::Alloc(Capacity * sizeof(Elem)); +} + +// Deque Destructor function +template <class Elem, class Allocator> +Deque<Elem, Allocator>::~Deque(void) { + Clear(); + Allocator::Free(Data); +} + +template <class Elem, class Allocator> +void Deque<Elem, Allocator>::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 <class Elem, class Allocator> +void Deque<Elem, Allocator>::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 <class Elem, class Allocator> +void Deque<Elem, Allocator>::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 <class Elem, class Allocator> +Elem Deque<Elem, Allocator>::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 <class Elem, class Allocator> +Elem Deque<Elem, Allocator>::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 <class Elem, class Allocator> +const Elem& Deque<Elem, Allocator>::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 <class Elem, class Allocator> +const Elem& Deque<Elem, Allocator>::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 <class Elem, class Allocator> +Elem& InPlaceMutableDeque<Elem, Allocator>::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 <class Elem, class Allocator> +Elem& InPlaceMutableDeque<Elem, Allocator>::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 <class Elem, class Allocator> +inline size_t Deque<Elem, Allocator>::GetCapacity(void) const { + return Capacity; +} + +template <class Elem, class Allocator> +inline size_t Deque<Elem, Allocator>::GetSize(void) const { + return ElemCount; +} + +template <class Elem, class Allocator> +inline bool Deque<Elem, Allocator>::IsEmpty(void) const { + return ElemCount == 0; +} + +template <class Elem, class Allocator> +inline bool Deque<Elem, Allocator>::IsFull(void) const { + return ElemCount == Capacity; +} + +// ******* CircularBuffer<Elem> ******* +// Push functions +template <class Elem, class Allocator> +void CircularBuffer<Elem, Allocator>::PushBack(const Elem& Item) { + if (this->IsFull()) + this->PopFront(); + BaseType::PushBack(Item); +} + +template <class Elem, class Allocator> +void CircularBuffer<Elem, Allocator>::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 <dxgitype.h> +#include <winerror.h> +#endif +#include <stdarg.h> +#include <algorithm> +#include <chrono> +#include <cstdio> +#include <ctime> +#include <mutex> +#include <unordered_map> +#include <utility> +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<std::chrono::system_clock>. +// +// 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<std::chrono::seconds>(timeSinceEpoch); + timeSinceEpoch -= s; + + std::chrono::milliseconds ms = + std::chrono::duration_cast<std::chrono::milliseconds>(timeSinceEpoch); + timeSinceEpoch -= ms; + + std::chrono::microseconds us = + std::chrono::duration_cast<std::chrono::microseconds>(timeSinceEpoch); + timeSinceEpoch -= us; + + std::chrono::nanoseconds ns = + std::chrono::duration_cast<std::chrono::nanoseconds>(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<OVR::String, int> 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<ovrResult, const char*> 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 <vulkan.h> 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<int32_t>(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 <Logging/Logging-fwd.h> +#include <chrono> +#include <functional> +#include <utility> +#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<std::chrono::system_clock> 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<String, int> GetSource() const; + + typedef OVR::Array<void*> 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<LastErrorTLS> { + OVR_DECLARE_SINGLETON(LastErrorTLS); + + public: + OVRError& LastError(); + + protected: + // Protect hash from multiple thread access. + Lock TheLock; + + // Map thread-id to OVRError objects. + typedef Hash<ThreadId, OVRError> 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 "<code>: " +/// 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<void(const OVRError& err, bool quiet)> 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 <stdio.h> + +#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 <stdio.h> +#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<File>, public FileConstants { + public: + File() {} + // ** Location Information + + // Returns a file name path relative to the 'reference' directory + // This is often a path that was used to create a file + // (this is not a global path, global path can be obtained with help of directory) + virtual const char* GetFilePath() = 0; + + // ** File Information + + // Return 1 if file's usable (open) + virtual bool IsValid() = 0; + // Return 1 if file's writable, otherwise 0 + virtual bool IsWritable() = 0; + + // Return position + virtual int Tell() = 0; + virtual 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<File> pFile; + + // Hidden default constructor + DelegatedFile() : pFile(0) {} + DelegatedFile(const DelegatedFile& source) : File() { + OVR_UNUSED(source); + } + + public: + // Constructors + DelegatedFile(File* pfile) : pFile(pfile) {} + + // ** Location Information + virtual const char* GetFilePath() { + return pFile->GetFilePath(); + } + + // ** File Information + virtual bool IsValid() { + return pFile && pFile->IsValid(); + } + virtual bool IsWritable() { + return pFile->IsWritable(); + } + // virtual bool IsRecoverable() { return + // pFile->IsRecoverable(); } + + virtual int Tell() { + return pFile->Tell(); + } + virtual 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 <stdio.h> +#ifndef OVR_OS_WINCE +#include <sys/stat.h> +#endif + +#include "OVR_SysFile.h" + +#ifndef OVR_OS_WINCE +#include <errno.h> +#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)<numBytes) ? errno : 0; + + return int(newPos - (int)pos); +} + +// Return # of bytes till EOF +int FILEFile::BytesAvailable() { + int64_t pos = LTell(); + int64_t endPos = LGetLength(); + + // Return -1 for major error + if ((pos == -1) || (endPos == -1)) { + ErrorCode = SFerror(); + return 0; + } else + ErrorCode = 0; + + return int(endPos - (int)pos); +} + +// Flush file contents +bool FILEFile::Flush() { + return !fflush(fs); +} + +int FILEFile::Seek(int offset, int origin) { + int newOrigin = 0; + switch (origin) { + case Seek_Set: + newOrigin = SEEK_SET; + break; + case Seek_Cur: + newOrigin = SEEK_CUR; + break; + case Seek_End: + newOrigin = SEEK_END; + break; + } + + if (newOrigin == SEEK_SET && offset == Tell()) + return Tell(); + + if (fseek(fs, offset, newOrigin)) { +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + OVR_ASSERT(0); +#endif + return -1; + } + +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + // Track file position after seeks for read verification later. + switch (origin) { + case Seek_Set: + TestPos = offset; + break; + case Seek_Cur: + TestPos += offset; + break; + case Seek_End: + TestPos = FileTestLength + offset; + break; + } + OVR_ASSERT((int)TestPos == Tell()); +#endif + + return (int)Tell(); +} + +int64_t FILEFile::LSeek(int64_t offset, int origin) { + return Seek((int)offset, origin); +} + +int FILEFile::CopyFromStream(File* pstream, int byteSize) { + 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; +} + +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<File> FileFILEOpen(const String& path, int flags, int mode) { + Ptr<File> 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 C> +class IdentityHash { + public: + size_t operator()(const C& data) const { + return (size_t)data; + } +}; + +// Computes a hash of an object's representation. +template <class C> +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 C, class HashF> +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 C, class HashF> +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<C, HashF> if hashes are expensive to +// compute and thus need caching in entries. +// Entry = HashsetEntry<C, HashF> if hashes are already externally cached. +// +template < + class C, + class HashF = FixedSizeHash<C>, + class AltHashF = HashF, + class Allocator = ContainerAllocator<C>, + class Entry = HashsetCachedEntry<C, HashF>> +class HashSetBase { + enum { HashMinSize = 8 }; + + public: + OVR_MEMORY_REDEFINE_NEW(HashSetBase) + + typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry> 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 <class CRef> + 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 <class CRef> + inline void Add(const CRef& key) { + size_t hashValue = HashF()(key); + add(key, hashValue); + } + + // Remove by alternative key. + template <class K> + 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 <class CRef> + 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 <class K> + C* Get(const K& key) { + intptr_t index = findIndex(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + template <class K> + 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 <class K> + const C* GetAlt(const K& key) const { + intptr_t index = findIndexAlt(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + template <class K> + C* GetAlt(const K& key) { + intptr_t index = findIndexAlt(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + template <class K> + 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<C, HashF, AltHashF, Allocator, Entry>; + + 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<SelfType*>(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 <class K> + void RemoveAlt(const K& key) { + SelfType* phash = const_cast<SelfType*>(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<C, HashF, AltHashF, Allocator, Entry>; + + 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<SelfType*>(this)->Begin(); + } + ConstIterator End() const { + return const_cast<SelfType*>(this)->End(); + } + + template <class K> + Iterator Find(const K& key) { + intptr_t index = findIndex(key); + if (index >= 0) + return Iterator(this, index); + return Iterator(NULL, 0); + } + + template <class K> + Iterator FindAlt(const K& key) { + intptr_t index = findIndexAlt(key); + if (index >= 0) + return Iterator(this, index); + return Iterator(NULL, 0); + } + + template <class K> + ConstIterator Find(const K& key) const { + return const_cast<SelfType*>(this)->Find(key); + } + + template <class K> + ConstIterator FindAlt(const K& key) const { + return const_cast<SelfType*>(this)->FindAlt(key); + } + + private: + // Find the index of the matching Entry. If no match, then return -1. + template <class K> + intptr_t findIndex(const K& key) const { + if (pTable == NULL) + return -1; + size_t hashValue = HashF()(key) & pTable->SizeMask; + return findIndexCore(key, hashValue); + } + + template <class K> + 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 <class K> + 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 <class CRef> + 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<C>, + class AltHashF = HashF, + class Allocator = ContainerAllocator<C>, + class Entry = HashsetCachedEntry<C, HashF>> +class HashSet : public HashSetBase<C, HashF, AltHashF, Allocator, Entry> { + public: + typedef HashSetBase<C, HashF, AltHashF, Allocator, Entry> BaseType; + typedef HashSet<C, HashF, AltHashF, Allocator, Entry> 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 <class CRef> + void Set(const CRef& key) { + BaseType::Set(key); + } + + template <class CRef> + 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<C>, + class AltHashF = HashF, + class Allocator = ContainerAllocator<C>> +class HashSetUncached : public HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF>> { + public: + typedef HashSetUncached<C, HashF, AltHashF, Allocator> SelfType; + typedef HashSet<C, HashF, AltHashF, Allocator, HashsetEntry<C, HashF>> 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 <class C, class U, class HashF> +struct HashNode { + typedef HashNode<C, U, HashF> 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 <class K> + bool operator==(const K& src) const { + return (First == src); + } + + template <class K> + 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 <class K> + size_t operator()(const K& data) const { + return data.GetHash(); + } + }; + struct NodeAltHashF { + template <class K> + size_t operator()(const K& data) const { + return HashNode<C, U, HashF>::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 C, class HashF> +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 C, class HashF> +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<C>, + class Allocator = ContainerAllocator<C>, + class HashNode = OVR::HashNode<C, U, HashF>, + class Entry = HashsetCachedNodeEntry<HashNode, typename HashNode::NodeHashF>, + 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<C, U, HashF, Allocator, HashNode, Entry, Container> 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 <class K> + 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 <class K> + 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 <class K> + inline U* GetAlt(const K& key) { + HashNode* p = mHash.GetAlt(key); + return p ? &p->Second : 0; + } + template <class K> + 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 <class K> + Iterator FindAlt(const K& key) { + return mHash.FindAlt(key); + } + template <class K> + ConstIterator FindAlt(const K& key) const { + return mHash.FindAlt(key); + } +}; + +// Hash with uncached hash code; declared for convenience. +template <class C, class U, class HashF = FixedSizeHash<C>, class Allocator = ContainerAllocator<C>> +class HashUncached + : public Hash< + C, + U, + HashF, + Allocator, + HashNode<C, U, HashF>, + HashsetNodeEntry<HashNode<C, U, HashF>, typename HashNode<C, U, HashF>::NodeHashF>> { + public: + typedef HashUncached<C, U, HashF, Allocator> SelfType; + typedef Hash< + C, + U, + HashF, + Allocator, + HashNode<C, U, HashF>, + HashsetNodeEntry<HashNode<C, U, HashF>, typename HashNode<C, U, HashF>::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 C, class U, class Allocator = ContainerAllocator<C>, class HashF = IdentityHash<C>> +class HashIdentity : public HashUncached<C, U, HashF, Allocator> { + public: + typedef HashIdentity<C, U, Allocator, HashF> SelfType; + typedef HashUncached<C, U, HashF, Allocator> 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 <ctype.h> +#include <float.h> +#include <limits.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#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<JSON>, public ListNode<JSON> { + protected: + List<JSON> Children; + + public: + JSONItemType Type; // Type of this JSON node. + String Name; // Name part of the {Name, Value} pair in a parent object. + String Value; + double dValue; + + public: + ~JSON(); + + // *** Creation of NEW JSON objects + + static JSON* CreateObject() { + return new JSON(JSON_Object); + } + static JSON* CreateNull() { + return new JSON(JSON_Null); + } + static JSON* CreateArray() { + return new JSON(JSON_Array); + } + static JSON* CreateBool(bool b); + 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 <typename T> + 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 <typename T> + 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<MyData> +// { +// . . . +// }; + +template <class T> +class ListNode { + private: + ListNode<T>* pPrev; + ListNode<T>* pNext; + + template <class X, class B> + 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<T>* 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>. B specifies the base class that was directly +// derived from ListNode, and is only necessary if there is an intermediate +// inheritance chain. + +template <class T, class B = T> +class List { + public: + typedef T ValueType; + + List() { + Root.pNext = Root.pPrev = &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<B>* 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<B>* 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<T>& 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<T>& 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<T>& 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<T>& 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<T>* 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<T>&); + const List<T>& operator=(const List<T>&); + + ListNode<B> Root; +}; + +//------------------------------------------------------------------------ +// ***** FreeListElements +// +// Remove all elements in the list and free them in the allocator + +template <class List, class Allocator> +void FreeListElements(List& list, Allocator& allocator) { + typename List::ValueType* self = list.GetFirst(); + while (!list.IsNull(self)) { + typename List::ValueType* next = list.GetNext(self); + allocator.Free(self); + self = next; + } + list.Clear(); +} + +} // 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 <cstring> +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 T, class SlotType = T> +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<int> UpdateBegin = {0}; + std::atomic<int> 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 <class Payload, int PaddingSize> +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<int> 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 <new> + +#if defined(_MSC_VER) + #pragma warning(push, 0) + #include <malloc.h> + #include <crtdbg.h> + + #include <math.h> // Work around VS header bug by #including math.h then intrin.h. + #if (_MSC_VER >= 1500) + #include <intrin.h> + #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 <cstddef.h> 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 <typename T> + operator T*() const { + return 0; + } + + template <typename C, typename T> + 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 <typename T> +inline bool operator==(T* pT, const std::nullptr_t) { + return pT == 0; +} + +template <typename T> +inline bool operator==(const std::nullptr_t, T* pT) { + return pT == 0; +} + +template <typename T, typename U> +inline bool operator==(const std::nullptr_t, T U::*pU) { + return pU == 0; +} + +template <typename T, typename U> +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 C> +class RefCountBase; +template <class C> +class RefCountBaseNTS; + +class RefCountImpl; +class RefCountNTSImpl; + +//----------------------------------------------------------------------------------- +// ***** Implementation For Reference Counting + +// RefCountImplCore holds RefCount value and defines a few utility +// functions shared by all implementations. + +class RefCountImplCore { + protected: + std::atomic<int> 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 Base> +class RefCountBaseStatImpl : public Base { + public: + RefCountBaseStatImpl() {} + +// *** Override New and Delete + +// DOM-IGNORE-BEGIN +// Undef new temporarily if it is being redefined +#ifdef OVR_DEFINE_NEW +#undef new +#endif + +#ifdef OVR_BUILD_DEBUG +// Custom check used to detect incorrect calls of 'delete' on ref-counted objects. +#define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) \ + do { \ + if (p) \ + Base::checkInvalidDelete((class_name*)p); \ + } while (0) +#else +#define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) +#endif + + // Redefine all new & delete operators. + OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE) + +#undef OVR_REFCOUNTALLOC_CHECK_DELETE + +#ifdef OVR_DEFINE_NEW +#define new OVR_DEFINE_NEW +#endif + // OVR_BUILD_DEFINE_NEW + // DOM-IGNORE-END +}; + +template <class Base> +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 C> +class RefCountBase : public RefCountBaseStatImpl<RefCountImpl> { + public: + // Constructor. + OVR_FORCE_INLINE RefCountBase() : RefCountBaseStatImpl<RefCountImpl>() {} +}; + +// RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release + +template <class C> +class RefCountBaseV : virtual public RefCountBaseStatVImpl<RefCountVImpl> { + public: + // Constructor. + OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatVImpl<RefCountVImpl>() {} +}; + +// RefCountBaseNTS is a base class for classes that require Non-Thread-Safe reference +// counting; it also overrides the new and delete operators to use MemoryHeap. +// This class should only be used if all pointers to it are known to be assigned, +// destroyed and manipulated within one thread. +// +// Reference counted objects start out with RefCount value of 1. Further lifetime +// management is done through the AddRef() and Release() methods, typically +// hidden by Ptr<>. + +template <class C> +class RefCountBaseNTS : public RefCountBaseStatImpl<RefCountNTSImpl> { + public: + // Constructor. + OVR_FORCE_INLINE RefCountBaseNTS() : RefCountBaseStatImpl<RefCountNTSImpl>() {} +}; + +//----------------------------------------------------------------------------------- +// ***** 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<C>& operator= (C&) +// Ptr<C>& 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<Widget> w = *new Widget; // Calls the Ptr(C&) constructor. Note that the Widget +// constructor sets initial refcount to 1. +// + +template <class C> +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<C>& src) { + if (src.pObject) + src.pObject->AddRef(); + pObject = src.pObject; + } + + template <class R> + OVR_FORCE_INLINE Ptr(Ptr<R>& src) { + if (src) + src->AddRef(); + pObject = src; + } + + // Destructor + OVR_FORCE_INLINE ~Ptr() { + if (pObject) + pObject->Release(); + } + + // Compares + OVR_FORCE_INLINE bool operator==(const Ptr& other) const { + return pObject == other.pObject; + } + + OVR_FORCE_INLINE bool operator!=(const Ptr& other) const { + return pObject != other.pObject; + } + + OVR_FORCE_INLINE bool operator==(C* pother) const { + return pObject == pother; + } + + OVR_FORCE_INLINE bool operator!=(C* pother) const { + return pObject != pother; + } + + OVR_FORCE_INLINE bool operator<(const Ptr& other) const { + return pObject < other.pObject; + } + + // Assignment + template <class R> + OVR_FORCE_INLINE const Ptr<C>& operator=(const Ptr<R>& src) { + // 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<C>& operator=(const Ptr<C>& src) { + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + + OVR_FORCE_INLINE const Ptr<C>& operator=(C* psrc) { + if (psrc) + psrc->AddRef(); + if (pObject) + pObject->Release(); + pObject = psrc; + return *this; + } + + // This operator adopts the object's existing reference count rather than increment it. + OVR_FORCE_INLINE const Ptr<C>& operator=(C& src) { + if (pObject) + pObject->Release(); + pObject = &src; + return *this; + } + + // Set Assignment + template <class R> + OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<R>& src) { + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + // Specialization + OVR_FORCE_INLINE Ptr<C>& SetPtr(const Ptr<C>& src) { + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + + OVR_FORCE_INLINE Ptr<C>& SetPtr(C* psrc) { + if (psrc) + psrc->AddRef(); + if (pObject) + pObject->Release(); + pObject = psrc; + return *this; + } + + // This function adopts the object's existing reference count rather than increment it. + OVR_FORCE_INLINE Ptr<C>& 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 T> +class LockedPtr { + public: + LockedPtr(Lock* lock = nullptr) : TheLock(lock) {} + + void Set(T* value) { + OVR_ASSERT(TheLock); + TheLock->DoLock(); + Ptr<T> 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 <class S> + void Get(Ptr<S>& outputPtr) const { + OVR_ASSERT(TheLock); + TheLock->DoLock(); + Ptr<T> retval = ThePtr; + TheLock->Unlock(); + outputPtr = retval; + } + + protected: + mutable Lock* TheLock; + Ptr<T> 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 <Sddl.h> // ConvertStringSecurityDescriptorToSecurityDescriptor +#endif // OVR_OS_WIN32 + +#if defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) +#include <errno.h> // error results for mmap +#include <fcntl.h> // O_ constants +#include <sys/mman.h> // shm_open(), mmap() +#include <sys/stat.h> // mode constants +#include <unistd.h> // 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<FakeMemoryBlock> { + String Name; + std::unique_ptr<char[]> 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<FakeMemoryBlock> Block; + + FakeMemoryInternal(FakeMemoryBlock* block); + ~FakeMemoryInternal(); + + virtual void* GetFileView() override { + return FileView; + } +}; + +//----------------------------------------------------------------------------- +// FakeMemoryManager + +class FakeMemoryManager : public NewOverrideBase, public SystemSingletonBase<FakeMemoryManager> { + OVR_DECLARE_SINGLETON(FakeMemoryManager); + + Lock FakeLock; + Array<Ptr<FakeMemoryBlock>> 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<FakeMemoryBlock> 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<SharedMemory> SharedMemoryFactory::Open(const SharedMemory::OpenParameters& params) { + Ptr<SharedMemory> 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<SharedMemory> { + 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<SharedMemoryFactory> { + 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<SharedMemory> Open(const SharedMemory::OpenParameters&); +}; + +// A shared object +// Its constructor will be called when creating a writer +// Its destructor will not be called +template <class SharedType> +class ISharedObject : public RefCountBase<ISharedObject<SharedType>> { + public: + static const int RegionSize = (int)sizeof(SharedType); + + protected: + Ptr<SharedMemory> 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<SharedType>(pSharedMemory->GetData()); + } + + return true; + } + + return false; + } + + SharedType* Get() const { + if (!pSharedMemory) { + return NULL; + } + + void* data = pSharedMemory->GetData(); + if (!data) { + return NULL; + } + + return reinterpret_cast<SharedType*>(data); + } + + public: + String GetName() const { + return pSharedMemory ? pSharedMemory->GetName() : String{""}; + } +}; + +// Writer specialized shared object: Ctor will be called on Open() +template <class SharedType> +class SharedObjectWriter : public ISharedObject<SharedType> { + public: + OVR_FORCE_INLINE bool Open(const char* name) { + return ISharedObject<SharedType>::Open(name, false); + } + OVR_FORCE_INLINE SharedType* Get() { + return ISharedObject<SharedType>::Get(); + } +}; + +// Reader specialized shared object: Ctor will not be called +template <class SharedType> +class SharedObjectReader : public ISharedObject<SharedType> { + public: + OVR_FORCE_INLINE bool Open(const char* name) { + return ISharedObject<SharedType>::Open(name, true); + } + OVR_FORCE_INLINE const SharedType* Get() const { + return ISharedObject<SharedType>::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 <locale.h> + +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<char*>(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<wchar_t*>(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 <locale.h> +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 <ctype.h> +#include <stdarg.h> // for va_list args +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "OVR_Types.h" + +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) +#define OVR_MSVC_SAFESTRING +#include <errno.h> +#endif + +// Wide-char funcs +#include <wchar.h> +#include <wctype.h> + +namespace OVR { + +// 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 <ctype.h> +#include <stdlib.h> +#include <atomic> + +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<int>(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 <stdarg.h> +#include <string> +#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 U, class Allocator = ContainerAllocator<U>> +class StringHash : public Hash<String, U, String::NoCaseHashFunctor, Allocator> { + public: + typedef U ValueType; + typedef StringHash<U, Allocator> SelfType; + typedef Hash<String, U, String::NoCaseHashFunctor, Allocator> BaseType; + + public: + void operator=(const SelfType& src) { + BaseType::operator=(src); + } + + bool GetCaseInsensitive(const String& key, U* pvalue) const { + String::NoCaseKey ikey(key); + return BaseType::GetAlt(ikey, pvalue); + } + // Pointer-returning get variety. + const U* GetCaseInsensitive(const String& key) const { + String::NoCaseKey ikey(key); + return BaseType::GetAlt(ikey); + } + U* GetCaseInsensitive(const String& key) { + String::NoCaseKey ikey(key); + return BaseType::GetAlt(ikey); + } + + typedef typename BaseType::Iterator base_iterator; + + base_iterator FindCaseInsensitive(const String& key) { + String::NoCaseKey ikey(key); + return BaseType::FindAlt(ikey); + } + + // Set just uses a find and assigns value if found. The key is not modified; + // this behavior is identical to Flash string variable assignment. + void SetCaseInsensitive(const String& key, const U& value) { + base_iterator it = FindCaseInsensitive(key); + if (it != BaseType::End()) { + it->Second = value; + } else { + BaseType::Add(key, value); + } + } +}; + +} // 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 <stdarg.h> +#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 <stdio.h> + +#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<File> 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 <new> +#include "Logging/Logging_Library.h" +#include "OVR_DebugHelp.h" +#include "OVR_Threads.h" +#include "OVR_Timer.h" + +#if defined(_MSC_VER) +#include <new.h> +#else +#include <new> +#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 T> +class SystemSingletonBase : public SystemSingletonInternal { + static std::atomic<T*> 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 <class T> +std::atomic<T*> OVR::SystemSingletonBase<T>::SingletonInstance; + +// Place this in the singleton class in the header file +#define OVR_DECLARE_SINGLETON(T) \ + friend class OVR::SystemSingletonBase<T>; \ + \ + 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<T>::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 <condition_variable> +#include <memory> +#include <mutex> + +#if !defined(_WIN32) +#include <unistd.h> +#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<MutexImpl> pImpl; + + public: + // Constructor/destructor + Mutex(bool recursive = 1); + ~Mutex(); + + // Locking functions + void DoLock(); + bool TryLock(); + void Unlock(); + + // Returns 1 if the mutes is currently locked by another thread + // Returns 0 if the mutex is not locked by another thread, and can therefore be acquired. + bool IsLockedByAnotherThread(); + + // Locker class; Used for automatic locking of a mutex withing scope + class Locker { + public: + Mutex* pMutex; + Locker(Mutex* pmutex) : pMutex(pmutex) { + pMutex->DoLock(); + } + Locker(const std::unique_ptr<Mutex>& 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 <errno.h> +#include <pthread.h> +#include <sched.h> +#include <sys/time.h> +#include <time.h> +#include <unistd.h> +#include "OVR_Timer.h" + +#if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) +#include <sys/param.h> +#include <sys/sysctl.h> +#if !defined(OVR_OS_MAC) +#include <pthread_np.h> +#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<std::mutex> 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<std::mutex> 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 <process.h> + +#ifdef _WIN32 +#include <processthreadsapi.h> +#include <sdkddkver.h> +#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)) { +// <use 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<std::mutex> 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<std::mutex> 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 <MMSystem.h> +#pragma comment(lib, "winmm.lib") +#elif defined(OVR_OS_ANDROID) +#include <android/log.h> +#include <time.h> +#else +#include <chrono> +#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<double, std::chrono::seconds::period>; + + 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<double, std::chrono::seconds::period>; + + 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<uint64_t, std::chrono::nanoseconds::period>; + + 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::steady_clock::duration>( + 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::steady_clock::duration>( + 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 <chrono> +#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 <cstddef> +#include "OVR_Compiler.h" + +#if defined(_WIN32) && defined(OVR_KILL_WINDOWS_A_FUNCTIONS) +#include <commctrl.h> +#include "OVR_Win32_IncludeWindows.h" +#pragma warning(push) +#pragma warning(disable : 4091) +#include <DbgHelp.h> +#pragma warning(pop) +#include <Cfgmgr32.h> +#include <Psapi.h> +#include <Sddl.h> +#include <SetupAPI.h> +#include <ShlObj.h> +#include <Shlwapi.h> +#include <WtsApi32.h> +#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 <float.h> +#include <limits.h> +#include <stddef.h> + +// MSVC Based Memory Leak checking - for now +#if defined(OVR_CC_MSVC) && defined(OVR_BUILD_DEBUG) +#define _CRTDBG_MAP_ALLOC +#include <crtdbg.h> +#include <stdlib.h> +#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 <stdint.h> +#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 <sys/types.h> +typedef int8_t SByte; +typedef uint8_t UByte; +typedef int16_t SInt16; +typedef uint16_t UInt16; +typedef int32_t SInt32; +typedef uint32_t UInt32; +typedef int64_t SInt64; +typedef uint64_t UInt64; + +#endif + +// 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<const volatile char&>((((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 <stdlib.h> +#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 <stdlib.h> + +// 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 <emmintrin.h> +#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<int64_t>(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 <class DestType, class SourceType> +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); +// <use argList and argListCopy> +// +// 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 <typename R> +struct OVRArrayCountOf_helper; + +template <typename T, std::size_t N> +struct OVRArrayCountOf_helper<T[N]> { + enum : std::size_t { size = N }; +}; + +template <typename T, std::size_t N> +struct OVRArrayCountOf_helper<T (&)[N]> { + enum : std::size_t { size = N }; +}; + +template <typename T> +constexpr std::size_t OVRArrayCountOf() { + return OVRArrayCountOf_helper<T>::size; +} + +#define OVR_ARRAY_COUNT(x) OVRArrayCountOf<decltype(x)>() +#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 <string.h> +#include <wchar.h> + +// 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 <Windows.h> from #including <Winsock.h>, as we use <Winsock2.h> instead. +#ifndef _WINSOCKAPI_ +#define DID_DEFINE_WINSOCKAPI +#define _WINSOCKAPI_ +#endif + +// Prevents <Windows.h> 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 <Windows.h> +#undef WIN32_NO_STATUS +#include <ntstatus.h> +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 <wrl.h> 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 <typename Traits> +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<ScopedHANDLE_NullTraits> ScopedMutexHANDLE; +typedef ScopedHANDLE<ScopedHANDLE_NullTraits> ScopedEventHANDLE; +typedef ScopedHANDLE<ScopedHANDLE_InvalidTraits> ScopedFileHANDLE; +typedef ScopedHANDLE<ScopedHANDLE_NullTraits> ScopedProcessHANDLE; +typedef ScopedHANDLE<ScopedHANDLE_NullTraits> ScopedThreadHANDLE; +typedef ScopedHANDLE<ScopedHANDLE_NullTraits> 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 <evntrace.h> +#include <wmistr.h> +#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 @@ +<?xml version="1.0"?>
+<instrumentationManifest xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd" xmlns="http://schemas.microsoft.com/win/2004/08/events" xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:trace="http://schemas.microsoft.com/win/2004/08/events/trace">
+ <instrumentation>
+ <events>
+ <provider name="OVR-SDK-LibOVR" guid="{553787FC-D3D7-4F5E-ACB2-1597C7209B3C}" symbol="LibOVRProvider" resourceFileName="res" messageFileName="msg">
+ <events>
+ <event symbol="Call" value="0" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Function" opcode="Call" template="FunctionWaypoint" message="$(string.OVR-SDK-LibOVR.event.0.message)"></event>
+ <event symbol="Return" value="1" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Function" opcode="Return" template="FunctionWaypoint" message="$(string.OVR-SDK-LibOVR.event.1.message)"></event>
+ <event symbol="Waypoint" value="2" version="0" channel="LibOVR/Debug" level="win:Informational" task="Function" opcode="Waypoint" template="FunctionWaypoint" message="$(string.OVR-SDK-LibOVR.event.2.message)"></event>
+ <event symbol="DistortionBegin" value="4" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Distort" opcode="Begin" template="Distortion" message="$(string.OVR-SDK-LibOVR.event.4.message)"></event>
+ <event symbol="DistortionWaitGPU" value="5" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Distort" opcode="WaitGPU" template="Distortion" message="$(string.OVR-SDK-LibOVR.event.5.message)"></event>
+ <event symbol="DistortionPresent" value="6" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Distort" opcode="Present" template="Distortion" message="$(string.OVR-SDK-LibOVR.event.6.message)"></event>
+ <event symbol="DistortionEnd" value="7" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Distort" opcode="End" template="Distortion" message="$(string.OVR-SDK-LibOVR.event.7.message)"></event>
+ <event symbol="HmdDesc_v0" value="8" version="0" channel="LibOVR/Analytic" level="win:Informational" task="HmdInfo" opcode="HmdDesc" template="HmdDesc_v0" message="$(string.OVR-SDK-LibOVR.event.8.message)"></event>
+ <event symbol="HmdDesc" value="8" version="1" channel="LibOVR/Analytic" level="win:Informational" task="HmdInfo" opcode="HmdDesc" template="HmdDesc" message="$(string.OVR-SDK-LibOVR.event.8.message)"></event>
+ <event symbol="CameraFrameReceived_v0" value="9" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="Receive" template="CameraFrameData_v0" message="$(string.OVR-SDK-LibOVR.event.9.message)"></event>
+ <event symbol="CameraFrameReceived" value="9" version="1" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="Receive" template="CameraFrameData" message="$(string.OVR-SDK-LibOVR.event.9.message)"></event>
+ <event symbol="CameraBeginProcessing_v0" value="10" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="Begin" template="CameraFrameData_v0" message="$(string.OVR-SDK-LibOVR.event.10.message)"></event>
+ <event symbol="CameraBeginProcessing" value="10" version="1" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="Begin" template="CameraFrameData" message="$(string.OVR-SDK-LibOVR.event.10.message)"></event>
+ <event symbol="CameraFrameRequest" value="11" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="Request" template="CameraFrameRequest" message="$(string.OVR-SDK-LibOVR.event.11.message)"></event>
+ <event symbol="CameraEndProcessing_v0" value="12" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="End" template="CameraFrameData_v0" message="$(string.OVR-SDK-LibOVR.event.12.message)"></event>
+ <event symbol="CameraEndProcessing" value="12" version="1" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="End" template="CameraFrameData" message="$(string.OVR-SDK-LibOVR.event.12.message)"></event>
+ <event symbol="CameraSkippedFrames_v0" value="13" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="Waypoint" template="CameraFrameRequest" message="$(string.OVR-SDK-LibOVR.event.13.message)"></event>
+ <event symbol="CameraSkippedFrames" value="13" version="1" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="Waypoint" template="CameraGetFrame" message="$(string.OVR-SDK-LibOVR.event.13.message)"></event>
+ <event symbol="JSONChunk" value="14" version="0" channel="LibOVR/Analytic" level="win:Informational" task="HmdInfo" opcode="Waypoint" template="JSONChunk" message="$(string.OVR-SDK-LibOVR.event.14.message)"></event>
+ <event symbol="LogDebugMessage" value="15" version="0" channel="LibOVR/Debug" level="win:Verbose" task="Log" opcode="Waypoint" template="Log" message="$(string.OVR-SDK-LibOVR.event.15.message)"></event>
+ <event symbol="LogInfoMessage" value="16" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Log" opcode="Waypoint" template="Log" message="$(string.OVR-SDK-LibOVR.event.16.message)"></event>
+ <event symbol="LogErrorMessage" value="17" version="0" channel="LibOVR/Error" level="win:Error" task="Log" opcode="Waypoint" template="Log" message="$(string.OVR-SDK-LibOVR.event.17.message)"></event>
+ <event symbol="HmdTrackingState" value="18" version="0" channel="LibOVR/Analytic" level="win:Informational" task="HmdInfo" opcode="Waypoint" template="HmdTrackingState" message="$(string.OVR-SDK-LibOVR.event.18.message)"></event>
+ <event symbol="CameraBlobs_v0" value="19" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="Waypoint" template="CameraBlobs_v0" message="$(string.OVR-SDK-LibOVR.event.19.message)"></event>
+ <event symbol="CameraBlobs" value="19" version="1" channel="LibOVR/Analytic" level="win:Informational" task="Camera" opcode="Waypoint" template="CameraBlobs" message="$(string.OVR-SDK-LibOVR.event.19.message)"></event>
+ <event symbol="PoseLatchCPUWrite" value="30" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Distort" opcode="Begin" template="PoseLLCPUWrite" message="$(string.OVR-SDK-LibOVR.event.30.message)"></event>
+ <event symbol="PoseLatchGPULatchReadback" value="31" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Distort" opcode="End" template="PoseLLGPUReadback" message="$(string.OVR-SDK-LibOVR.event.31.message)"></event>
+ <event symbol="QueueAheadDelayBegin" value="32" version="0" channel="LibOVR/Analytic" level="win:Informational" task="SubmitFrame" opcode="Begin" template="QueueAhead" message="$(string.OVR-SDK-LibOVR.event.32.message)"></event>
+ <event symbol="QueueAheadDelayEnd" value="33" version="0" channel="LibOVR/Analytic" level="win:Informational" task="SubmitFrame" opcode="End" template="QueueAhead" message="$(string.OVR-SDK-LibOVR.event.33.message)"></event>
+ <event symbol="HmdDisplay" value="34" version="0" channel="LibOVR/Analytic" level="win:Informational" task="HmdInfo" opcode="HmdDesc" template="HmdDisplay" message="$(string.OVR-SDK-LibOVR.event.34.message)"></event>
+ <event symbol="PhaseSyncBegin" value="35" version="0" channel="LibOVR/Analytic" level="win:Informational" task="PhaseSync" opcode="Begin" template="PhaseSyncBegin" message="$(string.OVR-SDK-LibOVR.event.35.message)"></event>
+ <event symbol="PhaseSyncEnd" value="36" version="0" channel="LibOVR/Analytic" level="win:Informational" task="PhaseSync" opcode="End" template="PhaseSyncEnd" message="$(string.OVR-SDK-LibOVR.event.36.message)"></event>
+ <event symbol="VSync" value="37" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Distort" opcode="Present" template="RecordedVSync" message="$(string.OVR-SDK-LibOVR.event.37.message)"></event>
+ <event symbol="AppCompositorFocus" value="38" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Log" opcode="Waypoint" template="AppEvent" message="$(string.OVR-SDK-LibOVR.event.38.message)"></event>
+ <event symbol="AppConnect" value="39" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Log" opcode="Waypoint" template="AppEvent" message="$(string.OVR-SDK-LibOVR.event.39.message)"></event>
+ <event symbol="AppDisconnect" value="40" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Log" opcode="Waypoint" template="AppEvent" message="$(string.OVR-SDK-LibOVR.event.40.message)"></event>
+ <event symbol="AppNoOp" value="41" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Log" opcode="Waypoint" template="AppEvent" message="$(string.OVR-SDK-LibOVR.event.41.message)"></event>
+ <event symbol="PosePrediction" value="42" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Sensor" opcode="Begin" template="PosePrediction" message="$(string.OVR-SDK-LibOVR.event.42.message)"></event>
+ <event symbol="LatencyTiming" value="43" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Log" opcode="Waypoint" template="LatencyTiming" message="$(string.OVR-SDK-LibOVR.event.43.message)"></event>
+ <event symbol="EndFrameAppTiming" value="44" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Log" opcode="Waypoint" template="EndFrameAppTiming" message="$(string.OVR-SDK-LibOVR.event.44.message)"></event>
+ <event symbol="HardwareInfo" value="45" version="0" channel="LibOVR/Analytic" level="win:Informational" task="HmdInfo" opcode="Waypoint" template="HardwareInfoTemplate" message="$(string.OVR-SDK-LibOVR.event.45.message)"></event>
+ <event symbol="VirtualDisplayPacketTrace" value="46" version="0" channel="LibOVR/Analytic" level="win:Informational" task="VirtualDisplay" opcode="Waypoint" template="VirtualDisplayPacketTemplate" message="$(string.OVR-SDK-LibOVR.event.46.message)"></event>
+ <event symbol="ClientFrameMissed" value="47" version="0" channel="LibOVR/Analytic" level="win:Informational" task="VirtualDisplay" opcode="Waypoint" template="ClientMissedFrame" message="$(string.OVR-SDK-LibOVR.event.47.message)"></event>
+ <event symbol="CompositionBegin" value="48" version="0" channel="LibOVR/Analytic" level="win:Informational" task="CompositorRunLoop" opcode="Begin" template="CompositionBegin" message="$(string.OVR-SDK-LibOVR.event.48.message)"></event>
+ <event symbol="CompositionEnd" value="49" version="0" channel="LibOVR/Analytic" level="win:Informational" task="CompositorRunLoop" opcode="End" message="$(string.OVR-SDK-LibOVR.event.49.message)"></event>
+ <event symbol="RenderPacketTrace" value="50" version="0" channel="LibOVR/Analytic" level="win:Informational" task="VirtualDisplay" opcode="Waypoint" template="RenderPacketTemplate" message="$(string.OVR-SDK-LibOVR.event.50.message)"></event>
+ <event symbol="EndFrameOrigAppTiming" value="51" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Log" opcode="Begin" template="EndFrameAppTiming" message="$(string.OVR-SDK-LibOVR.event.51.message)"></event>
+ <event symbol="DistortionEndToEndTiming" value="52" version="0" channel="LibOVR/Analytic" level="win:LogAlways" task="CompositorRunLoop" opcode="Call" template="DistortionEndToEndTiming" message="$(string.OVR-SDK-LibOVR.event.52.message)"></event>
+ <event symbol="CompositionEndSpinWait" value="53" version="0" channel="LibOVR/Analytic" level="win:Informational" task="CompositorRunLoop" opcode="End" message="$(string.OVR-SDK-LibOVR.event.53.message)"></event>
+ <event symbol="CompositionFlushingToGPU" value="54" version="0" channel="LibOVR/Analytic" level="win:Informational" task="CompositorRunLoop" opcode="Waypoint" message="$(string.OVR-SDK-LibOVR.event.54.message)"></event>
+ <event symbol="PhaseSyncGPUCompleted" value="55" version="0" channel="LibOVR/Analytic" level="win:Informational" task="PhaseSync" opcode="Waypoint" template="PhaseSyncAppGPUEndTime" message="$(string.OVR-SDK-LibOVR.event.55.message)"></event>
+ <event symbol="CompositionMissedCompositorFrame" value="56" version="0" channel="LibOVR/Analytic" level="win:Informational" task="CompositorRunLoop" opcode="Waypoint" message="$(string.OVR-SDK-LibOVR.event.56.message)"></event>
+ <event symbol="CompositionGPUStartTime" value="57" version="0" channel="LibOVR/Analytic" level="win:Informational" task="CompositorRunLoop" opcode="Waypoint" template="CompositionGPUBeginTime" message="$(string.OVR-SDK-LibOVR.event.57.message)"></event>
+ <event symbol="NotificationBegin" value="58" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Notification" opcode="Waypoint" template="NotificationBegin" message="$(string.OVR-SDK-LibOVR.event.58.message)"></event>
+ <event symbol="NotificationEnd" value="59" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Notification" opcode="Waypoint" template="NotificationEnd" message="$(string.OVR-SDK-LibOVR.event.59.message)"></event>
+ <event symbol="NotificationCompSubmit" value="60" version="0" channel="LibOVR/Analytic" level="win:Informational" task="Notification" opcode="Waypoint" template="NotificationCompSubmit" message="$(string.OVR-SDK-LibOVR.event.60.message)"></event>
+ <event symbol="MotionEstimationCostStats" value="61" version="0" channel="LibOVR/Analytic" level="win:Informational" task="CompositorRunLoop" opcode="Waypoint" template="MotionEstimationCostStats" message="$(string.OVR-SDK-LibOVR.event.61.message)"></event>
+ <event symbol="PhaseSyncWaitToBeginFrame" value="62" version="0" channel="LibOVR/Analytic" level="win:Informational" task="PhaseSync" opcode="Waypoint" template="PhaseSyncWaitToBeginFrame" message="$(string.OVR-SDK-LibOVR.event.63.message)"></event>
+ <event symbol="PhaseSyncBeginFrame" value="63" version="0" channel="LibOVR/Analytic" level="win:Informational" task="PhaseSync" opcode="Waypoint" template="PhaseSyncBeginFrame" message="$(string.OVR-SDK-LibOVR.event.64.message)"></event>
+ <event symbol="PhaseSyncEndFrame" value="64" version="0" channel="LibOVR/Analytic" level="win:Informational" task="PhaseSync" opcode="Waypoint" template="PhaseSyncEndFrame" message="$(string.OVR-SDK-LibOVR.event.65.message)"></event>
+ <event symbol="PhaseSyncCompleteFrame" value="65" version="0" channel="LibOVR/Analytic" level="win:Informational" task="PhaseSync" opcode="Waypoint" template="PhaseSyncCompleteFrame" message="$(string.OVR-SDK-LibOVR.event.66.message)"></event>
+ </events>
+ <levels></levels>
+ <tasks>
+ <task name="Function" symbol="FN_TRACE" value="1" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.FN_TRACE.message)"></task>
+ <task name="Distort" symbol="DIS_TRACE" value="2" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.DIS_TRACE.message)"></task>
+ <task name="HmdInfo" symbol="HMD_TRACE" value="3" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.HMD_TRACE.message)"></task>
+ <task name="Camera" symbol="CAMERA_TRACE" value="4" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.CAMERA_TRACE.message)"></task>
+ <task name="Log" symbol="LOG_TRACE" value="5" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.LOG_TRACE.message)"></task>
+ <task name="SubmitFrame" symbol="SUBMITFRAME_TRACE" value="6" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.SUBMITFRAME_TRACE.message)"></task>
+ <task name="PhaseSync" symbol="PHASESYNC_TRACE" value="7" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.PHASESYNC_TRACE.message)"></task>
+ <task name="Sensor" symbol="SENSOR_TRACE" value="8" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.SENSOR_TRACE.message)"></task>
+ <task name="VirtualDisplay" symbol="VIRTUALDISPLAY_TRACE" value="9" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.VIRTUALDISPLAY_TRACE.message)"></task>
+ <task name="CompositorRunLoop" symbol="COMPOSITOR_RUNLOOP_TRACE" value="10" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.Compositor_RunLoop.message)"></task>
+ <task name="Notification" symbol="NOTIFICATION_TRACE" value="11" eventGUID="{00000000-0000-0000-0000-000000000000}" message="$(string.OVR-SDK-LibOVR.task.NOTIFICATION_TRACE.message)"></task>
+ </tasks>
+ <opcodes>
+ <opcode name="Call" symbol="FN_CALL" value="10" message="$(string.OVR-SDK-LibOVR.opcode.FN_CALL.message)"></opcode>
+ <opcode name="Return" symbol="FN_RETURN" value="11" message="$(string.OVR-SDK-LibOVR.opcode.FN_RETURN.message)"></opcode>
+ <opcode name="Waypoint" symbol="FN_WAYPOINT" value="12" message="$(string.OVR-SDK-LibOVR.opcode.FN_WAYPOINT.message)"></opcode>
+ <opcode name="Begin" symbol="DIS_BEGIN" value="13" message="$(string.OVR-SDK-LibOVR.opcode.DIS_BEGIN.message)"></opcode>
+ <opcode name="WaitGPU" symbol="DIS_WAITGPU" value="14" message="$(string.OVR-SDK-LibOVR.opcode.DIS_WAITGPU.message)"></opcode>
+ <opcode name="Present" symbol="DIS_PRESENT" value="15" message="$(string.OVR-SDK-LibOVR.opcode.DIS_PRESENT.message)"></opcode>
+ <opcode name="End" symbol="DIS_END" value="16" message="$(string.OVR-SDK-LibOVR.opcode.DIS_END.message)"></opcode>
+ <opcode name="HmdDesc" symbol="HMD_DESC" value="17" message="$(string.OVR-SDK-LibOVR.opcode.HMD_DESC.message)"></opcode>
+ <opcode name="Receive" symbol="CAM_RECEIVE" value="18" message="$(string.OVR-SDK-LibOVR.opcode.CAM_RECEIVE.message)"></opcode>
+ <opcode name="Request" symbol="CAM_REQUEST" value="19" message="$(string.OVR-SDK-LibOVR.opcode.CAM_REQUEST.message)"></opcode>
+ </opcodes>
+ <channels>
+ <channel name="LibOVR/Debug" chid="LibOVR/Debug" symbol="DEBUG_CHANNEL" type="Debug" enabled="false"></channel>
+ <channel name="LibOVR/Analytic" chid="LibOVR/Analytic" symbol="ANALYTIC_CHANNEL" type="Analytic" enabled="false"></channel>
+ <channel name="LibOVR/Error" chid="LibOVR/Error" symbol="ERROR_CHANNEL" type="Operational" enabled="false"></channel>
+ </channels>
+ <templates>
+ <template tid="FunctionWaypoint">
+ <data name="Name" inType="win:UnicodeString" outType="xs:string"></data>
+ <data name="Line" inType="win:Int32" outType="xs:int"></data>
+ <data name="FrameID" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ </template>
+ <template tid="Distortion">
+ <data name="VidPnTargetId" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="FrameID" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ </template>
+ <template tid="HmdDesc_v0">
+ <data name="Type" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="VendorId" inType="win:Int16" outType="xs:short"></data>
+ <data name="ProductId" inType="win:Int16" outType="xs:short"></data>
+ <data name="SerialNumber" inType="win:AnsiString" outType="xs:string" length="24"></data>
+ <data name="FirmwareMajor" inType="win:Int16" outType="xs:short"></data>
+ <data name="FirmwareMinor" inType="win:Int16" outType="xs:short"></data>
+ <data name="HmdCaps" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="TrackingCaps" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="DistortionCaps" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="ResolutionWidth" inType="win:Int32" outType="xs:int"></data>
+ <data name="ResolutionHeight" inType="win:Int32" outType="xs:int"></data>
+ </template>
+ <template tid="HmdDesc">
+ <data name="Type" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="VendorId" inType="win:Int16" outType="xs:short"></data>
+ <data name="ProductId" inType="win:Int16" outType="xs:short"></data>
+ <data name="SerialNumber" inType="win:AnsiString" outType="xs:string" length="24"></data>
+ <data name="FirmwareMajor" inType="win:Int16" outType="xs:short"></data>
+ <data name="FirmwareMinor" inType="win:Int16" outType="xs:short"></data>
+ <data name="HmdCaps" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="TrackingCaps" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="ResolutionWidth" inType="win:Int32" outType="xs:int"></data>
+ <data name="ResolutionHeight" inType="win:Int32" outType="xs:int"></data>
+ </template>
+ <template tid="CameraFrameData_v0">
+ <data name="FrameRate" inType="win:Float" outType="xs:float"></data>
+ <data name="FrameNumber" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="ArrivalTimeSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="CaptureTime" inType="win:Double" outType="xs:double"></data>
+ <data name="LostFrames" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ </template>
+ <template tid="CameraFrameData">
+ <data name="Camera" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="FrameNumber" inType="win:Int32" outType="xs:int"></data>
+ <data name="HmdFrameNumber" inType="win:Int32" outType="xs:int"></data>
+ <data name="ArrivalTime" inType="win:Double" outType="xs:double"></data>
+ <data name="CaptureTime" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="CameraFrameRequest">
+ <data name="RequestNumber" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="FrameCounter" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="LastFrameNumber" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ </template>
+ <template tid="CameraGetFrame">
+ <data name="Camera" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="LastFrameNumber" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ </template>
+ <template tid="JSONChunk">
+ <data name="Name" inType="win:UnicodeString" outType="xs:string"></data>
+ <data name="TotalChunks" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="ChunkSequence" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="TotalSize" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="ChunkSize" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="ChunkOffset" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="Chunk" inType="win:Binary" outType="xs:hexBinary" length="ChunkSize"></data>
+ </template>
+ <template tid="Log">
+ <data name="Message" inType="win:AnsiString" outType="xs:string"></data>
+ </template>
+ <template tid="HmdTrackingState">
+ <data name="TimeInSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="HeadPoseQuat" inType="win:Float" outType="xs:float" count="4"></data>
+ <data name="HeadPoseTranslation" inType="win:Float" outType="xs:float" count="3"></data>
+ <data name="HeadAngularVelocity" inType="win:Float" outType="xs:float" count="3"></data>
+ <data name="HeadLinearVelocity" inType="win:Float" outType="xs:float" count="3"></data>
+ <data name="CameraPoseQuat" inType="win:Float" outType="xs:float" count="4"></data>
+ <data name="CameraPoseTranslation" inType="win:Float" outType="xs:float" count="3"></data>
+ <data name="StatusFlags" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ </template>
+ <template tid="CameraBlobs_v0">
+ <data name="BlobCount" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="PositionX" inType="win:Double" outType="xs:double" count="BlobCount"></data>
+ <data name="PositionY" inType="win:Double" outType="xs:double" count="BlobCount"></data>
+ <data name="Size" inType="win:Int32" outType="xs:int" count="BlobCount"></data>
+ </template>
+ <template tid="CameraBlobs">
+ <data name="Camera" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="FrameNumber" inType="win:Int32" outType="xs:int"></data>
+ <data name="ArrivalTime" inType="win:Double" outType="xs:double"></data>
+ <data name="Width" inType="win:Int32" outType="xs:int"></data>
+ <data name="Height" inType="win:Int32" outType="xs:int"></data>
+ <data name="BlobCount" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="PositionX" inType="win:Double" outType="xs:double" count="BlobCount"></data>
+ <data name="PositionY" inType="win:Double" outType="xs:double" count="BlobCount"></data>
+ <data name="Size" inType="win:Int32" outType="xs:int" count="BlobCount"></data>
+ </template>
+ <template tid="PoseLLCPUWrite">
+ <data name="Sequence" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="Layer" inType="win:Int32" outType="xs:int"></data>
+ <data name="MotionSensorTime" inType="win:Float" outType="xs:float"></data>
+ <data name="PredictedScanlineFirst" inType="win:Float" outType="xs:float"></data>
+ <data name="PredictedScanlineLast" inType="win:Float" outType="xs:float"></data>
+ <data name="TimeToScanlineFirst" inType="win:Float" outType="xs:float"></data>
+ <data name="TimeToScanlineLast" inType="win:Float" outType="xs:float"></data>
+ <data name="StartPosition" inType="win:Float" outType="xs:float" count="3"></data>
+ <data name="EndPosition" inType="win:Float" outType="xs:float" count="3"></data>
+ <data name="StartQuat" inType="win:Float" outType="xs:float" count="4"></data>
+ <data name="EndQuat" inType="win:Float" outType="xs:float" count="4"></data>
+ </template>
+ <template tid="QueueAhead">
+ <data name="QueueAheadSeconds" inType="win:Float" outType="xs:float"></data>
+ </template>
+ <template tid="HmdDisplay">
+ <data name="Extended" inType="win:Boolean" outType="xs:boolean"></data>
+ <data name="DeviceTypeGuess" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="EdidVendorId" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="EdidModelNumber" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="DisplayID" inType="win:AnsiString" outType="xs:string"></data>
+ <data name="ModelName" inType="win:AnsiString" outType="xs:string"></data>
+ <data name="EdidSerialNumber" inType="win:AnsiString" outType="xs:string"></data>
+ <data name="LogicalResolutionInPixels_w" inType="win:Int32" outType="xs:int"></data>
+ <data name="LogicalResolutionInPixels_h" inType="win:Int32" outType="xs:int"></data>
+ <data name="NativeResolutionInPixels_w" inType="win:Int32" outType="xs:int"></data>
+ <data name="NativeResolutionInPixels_h" inType="win:Int32" outType="xs:int"></data>
+ <data name="DesktopDisplayOffset_x" inType="win:Int32" outType="xs:int"></data>
+ <data name="DesktopDisplayOffset_y" inType="win:Int32" outType="xs:int"></data>
+ <data name="DeviceNumber" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="Rotation" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="ApplicationExclusive" inType="win:Boolean" outType="xs:boolean"></data>
+ </template>
+ <template tid="PoseLLGPUReadback">
+ <data name="Sequence" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="Layer" inType="win:Int32" outType="xs:int"></data>
+ <data name="MotionSensorTime" inType="win:Float" outType="xs:float"></data>
+ <data name="PredictedScanlineFirst" inType="win:Float" outType="xs:float"></data>
+ <data name="PredictedScanlineLast" inType="win:Float" outType="xs:float"></data>
+ <data name="TimeToScanlineFirst" inType="win:Float" outType="xs:float"></data>
+ <data name="TimeToScanlineLast" inType="win:Float" outType="xs:float"></data>
+ </template>
+ <template tid="PhaseSyncBegin">
+ <data name="LastCompositeTime" inType="win:Double" outType="xs:double"></data>
+ <data name="LastVSyncTime" inType="win:Double" outType="xs:double"></data>
+ <data name="FrameIntervalMS" inType="win:Float" outType="xs:float"></data>
+ <data name="SemaphoreMS" inType="win:Float" outType="xs:float"></data>
+ <data name="SleepMS" inType="win:Float" outType="xs:float"></data>
+ <data name="SpinMS" inType="win:Float" outType="xs:float"></data>
+ <data name="PhaseSyncMS" inType="win:Float" outType="xs:float"></data>
+ <data name="BeginFrameTime" inType="win:Double" outType="xs:double"></data>
+ <data name="TargetCompletionTime" inType="win:Double" outType="xs:double"></data>
+ <data name="TargetCompositeTime" inType="win:Double" outType="xs:double"></data>
+ <data name="TargetVSyncTime" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="PhaseSyncEnd">
+ <data name="BeginFrameTime" inType="win:Double" outType="xs:double"></data>
+ <data name="EndFrameTime" inType="win:Double" outType="xs:double"></data>
+ <data name="CompletionTime" inType="win:Double" outType="xs:double"></data>
+ <data name="CompositeTime" inType="win:Double" outType="xs:double"></data>
+ <data name="VSyncTime" inType="win:Double" outType="xs:double"></data>
+ <data name="FrameTimeMS" inType="win:Float" outType="xs:float"></data>
+ <data name="FrameTimeCpuMS" inType="win:Float" outType="xs:float"></data>
+ <data name="FrameTimeVarianceMS" inType="win:Float" outType="xs:float"></data>
+ <data name="QueueAhead" inType="win:Float" outType="xs:float"></data>
+ <data name="FramesMissed" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="AvgFrameTimeMS" inType="win:Float" outType="xs:float"></data>
+ <data name="AvgFrameTimeCpuMS" inType="win:Float" outType="xs:float"></data>
+ <data name="AvgFrameTimeVarianceMS" inType="win:Float" outType="xs:float"></data>
+ <data name="AvgQueueAhead" inType="win:Float" outType="xs:float"></data>
+ <data name="SyncFrameTimeMS" inType="win:Float" outType="xs:float"></data>
+ <data name="SyncQueueAhead" inType="win:Float" outType="xs:float"></data>
+ <data name="SyncFramesMissed" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="PhaseSyncMS" inType="win:Float" outType="xs:float"></data>
+ </template>
+ <template tid="RecordedVSync">
+ <data name="Time" inType="win:Double" outType="xs:double"></data>
+ <data name="FrameIndex" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="TwGpuEndTime" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="AppEvent">
+ <data name="ProcessID" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ </template>
+ <template tid="PosePrediction">
+ <data name="OriginalPosition" inType="win:Double" outType="xs:double" count="3"></data>
+ <data name="OriginalOrientation" inType="win:Double" outType="xs:double" count="4"></data>
+ <data name="PredictedPosition" inType="win:Double" outType="xs:double" count="3"></data>
+ <data name="PredictedOrientation" inType="win:Double" outType="xs:double" count="4"></data>
+ <data name="PredictionTimeDeltaSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="TimeInSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="id" inType="win:AnsiString" outType="xs:string"></data>
+ </template>
+ <template tid="LatencyTiming">
+ <data name="RenderCpuBegin" inType="win:Double" outType="xs:double"></data>
+ <data name="RenderCpuEnd" inType="win:Double" outType="xs:double"></data>
+ <data name="RenderImu" inType="win:Double" outType="xs:double"></data>
+ <data name="TimewarpCpu" inType="win:Double" outType="xs:double"></data>
+ <data name="TimewarpLatched" inType="win:Double" outType="xs:double"></data>
+ <data name="TimewarpGpuEnd" inType="win:Double" outType="xs:double"></data>
+ <data name="PostPresent" inType="win:Double" outType="xs:double"></data>
+ <data name="ErrorRender" inType="win:Double" outType="xs:double"></data>
+ <data name="ErrorTimewarp" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="EndFrameAppTiming">
+ <data name="FrameIndex" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="RenderImuTime" inType="win:Double" outType="xs:double"></data>
+ <data name="ScanoutStartTime" inType="win:Double" outType="xs:double"></data>
+ <data name="GpuRenderDuration" inType="win:Double" outType="xs:double"></data>
+ <data name="BeginRenderingTime" inType="win:Double" outType="xs:double"></data>
+ <data name="EndRenderingTime" inType="win:Double" outType="xs:double"></data>
+ <data name="QueueAheadSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="RenderCount" inType="win:Int32" outType="xs:int"></data>
+ </template>
+ <template tid="HardwareInfoTemplate">
+ <data name="RequestedBits" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="CollectedBits" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="ImuTemp" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="StmTemp" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="NrfTemp" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="VBusVoltage" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="IAD" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="Proximity" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="PanelOnTime" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="UseRolling" inType="win:Boolean" outType="xs:boolean"></data>
+ <data name="HighBrightness" inType="win:Boolean" outType="xs:boolean"></data>
+ <data name="DP" inType="win:Boolean" outType="xs:boolean"></data>
+ <data name="SelfRefresh" inType="win:Boolean" outType="xs:boolean"></data>
+ <data name="Persistence" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="LightingOffset" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="PixelSettle" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ <data name="TotalRows" inType="win:UInt16" outType="xs:unsignedShort"></data>
+ </template>
+ <template tid="VirtualDisplayPacketTemplate">
+ <data name="PacketType" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="Stage" inType="win:Int32" outType="xs:int"></data>
+ <data name="SubmittingProcessID" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="ActiveProcessID" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ </template>
+ <template tid="ClientMissedFrame">
+ <data name="FrameIndex" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="ProcessID" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ </template>
+ <template tid="RenderPacketTemplate">
+ <data name="Stage" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="ClientPID" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ </template>
+ <template tid="DistortionEndToEndTiming">
+ <data name="ElapsedMs" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="CompositionBegin">
+ <data name="ExpectedCPUStartTimeInSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="ActualCPUStartTimeInSeconds" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="CompositionGPUBeginTime">
+ <data name="DistortionBeginTimeInSeconds" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="PhaseSyncAppGPUEndTime">
+ <data name="AppGPUEndTimeSeconds" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="NotificationEnd">
+ <data name="AppFrameIndex" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="CpuBeginToGpuEndSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="CpuBeginSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="GpuEndSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="SleepTimeMilliseconds" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ </template>
+ <template tid="NotificationBegin">
+ <data name="AppFrameIndex" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="CpuBeginToGpuEndSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="CompositeTimeSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="VSyncTimeSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="CompositeDeltaSeconds" inType="win:Double" outType="xs:double"></data>
+ <data name="VSyncDeltaSeconds" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="NotificationCompSubmit">
+ <data name="ShouldBeVisible" inType="win:Boolean" outType="xs:boolean"></data>
+ <data name="DisabledLayer" inType="win:Boolean" outType="xs:boolean"></data>
+ <data name="FrameIndex" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ </template>
+ <template tid="MotionEstimationCostStats">
+ <data name="Count" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="Average" inType="win:UInt32" outType="xs:unsignedInt"></data>
+ <data name="Log2Histogram" inType="win:UInt32" outType="xs:unsignedInt" count="33"></data>
+ </template>
+ <template tid="PhaseSyncWaitToBeginFrame">
+ <data name="Frame" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="BeginWaitTime" inType="win:Double" outType="xs:double"></data>
+ <data name="SemaphoreMS" inType="win:Float" outType="xs:float"></data>
+ <data name="SleepMS" inType="win:Float" outType="xs:float"></data>
+ <data name="SpinMS" inType="win:Float" outType="xs:float"></data>
+ <data name="EndWaitTime" inType="win:Double" outType="xs:double"></data>
+ <data name="TargetCompletionTime" inType="win:Double" outType="xs:double"></data>
+ <data name="TargetCompositeTime" inType="win:Double" outType="xs:double"></data>
+ <data name="TargetVSyncTime" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="PhaseSyncBeginFrame">
+ <data name="Frame" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="BeginFrameTime" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="PhaseSyncEndFrame">
+ <data name="Frame" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="EndFrameTime" inType="win:Double" outType="xs:double"></data>
+ </template>
+ <template tid="PhaseSyncCompleteFrame">
+ <data name="Frame" inType="win:UInt64" outType="xs:unsignedLong"></data>
+ <data name="CompletionTime" inType="win:Double" outType="xs:double"></data>
+ <data name="CompositeTime" inType="win:Double" outType="xs:double"></data>
+ <data name="VSyncTime" inType="win:Double" outType="xs:double"></data>
+ <data name="FrameTimeMS" inType="win:Float" outType="xs:float"></data>
+ <data name="AvgFrameTimeMS" inType="win:Float" outType="xs:float"></data>
+ <data name="FrameTimeCpuMS" inType="win:Float" outType="xs:float"></data>
+ <data name="AvgFrameTimeCpuMS" inType="win:Float" outType="xs:float"></data>
+ <data name="FrameTimeGpuMS" inType="win:Float" outType="xs:float"></data>
+ <data name="AvgFrameTimeGpuMS" inType="win:Float" outType="xs:float"></data>
+ <data name="FrameVarianceMS" inType="win:Float" outType="xs:float"></data>
+ <data name="AvgFrameVarianceMS" inType="win:Float" outType="xs:float"></data>
+ <data name="QueueAheadMS" inType="win:Float" outType="xs:float"></data>
+ <data name="AvgQueueAheadMS" inType="win:Float" outType="xs:float"></data>
+ <data name="AdaptiveGpuPerformanceScale" inType="win:Float" outType="xs:float"></data>
+ <data name="AvgAdaptiveGpuPerformanceScale" inType="win:Float" outType="xs:float"></data>
+ <data name="PhaseSyncDelayMS" inType="win:Float" outType="xs:float"></data>
+ </template>
+ </templates>
+ </provider>
+ </events>
+ </instrumentation>
+ <localization>
+ <resources culture="en-US">
+ <stringTable>
+ <string id="opcode.Info" value="Info"></string>
+ <string id="level.Verbose" value="Verbose"></string>
+ <string id="level.LogAlways" value="Log Always"></string>
+ <string id="level.Informational" value="Information"></string>
+ <string id="level.Error" value="Error"></string>
+ <string id="OVR-SDK-LibOVR.task.VIRTUALDISPLAY_TRACE.message" value="VirtualDisplay"></string>
+ <string id="OVR-SDK-LibOVR.task.SUBMITFRAME_TRACE.message" value="SubmitFrame"></string>
+ <string id="OVR-SDK-LibOVR.task.SENSOR_TRACE.message" value="Sensor"></string>
+ <string id="OVR-SDK-LibOVR.task.PHASESYNC_TRACE.message" value="PhaseSync"></string>
+ <string id="OVR-SDK-LibOVR.task.NOTIFICATION_TRACE.message" value="Notification"></string>
+ <string id="OVR-SDK-LibOVR.task.LOG_TRACE.message" value="Log"></string>
+ <string id="OVR-SDK-LibOVR.task.HMD_TRACE.message" value="HmdInfo"></string>
+ <string id="OVR-SDK-LibOVR.task.FN_TRACE.message" value="Function"></string>
+ <string id="OVR-SDK-LibOVR.task.DIS_TRACE.message" value="Distort"></string>
+ <string id="OVR-SDK-LibOVR.task.Compositor_RunLoop.message" value="Compositor run loop (render thread) events."></string>
+ <string id="OVR-SDK-LibOVR.task.CAMERA_TRACE.message" value="Camera"></string>
+ <string id="OVR-SDK-LibOVR.opcode.HMD_DESC.message" value="Descriptor"></string>
+ <string id="OVR-SDK-LibOVR.opcode.FN_WAYPOINT.message" value="Waypoint"></string>
+ <string id="OVR-SDK-LibOVR.opcode.FN_RETURN.message" value="Return"></string>
+ <string id="OVR-SDK-LibOVR.opcode.FN_CALL.message" value="Call"></string>
+ <string id="OVR-SDK-LibOVR.opcode.DIS_WAITGPU.message" value="WaitGPU"></string>
+ <string id="OVR-SDK-LibOVR.opcode.DIS_PRESENT.message" value="Present"></string>
+ <string id="OVR-SDK-LibOVR.opcode.DIS_END.message" value="End"></string>
+ <string id="OVR-SDK-LibOVR.opcode.DIS_BEGIN.message" value="Begin"></string>
+ <string id="OVR-SDK-LibOVR.opcode.CAM_REQUEST.message" value="Request"></string>
+ <string id="OVR-SDK-LibOVR.opcode.CAM_RECEIVE.message" value="Receive"></string>
+ <string id="OVR-SDK-LibOVR.event.9.message" value="Received Frame %2"></string>
+ <string id="OVR-SDK-LibOVR.event.8.message" value="Hmd Descriptor for %4"></string>
+ <string id="OVR-SDK-LibOVR.event.7.message" value="End distortion rendering for %1 (frame %2)"></string>
+ <string id="OVR-SDK-LibOVR.event.66.message" value="CompleteFrame"></string>
+ <string id="OVR-SDK-LibOVR.event.65.message" value="EndFrame"></string>
+ <string id="OVR-SDK-LibOVR.event.64.message" value="BeginFrame"></string>
+ <string id="OVR-SDK-LibOVR.event.63.message" value="WaitToBeginFrame"></string>
+ <string id="OVR-SDK-LibOVR.event.62.message" value="BeginWait"></string>
+ <string id="OVR-SDK-LibOVR.event.61.message" value="Motion Estimation Cost Statistics"></string>
+ <string id="OVR-SDK-LibOVR.event.60.message" value="Submisison of notification to distortion"></string>
+ <string id="OVR-SDK-LibOVR.event.6.message" value="Present distortion for %1 (frame %2)"></string>
+ <string id="OVR-SDK-LibOVR.event.59.message" value="Notification end frame"></string>
+ <string id="OVR-SDK-LibOVR.event.58.message" value="Notification begin frame"></string>
+ <string id="OVR-SDK-LibOVR.event.57.message" value="Time GPU started work (after preemption)"></string>
+ <string id="OVR-SDK-LibOVR.event.56.message" value="Compositor missed frame (glitched)"></string>
+ <string id="OVR-SDK-LibOVR.event.55.message" value="App GPU work completed."></string>
+ <string id="OVR-SDK-LibOVR.event.54.message" value="Flushing ATW work to GPU"></string>
+ <string id="OVR-SDK-LibOVR.event.53.message" value="End of spinwait"></string>
+ <string id="OVR-SDK-LibOVR.event.52.message" value="Distortion end to end timing %1s"></string>
+ <string id="OVR-SDK-LibOVR.event.51.message" value="App EndFrame %1"></string>
+ <string id="OVR-SDK-LibOVR.event.50.message" value="RenderPacket stage %1 client pid %2"></string>
+ <string id="OVR-SDK-LibOVR.event.5.message" value="Wait for distortion renderer GPU for %1 (frame %2)"></string>
+ <string id="OVR-SDK-LibOVR.event.49.message" value="End ATW Composition"></string>
+ <string id="OVR-SDK-LibOVR.event.48.message" value="Begin ATW Composition"></string>
+ <string id="OVR-SDK-LibOVR.event.47.message" value="Client Missed Frame %1"></string>
+ <string id="OVR-SDK-LibOVR.event.46.message" value="Virtual Display Packet %1"></string>
+ <string id="OVR-SDK-LibOVR.event.45.message" value="Hardware info"></string>
+ <string id="OVR-SDK-LibOVR.event.44.message" value="End frame app timing"></string>
+ <string id="OVR-SDK-LibOVR.event.43.message" value="Latency Timing"></string>
+ <string id="OVR-SDK-LibOVR.event.42.message" value="PosePrediction"></string>
+ <string id="OVR-SDK-LibOVR.event.41.message" value="Testing only. Should not see in production."></string>
+ <string id="OVR-SDK-LibOVR.event.40.message" value="Application Disconnected"></string>
+ <string id="OVR-SDK-LibOVR.event.4.message" value="Begin distortion rendering for %1 (frame %2)"></string>
+ <string id="OVR-SDK-LibOVR.event.39.message" value="Application Connected"></string>
+ <string id="OVR-SDK-LibOVR.event.38.message" value="Application compositor focus"></string>
+ <string id="OVR-SDK-LibOVR.event.37.message" value="VSync Service QPC"></string>
+ <string id="OVR-SDK-LibOVR.event.36.message" value="PhaseSyncEnd"></string>
+ <string id="OVR-SDK-LibOVR.event.35.message" value="PhaseSyncBegin"></string>
+ <string id="OVR-SDK-LibOVR.event.34.message" value="Hmd Display %4 %5"></string>
+ <string id="OVR-SDK-LibOVR.event.33.message" value="End of Queue Ahead frame delay"></string>
+ <string id="OVR-SDK-LibOVR.event.32.message" value="Beginning timing delay for QueueAhead"></string>
+ <string id="OVR-SDK-LibOVR.event.31.message" value="Pose latch GPU readback"></string>
+ <string id="OVR-SDK-LibOVR.event.30.message" value="Pose latch CPU write"></string>
+ <string id="OVR-SDK-LibOVR.event.29.message" value="Camera %1 Segment Blobs for %2"></string>
+ <string id="OVR-SDK-LibOVR.event.28.message" value="Camera %1 Get Frame %2"></string>
+ <string id="OVR-SDK-LibOVR.event.27.message" value="Camera %1 Pose Sensor Fusion for %2"></string>
+ <string id="OVR-SDK-LibOVR.event.26.message" value="Camera %1 Pose Reconstruction for %2"></string>
+ <string id="OVR-SDK-LibOVR.event.25.message" value="Synced Camera %1 Clock"></string>
+ <string id="OVR-SDK-LibOVR.event.24.message" value="Camera Pose Change %1"></string>
+ <string id="OVR-SDK-LibOVR.event.23.message" value="End Camera LED Matching %1 %2 %3 %4"></string>
+ <string id="OVR-SDK-LibOVR.event.22.message" value="Begin Camera LED Matching %1 %2 %3 %4"></string>
+ <string id="OVR-SDK-LibOVR.event.21.message" value="End Global Image Aquisition %2 %3"></string>
+ <string id="OVR-SDK-LibOVR.event.20.message" value="Begin Global Image Aquisition %1"></string>
+ <string id="OVR-SDK-LibOVR.event.2.message" value="Waypoint %1:%2 (frame %3)"></string>
+ <string id="OVR-SDK-LibOVR.event.19.message" value="Blobs %1"></string>
+ <string id="OVR-SDK-LibOVR.event.18.message" value="Tracking State"></string>
+ <string id="OVR-SDK-LibOVR.event.17.message" value="Error: %1"></string>
+ <string id="OVR-SDK-LibOVR.event.16.message" value="Info: %1"></string>
+ <string id="OVR-SDK-LibOVR.event.15.message" value="Debug: %1"></string>
+ <string id="OVR-SDK-LibOVR.event.14.message" value="JSON chunk %1 (%3 of %2) size %5"></string>
+ <string id="OVR-SDK-LibOVR.event.13.message" value="Camera %1 Skipped Frames %2"></string>
+ <string id="OVR-SDK-LibOVR.event.12.message" value="Finished Processing Frame %2"></string>
+ <string id="OVR-SDK-LibOVR.event.11.message" value="Request Frame %2"></string>
+ <string id="OVR-SDK-LibOVR.event.10.message" value="Begin Processing Frame %2"></string>
+ <string id="OVR-SDK-LibOVR.event.1.message" value="Return %1:%2 (frame %3)"></string>
+ <string id="OVR-SDK-LibOVR.event.0.message" value="Call %1:%2 (frame %3)"></string>
+ <string id="OVR-SDK-LibOVR.channel.ERROR_CHANNEL.message" value="Error"></string>
+ </stringTable>
+ </resources>
+ </localization>
+</instrumentationManifest>
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 Binary files differnew file mode 100644 index 0000000..bbac1a8 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN 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 Binary files differnew file mode 100644 index 0000000..b7c8301 --- /dev/null +++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Tracing/LibOVREvents_MSG00001.bin 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<float> 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 <io.h> +#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<ID3D11Device>& 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<ID3D11PixelShader> 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<ID3DDeviceContextState> 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<ID3D11Resource> resource; + dest->GetResource(&resource.GetRawRef()); + Ptr<ID3D11Texture2D> 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<ID3DDeviceContextState> 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<ID3D11Resource> resource; + source->GetResource(&resource.GetRawRef()); + + Ptr<ID3D11Texture2D> 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<ID3D11DeviceContext> deviceContext; + device->GetImmediateContext(&deviceContext.GetRawRef()); // Always succeeds. + + Ptr<ID3D11Texture2D> + 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<uint8_t*>(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<uint8_t*>(mapped.pData); + auto end = src + mapped.RowPitch * textureDesc.Height; + for (; src < end; src += mapped.RowPitch) { + dst = ConvertRGBA2BGRA(reinterpret_cast<uint32_t*>(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<const uint64_t*>(src); + auto dst2 = reinterpret_cast<uint64_t*>(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<uint32_t*>(dst2); + } + // Convert remaining odd pixel + auto pixel = *reinterpret_cast<const uint32_t*>(src2); + dst = reinterpret_cast<uint32_t*>(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<const __m128i*>(src); + const auto* lineEnd = reinterpret_cast<const __m128i*>(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<uint32_t*>(byteDst); + auto quadEnd = reinterpret_cast<uint32_t*>(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<char*>(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 <d3d11_1.h> +#include <array> +#include <memory> // unique_ptr + +#include "OVR_CAPI.h" + +namespace OVR { +namespace D3DUtil { + +//------------------------------------------------------------------------------------- +// ***** CAPI::Blitter + +// D3D11 implementation of blitter + +class Blitter : public RefCountBase<Blitter> { + public: + Blitter(const Ptr<ID3D11Device>& 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<ID3D11Device1> Device; + Ptr<ID3D11DeviceContext1> Context1; + Ptr<ID3DDeviceContextState> BltState; + Ptr<ID3D11InputLayout> IL; + Ptr<ID3D11Buffer> VB; + Ptr<ID3D11VertexShader> VS; + + std::array<Ptr<ID3D11PixelShader>, PixelShaders::ShaderCount> PS; + Ptr<ID3D11SamplerState> Sampler; + Ptr<ID3D11DepthStencilState> 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<ID3D11Device> device; // D3D11Device we use. Must match the textures we work with. + Ptr<ID3D11Texture2D> 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<UINT, UINT> pixelsDimentions = {0, 0}; + std::unique_ptr<uint32_t[]> 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 <D3D11Shader.h> +#include <d3dcompiler.h> + +#if _MSC_VER >= 1800 +// Visual Studio 2013+ support newer D3D/DXGI headers. +#define OVR_D3D11_VER 2 +#include <d3d11_2.h> +#define OVR_DXGI_VER 3 +#include <dxgi1_3.h> // 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 <d3d11_1.h> +#else +// Visual Studio 2010+ only supports original D3D/DXGI headers. +#define OVR_D3D11_VER 1 +#include <d3d11.h> +#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 <gl/GL.h> +#elif defined(__APPLE__) +#include <OpenGL/gl.h> +#else +#include <GL/gl.h> +#endif + +namespace OVR { +namespace GLUtil { + +//------------------------------------------------------------------------------------- +// ***** CAPI::Blitter + +// D3D11 implementation of blitter + +class Blitter : public RefCountBase<Blitter> { + 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<IUnknown**>(&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<Frame> 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> 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<Frame> currentFrame = frames.PopFront(); + + Ptr<Frame> 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<CirclePlot>::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<TextPlot>::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<Frame> 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<Frame> 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> 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> 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> 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> 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 <d2d1.h> +#include <dwrite.h> +#include "Kernel/OVR_Win32_IncludeWindows.h" +#endif + +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_Deque.h" +#include "Kernel/OVR_Threads.h" + +#include <stdint.h> + +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<Frame> { + 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<CirclePlot> plots; + Array<TextPlot> 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<Mutex> frontBufferMutex; + + InPlaceMutableDeque<Ptr<Frame>> 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<Frame> 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<PollFunc>* func) { + PollSubject.AddListener(func); +} + +LongPollThread::LongPollThread() : Terminated(false) { + LongPollThreadHandle = std::make_unique<std::thread>([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 <thread> +#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<LongPollThread> { + OVR_DECLARE_SINGLETON(LongPollThread); + virtual void OnThreadDestroy() override; + + public: + typedef Delegate0<void> PollFunc; + static const int WakeupInterval = 1000; // milliseconds + + void AddPollFunc(CallbackListener<PollFunc>* func); + + void Wake(); + + // debug method for assertion to maintain initialization order for this singleton + static bool IsInitialized(); + + protected: + CallbackEmitter<PollFunc> PollSubject; + + std::atomic<bool> Terminated; + Event WakeEvent; + std::unique_ptr<std::thread> 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 <stdarg.h> +#include <stdio.h> +#include <memory> +#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<char[]> 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<char[]>(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 <stdarg.h> + +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 <codecvt> +#include <locale> +#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 <sys/utsname.h> +#endif + +// Includes used for GetBaseOVRPath() +#ifdef OVR_OS_WIN32 +#include <Psapi.h> +#include <Shlobj.h> +#include <Shlwapi.h> +#include <intrin.h> +#include <pdh.h> +#include <pdhMsg.h> +#include <perflib.h> +#include <wtsapi32.h> +#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 <dirent.h> +#include <sys/stat.h> + +#ifdef OVR_OS_LINUX +#include <pwd.h> +#include <unistd.h> +#elif defined(OVR_OS_MAC) +#include <libproc.h> +#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<BYTE[]>(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<decltype(&::VerQueryValueW)>( + 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<String>& 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<int*>(brand + i * 16) = cpui[0]; + *reinterpret_cast<int*>(brand + 4 + i * 16) = cpui[1]; + *reinterpret_cast<int*>(brand + 8 + i * 16) = cpui[2]; + *reinterpret_cast<int*>(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<OVR::String>& 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<int>(dwProcessId), + static_cast<int>(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<std::codecvt_utf8<wchar_t>> 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<uint32_t*>(data); + break; + + case REG_QWORD: + anyValue.type = dwType; + anyValue.qwordData = *reinterpret_cast<uint64_t*>(data); + break; + + case REG_SZ: { + case REG_EXPAND_SZ: + anyValue.type = dwType; + std::wstring stringW(reinterpret_cast<wchar_t*>(data), (dataSize / sizeof(wchar_t)) - 1); + anyValue.stringData = + std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(stringW); + break; + } + + case REG_MULTI_SZ: { + anyValue.type = dwType; + + for (wchar_t* p = reinterpret_cast<wchar_t*>(data); *p; p += (wcslen(p) + 1)) { + std::wstring stringW(p); + std::string string8 = + std::wstring_convert<std::codecvt_utf8<wchar_t>, 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<uint8_t>& 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<uint8_t*>(&anyValue.qwordData), + reinterpret_cast<uint8_t*>(&anyValue.qwordData) + sizeof(anyValue.qwordData)); + break; + + case REG_DWORD: + value.assign( + reinterpret_cast<uint8_t*>(&anyValue.dwordData), + reinterpret_cast<uint8_t*>(&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<uint8_t> 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<double*>(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 4) + value = *reinterpret_cast<float*>(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<uint64_t*>(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 4) + value = *reinterpret_cast<uint32_t*>(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 2) + value = *reinterpret_cast<uint16_t*>(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 1) + value = *reinterpret_cast<uint8_t*>(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<int64_t*>(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 4) + value = *reinterpret_cast<int32_t*>(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 2) + value = *reinterpret_cast<int16_t*>(anyValue.binaryData.data()); + else if (anyValue.binaryData.size() >= 1) + value = *reinterpret_cast<int8_t*>(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<double*>(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<std::codecvt_utf8<wchar_t>, 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<BYTE*>(const_cast<wchar_t*>(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<std::codecvt_utf8<wchar_t>, 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<BYTE*>(&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<BYTE*>(&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<const uint8_t*>(&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<const uint8_t*>(&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<uint8_t*>(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<std::string> 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<size_t>(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<size_t>(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<BYTE*>(&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<wchar_t, MAX_PATH> 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<PROCESS_MEMORY_COUNTERS*>(&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<PdhHelper> { + 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 <set> +#include <string> +#include <vector> +#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 <filesystem> +#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<OVR::String>& 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<uint8_t>& 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<std::string, InsensitiveCompare> 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<uint8_t> binaryData; // REG_BINARY + uint32_t dwordData; // REG_DWORD + uint64_t qwordData; // REG_QWORD + std::string stringData; // REG_SZ or REG_EXPAND_SZ + std::vector<std::string> 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<OVR::ModuleInfo> 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 <Logging/Logging_Library.h> + +#include "Kernel/OVR_DebugHelp.h" +#include "Kernel/OVR_Win32_IncludeWindows.h" + +#if defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) +#include <sys/ptrace.h> +#include <sys/types.h> +#include <unistd.h> + +#if defined(OVR_OS_LINUX) +#include <sys/wait.h> +#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<std::thread>([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<int>(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 <thread> +#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<uint32_t> WhenLastFedMilliseconds = {0}; + std::atomic<int> ThreshholdMilliseconds = {0}; + + String ThreadName; + bool Listed; +}; + +//----------------------------------------------------------------------------- +// WatchDogObserver + +class WatchDogObserver : public SystemSingletonBase<WatchDogObserver> { + OVR_DECLARE_SINGLETON(WatchDogObserver); + virtual void OnThreadDestroy() override; + + friend class WatchDog; + + std::unique_ptr<std::thread> 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<WatchDog*> 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 |