diff options
Diffstat (limited to 'LibOVR/Src')
79 files changed, 3209 insertions, 2051 deletions
diff --git a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp index 217310c..f335675 100644 --- a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp @@ -99,7 +99,6 @@ double DistortionRenderer::WaitTillTime(double absTime) return 0.0; double newTime = initialTime; - volatile int i; while (newTime < absTime) { @@ -124,7 +123,7 @@ double DistortionRenderer::WaitTillTime(double absTime) if (sleptTime > remainingWaitTime) { OVR_DEBUG_LOG_TEXT( - ("[DistortionRenderer::FlushGpuAndWaitTillTime] Sleep interval too long: %f\n", sleptTime)); + ("[DistortionRenderer::WaitTillTime] Sleep interval too long: %f\n", sleptTime)); } else { @@ -135,9 +134,9 @@ double DistortionRenderer::WaitTillTime(double absTime) else #endif { - for (int j = 0; j < 50; j++) - i = 0; - } + for (int j = 0; j < 5; j++) + OVR_PROCESSOR_PAUSE(); + } newTime = ovr_GetTimeInSeconds(); } diff --git a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h index 601cbc2..c9a86fa 100644 --- a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h @@ -50,14 +50,15 @@ public: DistortionRenderer(ovrRenderAPIType api, ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState) : + LastUsedOverdriveTextureIndex(-1), + LatencyTestActive(false), + LatencyTest2Active(false), RenderAPI(api), HMD(hmd), TimeManager(timeManager), RState(renderState), - RegisteredPostDistortionCallback(NULL), - LastUsedOverdriveTextureIndex(-1), - LatencyTestActive(false), - LatencyTest2Active(false) + GfxState(), + RegisteredPostDistortionCallback(NULL) { #ifdef OVR_OS_WIN32 timer = CreateWaitableTimer(NULL, TRUE, NULL); diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp index 2823658..9c192e3 100644 --- a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp +++ b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp @@ -219,20 +219,40 @@ void FrameLatencyTracker::GetLatencyTimings(float latencies[3]) latencies[2] = (float)FrameDeltas.GetMedianTimeDelta(); } } - - + + //------------------------------------------------------------------------------------- -FrameTimeManager::FrameTimeManager(bool vsyncEnabled) - : VsyncEnabled(vsyncEnabled), DynamicPrediction(true), SdkRender(false), - FrameTiming() +FrameTimeManager::FrameTimeManager(bool vsyncEnabled) : + VsyncEnabled(vsyncEnabled), + DynamicPrediction(true), + SdkRender(false), + DirectToRift(false), +#ifndef NO_SCREEN_TEAR_HEALING + ScreenTearing(false), + TearingFrameCount(0), +#endif // NO_SCREEN_TEAR_HEALING + FrameTiming() { RenderIMUTimeSeconds = 0.0; TimewarpIMUTimeSeconds = 0.0; - - // HACK: SyncToScanoutDelay observed close to 1 frame in video cards. - // Overwritten by dynamic latency measurement on DK2. - VSyncToScanoutDelay = 0.013f; + + // If driver is in use, + DirectToRift = !Display::InCompatibilityMode(false); + if (DirectToRift) + { + // The latest driver provides a post-present vsync-to-scan-out delay + // that is roughly zero. The latency tester will provide real numbers + // but when it is unavailable for some reason, we should default to + // an expected value. + VSyncToScanoutDelay = 0.0001f; + } + else + { + // HACK: SyncToScanoutDelay observed close to 1 frame in video cards. + // Overwritten by dynamic latency measurement on DK2. + VSyncToScanoutDelay = 0.013f; + } NoVSyncToScanoutDelay = 0.004f; } @@ -302,6 +322,10 @@ double FrameTimeManager::calcScreenDelay() const double screenDelay = ScreenSwitchingDelay; double measuredVSyncToScanout; +#ifndef NO_SCREEN_TEAR_HEALING + bool tearing = false; +#endif // NO_SCREEN_TEAR_HEALING + // Use real-time DK2 latency tester HW for prediction if its is working. // Do sanity check under 60 ms if (!VsyncEnabled) @@ -311,8 +335,14 @@ double FrameTimeManager::calcScreenDelay() const else if ( DynamicPrediction && (ScreenLatencyTracker.FrameDeltas.GetCount() > 3) && (measuredVSyncToScanout = ScreenLatencyTracker.FrameDeltas.GetMedianTimeDelta(), - (measuredVSyncToScanout > 0.0001) && (measuredVSyncToScanout < 0.06)) ) + (measuredVSyncToScanout > -0.0001) && (measuredVSyncToScanout < 0.06)) ) { +#ifndef NO_SCREEN_TEAR_HEALING + if (DirectToRift && measuredVSyncToScanout > 0.010 && measuredVSyncToScanout < 0.030) + { + tearing = true; + } +#endif // NO_SCREEN_TEAR_HEALING screenDelay += measuredVSyncToScanout; } else @@ -320,11 +350,51 @@ double FrameTimeManager::calcScreenDelay() const screenDelay += VSyncToScanoutDelay; } +#ifndef NO_SCREEN_TEAR_HEALING + if (tearing) + { + if (TearingFrameCount > 75) + { + if (!ScreenTearing) + { + ScreenTearing = true; + HealingFrameCount = 0; + } + } + else + { + TearingFrameCount++; + } + } + else + { + TearingFrameCount = 0; + ScreenTearing = false; + } +#endif // NO_SCREEN_TEAR_HEALING + return screenDelay; } +#ifndef NO_SCREEN_TEAR_HEALING + +bool FrameTimeManager::ScreenTearingReaction() +{ + if (ScreenTearing) + { + if (HealingFrameCount < 75) + { + ++HealingFrameCount; + return true; + } + } + + return false; +} + +#endif // NO_SCREEN_TEAR_HEALING -double FrameTimeManager::calcTimewarpWaitDelta() const +double FrameTimeManager::calcTimewarpWaitDelta() const { // If timewarp timing hasn't been calculated, we should wait. if (!VsyncEnabled) @@ -842,11 +912,11 @@ double TimeDeltaCollector::GetMedianTimeDelta() const SortedList[i] = smallestDelta; } + // FIRMWARE HACK: Don't take the actual median, but err on the low time side Median = SortedList[Count/4]; ReCalcMedian = false; } - // FIRMWARE HACK: Don't take the actual median, but err on the low time side return Median; } diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h index 5522668..2af5388 100644 --- a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h +++ b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h @@ -40,7 +40,7 @@ namespace OVR { namespace CAPI { // how long to wait. struct TimeDeltaCollector { - TimeDeltaCollector() : Count(0), ReCalcMedian(true), Median(-1.0) { } + TimeDeltaCollector() : Median(-1.0), Count(0), ReCalcMedian(true) { } void AddTimeDelta(double timeSeconds); void Clear() { Count = 0; } @@ -132,7 +132,7 @@ public: class FrameTimeManager { public: - FrameTimeManager(bool vsyncEnabled = true); + FrameTimeManager(bool vsyncEnabled); // Data that affects frame timing computation. struct TimingInputs @@ -222,11 +222,14 @@ public: void GetLatencyTimings(float latencies[3]) { return ScreenLatencyTracker.GetLatencyTimings(latencies); } - const Timing& GetFrameTiming() const { return FrameTiming; } -private: +#ifndef NO_SCREEN_TEAR_HEALING + bool IsScreenTearing() const { return ScreenTearing; }; + bool ScreenTearingReaction(); +#endif // NO_SCREEN_TEAR_HEALING +private: double calcFrameDelta() const; double calcScreenDelay() const; double calcTimewarpWaitDelta() const; @@ -292,8 +295,18 @@ private: bool VsyncEnabled; // Set if we are rendering via the SDK, so DistortionRenderTimes is valid. bool DynamicPrediction; - // Set if SDk is doing teh rendering. + // Set if SDk is doing the rendering. bool SdkRender; + // Direct to rift. + bool DirectToRift; +#ifndef NO_SCREEN_TEAR_HEALING + // Screen tearing detection + mutable bool ScreenTearing; + // Number of frames tearing has been observed + mutable int TearingFrameCount; + // Number of frames of reaction + mutable int HealingFrameCount; +#endif // NO_SCREEN_TEAR_HEALING // Total frame delay due to VsyncToFirstScanline, persistence and settle time. // Computed from RenderInfor.Shutter. diff --git a/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp b/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp index d77542b..fd3d667 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp +++ b/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp @@ -62,7 +62,8 @@ ovrHmdDesc HMDRenderState::GetDesc() const d.TrackingCaps = ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Orientation; d.DistortionCaps = ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp | ovrDistortionCap_Vignette | ovrDistortionCap_SRGB | - ovrDistortionCap_FlipInput | ovrDistortionCap_ProfileNoTimewarpSpinWaits; + ovrDistortionCap_FlipInput | ovrDistortionCap_ProfileNoTimewarpSpinWaits | + ovrDistortionCap_HqDistortion; if( OurHMDInfo.InCompatibilityMode ) d.HmdCaps |= ovrHmdCap_ExtendDesktop; diff --git a/LibOVR/Src/CAPI/CAPI_HMDState.cpp b/LibOVR/Src/CAPI/CAPI_HMDState.cpp index 6d6162d..720857d 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDState.cpp +++ b/LibOVR/Src/CAPI/CAPI_HMDState.cpp @@ -42,31 +42,70 @@ HMDState::HMDState(const OVR::Service::HMDNetworkInfo& netInfo, const OVR::HMDInfo& hmdInfo, Profile* profile, Service::NetClient* client) : - pClient(client), pProfile(profile), pHmdDesc(0), pWindow(0), - NetInfo(netInfo), + pClient(client), NetId(netInfo.NetId), + NetInfo(netInfo), OurHMDInfo(hmdInfo), + pLastError(NULL), EnabledHmdCaps(0), - LastFrameTimeSeconds(0.f), - LastGetFrameTimeSeconds(0.), + EnabledServiceHmdCaps(0), + SharedStateReader(), + TheSensorStateReader(), + TheLatencyTestStateReader(), LatencyTestActive(false), - LatencyTest2Active(false) + //LatencyTestDrawColor(), + LatencyTest2Active(false), + //LatencyTest2DrawColor(), + TimeManager(true), + RenderState(), + pRenderer(), + pHSWDisplay(), + LastFrameTimeSeconds(0.), + LastGetFrameTimeSeconds(0.), + //LastGetStringValue(), + RenderingConfigured(false), + BeginFrameCalled(false), + BeginFrameThreadId(), + RenderAPIThreadChecker(), + BeginFrameTimingCalled(false) { sharedInit(profile); } + HMDState::HMDState(const OVR::HMDInfo& hmdInfo, Profile* profile) : - pClient(0), + pProfile(profile), pHmdDesc(0), + pWindow(0), + pClient(0), NetId(InvalidVirtualHmdId), - pProfile(profile), + NetInfo(), OurHMDInfo(hmdInfo), + pLastError(NULL), EnabledHmdCaps(0), + EnabledServiceHmdCaps(0), + SharedStateReader(), + TheSensorStateReader(), + TheLatencyTestStateReader(), + LatencyTestActive(false), + //LatencyTestDrawColor(), + LatencyTest2Active(false), + //LatencyTest2DrawColor(), + TimeManager(true), + RenderState(), + pRenderer(), + pHSWDisplay(), LastFrameTimeSeconds(0.), - LastGetFrameTimeSeconds(0.) + LastGetFrameTimeSeconds(0.), + //LastGetStringValue(), + RenderingConfigured(false), + BeginFrameCalled(false), + BeginFrameThreadId(), + RenderAPIThreadChecker(), + BeginFrameTimingCalled(false) { sharedInit(profile); } @@ -82,7 +121,10 @@ HMDState::~HMDState() ConfigureRendering(0,0,0,0); if (pHmdDesc) - delete pHmdDesc; + { + OVR_FREE(pHmdDesc); + pHmdDesc = NULL; + } } void HMDState::sharedInit(Profile* profile) @@ -96,7 +138,7 @@ void HMDState::sharedInit(Profile* profile) UpdateRenderProfile(profile); OVR_ASSERT(!pHmdDesc); - pHmdDesc = new ovrHmdDesc; + pHmdDesc = (ovrHmdDesc*)OVR_ALLOC(sizeof(ovrHmdDesc)); *pHmdDesc = RenderState.GetDesc(); pHmdDesc->Handle = this; @@ -120,6 +162,8 @@ void HMDState::sharedInit(Profile* profile) BeginFrameThreadId = 0; BeginFrameTimingCalled = false; + TheSensorStateReader.LoadProfileCenteredFromWorld(profile); + // Construct the HSWDisplay. We will later reconstruct it with a specific ovrRenderAPI type if the application starts using SDK-based rendering. if(!pHSWDisplay) pHSWDisplay = *OVR::CAPI::HSWDisplay::Factory(ovrRenderAPI_None, pHmdDesc, RenderState); @@ -264,7 +308,7 @@ ovrTrackingState HMDState::PredictedTrackingState(double absTime) TheSensorStateReader.GetSensorStateAtTime(absTime, ss); // Zero out the status flags - if (!pClient || !pClient->IsConnected()) + if (!pClient || !pClient->IsConnected(false, false)) { ss.StatusFlags = 0; } @@ -360,8 +404,7 @@ bool HMDState::getBoolValue(const char* propertyName, bool defaultVal) bool HMDState::setBoolValue(const char* propertyName, bool value) { - NetClient::GetInstance()->SetBoolValue(GetNetId(), propertyName, value); - return true; + return NetClient::GetInstance()->SetBoolValue(GetNetId(), propertyName, value); } int HMDState::getIntValue(const char* propertyName, int defaultVal) @@ -379,8 +422,7 @@ int HMDState::getIntValue(const char* propertyName, int defaultVal) bool HMDState::setIntValue(const char* propertyName, int value) { - NetClient::GetInstance()->SetIntValue(GetNetId(), propertyName, value); - return true; + return NetClient::GetInstance()->SetIntValue(GetNetId(), propertyName, value); } float HMDState::getFloatValue(const char* propertyName, float defaultVal) @@ -411,8 +453,7 @@ float HMDState::getFloatValue(const char* propertyName, float defaultVal) bool HMDState::setFloatValue(const char* propertyName, float value) { - NetClient::GetInstance()->SetNumberValue(GetNetId(), propertyName, value); - return true; + return NetClient::GetInstance()->SetNumberValue(GetNetId(), propertyName, value); } static unsigned CopyFloatArrayWithLimit(float dest[], unsigned destSize, @@ -501,11 +542,11 @@ bool HMDState::setFloatArray(const char* propertyName, float values[], unsigned da[i] = values[i]; } - NetClient::GetInstance()->SetNumberValues(GetNetId(), propertyName, da, arraySize); + bool result = NetClient::GetInstance()->SetNumberValues(GetNetId(), propertyName, da, arraySize); delete[] da; - return true; + return result; } const char* HMDState::getString(const char* propertyName, const char* defaultVal) @@ -529,8 +570,7 @@ const char* HMDState::getString(const char* propertyName, const char* defaultVal bool HMDState::setString(const char* propertyName, const char* value) { - NetClient::GetInstance()->SetStringValue(GetNetId(), propertyName, value); - return true; + return NetClient::GetInstance()->SetStringValue(GetNetId(), propertyName, value); } @@ -539,93 +579,7 @@ bool HMDState::setString(const char* propertyName, const char* value) bool HMDState::ProcessLatencyTest(unsigned char rgbColorOut[3]) { - bool result = false; - - result = NetClient::GetInstance()->LatencyUtil_ProcessInputs(Timer::GetSeconds(), rgbColorOut); - -#if 0 //def ENABLE_LATENCY_TESTER - // Check create. - if (pLatencyTester) - { - if (pLatencyTester->IsConnected()) - { - Color colorToDisplay; - - LatencyUtil.ProcessInputs(); - result = LatencyUtil.DisplayScreenColor(colorToDisplay); - rgbColorOut[0] = colorToDisplay.R; - rgbColorOut[1] = colorToDisplay.G; - rgbColorOut[2] = colorToDisplay.B; - } - else - { - // Disconnect. - LatencyUtil.SetDevice(NULL); - pLatencyTester = 0; - LogText("LATENCY SENSOR disconnected.\n"); - } - } - else if (AddLatencyTestCount > 0) - { - // This might have some unlikely race condition issue which could cause us to miss a device... - AddLatencyTestCount = 0; - - pLatencyTester = *GlobalState::pInstance->GetManager()->EnumerateDevices<LatencyTestDevice>().CreateDevice(); - if (pLatencyTester) - { - LatencyUtil.SetDevice(pLatencyTester); - LogText("LATENCY TESTER connected\n"); - } - } -#endif - - return result; -} - -void HMDState::ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTime) -{ - OVR_UNUSED2(rgbColorOut, startTime); - /* - // Check create. - if (!(EnabledHmdCaps & ovrHmdCap_LatencyTest)) - return; - - if (pLatencyTesterDisplay && !LatencyUtil2.HasDisplayDevice()) - { - if (!pLatencyTesterDisplay->IsConnected()) - { - LatencyUtil2.SetDisplayDevice(NULL); - } - } - else if (AddLatencyTestDisplayCount > 0) - { - // This might have some unlikely race condition issue - // which could cause us to miss a device... - AddLatencyTestDisplayCount = 0; - - pLatencyTesterDisplay = *GlobalState::pInstance->GetManager()-> - EnumerateDevices<LatencyTestDevice>().CreateDevice(); - if (pLatencyTesterDisplay) - { - LatencyUtil2.SetDisplayDevice(pLatencyTesterDisplay); - } - } - - if (LatencyUtil2.HasDevice() && pSensor && pSensor->IsConnected()) - { - LatencyUtil2.BeginTest(startTime); - - Color colorToDisplay; - LatencyTest2Active = LatencyUtil2.DisplayScreenColor(colorToDisplay); - rgbColorOut[0] = colorToDisplay.R; - rgbColorOut[1] = colorToDisplay.G; - rgbColorOut[2] = colorToDisplay.B; - } - else - { - LatencyTest2Active = false; - } - */ + return NetClient::GetInstance()->LatencyUtil_ProcessInputs(Timer::GetSeconds(), rgbColorOut); } //------------------------------------------------------------------------------------- diff --git a/LibOVR/Src/CAPI/CAPI_HMDState.h b/LibOVR/Src/CAPI/CAPI_HMDState.h index 863c5c5..40f4738 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDState.h +++ b/LibOVR/Src/CAPI/CAPI_HMDState.h @@ -156,8 +156,7 @@ public: unsigned SetEnabledHmdCaps(); bool ProcessLatencyTest(unsigned char rgbColorOut[3]); - void ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTime); - + // *** Rendering Setup bool ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], const ovrFovPort eyeFovIn[2], diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp index 18ad298..b2f8547 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp @@ -340,6 +340,12 @@ void DistortionRenderer::EndFrame(bool swapBuffers) if (RParams.pSwapChain) { UINT swapInterval = (RState.EnabledHmdCaps & ovrHmdCap_NoVSync) ? 0 : 1; +#ifndef NO_SCREEN_TEAR_HEALING + if (TimeManager.ScreenTearingReaction()) + { + swapInterval = 0; + } +#endif // NO_SCREEN_TEAR_HEALING RParams.pSwapChain->Present(swapInterval, 0); // Force GPU to flush the scene, resulting in the lowest possible latency. @@ -491,26 +497,33 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ for(int eyeNum = 0; eyeNum < 2; eyeNum++) - { + { ShaderFill distortionShaderFill(DistortionShader); distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture); + if(RState.DistortionCaps & ovrDistortionCap_HqDistortion) + { + static float aaDerivMult = 0.5f; + DistortionShader->SetUniform1f("AaDerivativeMult", aaDerivMult); + } + else + { + // 0.0 disables high quality anti-aliasing + DistortionShader->SetUniform1f("AaDerivativeMultOffset", -1.0f); + } + if(overdriveActive) { distortionShaderFill.SetTexture(1, pOverdriveTextures[LastUsedOverdriveTextureIndex]); - - float invRtWidth = 1.0f / (float)RParams.RTSize.w; - float invRtHeight = 1.0f / (float)RParams.RTSize.h; - DistortionShader->SetUniform2f("OverdriveInvRTSize", invRtWidth, invRtHeight); - + static float overdriveScaleRegularRise = 0.1f; - static float overdriveScaleRegularFall = 0.05f; // falling issues are hardly visible + static float overdriveScaleRegularFall = 0.05f; // falling issues are hardly visible DistortionShader->SetUniform2f("OverdriveScales", overdriveScaleRegularRise, overdriveScaleRegularFall); } else { // -1.0f disables PLO - DistortionShader->SetUniform2f("OverdriveInvRTSize", -1.0f, -1.0f); + DistortionShader->SetUniform2f("OverdriveScales", -1.0f, -1.0f); } distortionShaderFill.SetInputLayout(DistortionVertexIL); @@ -524,7 +537,7 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, RState.EyeRenderPoses[eyeNum], timeWarpMatrices); - // Feed identity like matrices in until we get proper timewarp calculation going on + // Can feed identity like matrices incase of concern over timewarp calculations DistortionShader->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0])); DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1])); diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp index a685191..5ede0b8 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp @@ -156,9 +156,6 @@ void DistortionRenderer::EndFrame(bool swapBuffers) renderEndFrame(); } - if(RegisteredPostDistortionCallback) - RegisteredPostDistortionCallback(device); - if(LatencyTestDrawColor) { // TODO: Support latency tester quad diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h index be5aa5f..c35bf43 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h @@ -26,8 +26,6 @@ limitations under the License. #include "../../Kernel/OVR_Types.h" -#undef new - #if defined (OVR_OS_WIN32) #define WIN32_LEAN_AND_MEAN #if _MSC_VER < 1700 diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp index bb52d98..2c903b6 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp @@ -98,6 +98,9 @@ DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager { DistortionMeshVAOs[0] = 0; DistortionMeshVAOs[1] = 0; + + // Initialize render params. + memset(&RParams, 0, sizeof(RParams)); } DistortionRenderer::~DistortionRenderer() @@ -155,7 +158,6 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, RParams.Win = config->OGL.Win; if (!RParams.Win) { - int unused; RParams.Win = glXGetCurrentDrawable(); } if (!RParams.Win) @@ -270,9 +272,16 @@ void DistortionRenderer::EndFrame(bool swapBuffers) if (swapBuffers) { bool useVsync = ((RState.EnabledHmdCaps & ovrHmdCap_NoVSync) == 0); - int swapInterval = (useVsync) ? 1 : 0; + int swapInterval = (useVsync) ? 1 : 0; #if defined(OVR_OS_WIN32) - if (wglGetSwapIntervalEXT() != swapInterval) +#ifndef NO_SCREEN_TEAR_HEALING + if (TimeManager.ScreenTearingReaction()) + { + swapInterval = 0; + useVsync = false; + } +#endif // NO_SCREEN_TEAR_HEALING + if (wglGetSwapIntervalEXT() != swapInterval) wglSwapIntervalEXT(swapInterval); HDC dc = (RParams.DC != NULL) ? RParams.DC : GetDC(RParams.Window); @@ -297,7 +306,7 @@ void DistortionRenderer::EndFrame(bool swapBuffers) { GLuint currentSwapInterval = 0; glXQueryDrawable(RParams.Disp, RParams.Win, GLX_SWAP_INTERVAL_EXT, ¤tSwapInterval); - if (currentSwapInterval != swapInterval) + if (currentSwapInterval != (GLuint)swapInterval) glXSwapIntervalEXT(RParams.Disp, RParams.Win, swapInterval); } @@ -332,58 +341,17 @@ double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) return WaitTillTime(absTime); } - - + + DistortionRenderer::GraphicsState::GraphicsState() { - bool foundVersion = false; - const char* glVersionString = (const char*)glGetString(GL_VERSION); - if (glVersionString) - { - OVR_DEBUG_LOG(("GL_VERSION STRING: %s", (const char*)glVersionString)); - char prefix[64]; + GetGLVersionAndExtensions(GLVersionInfo); +} - for (int i = 10; i < 30; ++i) - { - int major = i / 10; - int minor = i % 10; - OVR_sprintf(prefix, 64, "%d.%d", major, minor); - if (strstr(glVersionString, prefix) == glVersionString) - { - GlMajorVersion = major; - GlMinorVersion = minor; - foundVersion = true; - break; - } - } - } - - if (!foundVersion) - { - glGetIntegerv(GL_MAJOR_VERSION, &GlMajorVersion); - glGetIntegerv(GL_MAJOR_VERSION, &GlMinorVersion); - } - OVR_ASSERT(GlMajorVersion >= 2); - - if (GlMajorVersion >= 3) - { - SupportsVao = true; - SupportsDrawBuffers = true; - } - else - { - const char* extensions = (const char*)glGetString(GL_EXTENSIONS); - SupportsVao = (strstr(extensions, "GL_ARB_vertex_array_object") != NULL - || strstr(extensions, "GL_APPLE_vertex_array_object") != NULL); - SupportsDrawBuffers = (strstr(extensions, "GL_EXT_draw_buffers2") != NULL); - } -} - - void DistortionRenderer::GraphicsState::ApplyBool(GLenum Name, GLint Value, GLint index) { - if (SupportsDrawBuffers && index != -1) + if (GLVersionInfo.SupportsDrawBuffers && index != -1) { if (Value != 0) glEnablei(Name, index); @@ -410,7 +378,7 @@ void DistortionRenderer::GraphicsState::Save() glGetIntegerv(GL_CURRENT_PROGRAM, &Program); glGetIntegerv(GL_ACTIVE_TEXTURE, &ActiveTexture); glGetIntegerv(GL_TEXTURE_BINDING_2D, &TextureBinding); - if (SupportsVao) + if (GLVersionInfo.SupportsVAO) { glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArrayBinding); } @@ -420,7 +388,7 @@ void DistortionRenderer::GraphicsState::Save() glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &ArrayBufferBinding); } glGetIntegerv(GL_FRAMEBUFFER_BINDING, &FrameBufferBinding); - if (SupportsDrawBuffers) + if (GLVersionInfo.SupportsDrawBuffers) { glGetIntegeri_v(GL_BLEND, 0, &Blend); glGetIntegeri_v(GL_COLOR_WRITEMASK, 0, ColorWritemask); @@ -432,8 +400,10 @@ void DistortionRenderer::GraphicsState::Save() } glGetIntegerv(GL_DITHER, &Dither); glGetIntegerv(GL_RASTERIZER_DISCARD, &RasterizerDiscard); - if ((GlMajorVersion == 3 && GlMinorVersion >= 2) || GlMajorVersion >= 4) + if ((GLVersionInfo.MajorVersion == 3 && GLVersionInfo.MinorVersion >= 2) || GLVersionInfo.MajorVersion >= 4) + { glGetIntegerv(GL_SAMPLE_MASK, &SampleMask); + } IsValid = true; } @@ -441,7 +411,7 @@ void DistortionRenderer::GraphicsState::Save() #ifdef OVR_OS_MAC bool DistortionRenderer::GraphicsState::isAtLeastOpenGL3() { - return !(GlMajorVersion < 3|| (GlMajorVersion == 3 && GlMinorVersion < 2)); + return (((GLVersionInfo.MajorVersion * 100) + GLVersionInfo.MinorVersion) >= 302); // OpenGL 3.2 or later } #endif @@ -461,7 +431,7 @@ void DistortionRenderer::GraphicsState::Restore() glUseProgram(Program); glActiveTexture(ActiveTexture); glBindTexture(GL_TEXTURE_2D, TextureBinding); - if (SupportsVao) + if (GLVersionInfo.SupportsVAO) { #ifdef OVR_OS_MAC if (isAtLeastOpenGL3()) @@ -485,15 +455,22 @@ void DistortionRenderer::GraphicsState::Restore() ApplyBool(GL_BLEND, Blend, 0); - if (SupportsDrawBuffers) + if (GLVersionInfo.SupportsDrawBuffers) + { glColorMaski(0, (GLboolean)ColorWritemask[0], (GLboolean)ColorWritemask[1], (GLboolean)ColorWritemask[2], (GLboolean)ColorWritemask[3]); + } else + { glColorMask((GLboolean)ColorWritemask[0], (GLboolean)ColorWritemask[1], (GLboolean)ColorWritemask[2], (GLboolean)ColorWritemask[3]); + } ApplyBool(GL_DITHER, Dither); ApplyBool(GL_RASTERIZER_DISCARD, RasterizerDiscard); - if ((GlMajorVersion == 3 && GlMinorVersion >= 2) || GlMajorVersion >= 4) + if ((GLVersionInfo.MajorVersion == 3 && GLVersionInfo.MinorVersion >= 2) || + GLVersionInfo.MajorVersion >= 4) + { ApplyBool(GL_SAMPLE_MASK, SampleMask); + } } @@ -525,9 +502,13 @@ void DistortionRenderer::initBuffersAndShaders() { pCurVBVert->ScreenPosNDC.x = pCurOvrVert->ScreenPosNDC.x; pCurVBVert->ScreenPosNDC.y = pCurOvrVert->ScreenPosNDC.y; - pCurVBVert->TanEyeAnglesR = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesR); - pCurVBVert->TanEyeAnglesG = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesG); - pCurVBVert->TanEyeAnglesB = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesB); + + // Previous code here did this: pCurVBVert->TanEyeAnglesR = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesR); However that's an usafe + // cast of unrelated types which can result in undefined behavior by a conforming compiler. A safe equivalent is simply memcpy. + static_assert(sizeof(OVR::Vector2f) == sizeof(ovrVector2f), "Mismatch of structs that are presumed binary equivalents."); + memcpy(&pCurVBVert->TanEyeAnglesR, &pCurOvrVert->TanEyeAnglesR, sizeof(pCurVBVert->TanEyeAnglesR)); + memcpy(&pCurVBVert->TanEyeAnglesG, &pCurOvrVert->TanEyeAnglesG, sizeof(pCurVBVert->TanEyeAnglesG)); + memcpy(&pCurVBVert->TanEyeAnglesB, &pCurOvrVert->TanEyeAnglesB, sizeof(pCurVBVert->TanEyeAnglesB)); // Convert [0.0f,1.0f] to [0,255] if (DistortionCaps & ovrDistortionCap_Vignette) @@ -569,7 +550,7 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); - if (glState->SupportsDrawBuffers) + if (glState->GLVersionInfo.SupportsDrawBuffers) { glDisablei(GL_BLEND, 0); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); @@ -582,8 +563,10 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ glDisable(GL_DITHER); glDisable(GL_RASTERIZER_DISCARD); - if ((glState->GlMajorVersion >= 3 && glState->GlMinorVersion >= 2) || glState->GlMajorVersion >= 4) + if ((glState->GLVersionInfo.MajorVersion >= 3 && glState->GLVersionInfo.MinorVersion >= 2) || glState->GLVersionInfo.MajorVersion >= 4) + { glDisable(GL_SAMPLE_MASK); + } glClearColor( RState.ClearColor[0], @@ -780,7 +763,7 @@ void DistortionRenderer::renderPrimitives( } else { - if (glState->SupportsVao) + if (glState->GLVersionInfo.SupportsVAO) { #ifdef OVR_OS_MAC if (glState->isAtLeastOpenGL3()) @@ -836,7 +819,7 @@ void DistortionRenderer::renderPrimitives( glDrawArrays(prim, 0, count); - if (!glState->SupportsVao) + if (!glState->GLVersionInfo.SupportsVAO) { for (int i = 0; i < attributeCount; ++i) glDisableVertexAttribArray(locs[i]); @@ -844,7 +827,7 @@ void DistortionRenderer::renderPrimitives( delete[] locs; - if (glState->SupportsVao) + if (glState->GLVersionInfo.SupportsVAO) { #ifdef OVR_OS_MAC if (glState->isAtLeastOpenGL3()) @@ -874,7 +857,8 @@ void DistortionRenderer::initShaders() GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); const char* shaderPrefix = - (glState->GlMajorVersion < 3 || (glState->GlMajorVersion == 3 && glState->GlMinorVersion < 2)) ? + (glState->GLVersionInfo.MajorVersion < 3 || + (glState->GLVersionInfo.MajorVersion == 3 && glState->GLVersionInfo.MinorVersion < 2)) ? glsl2Prefix : glsl3Prefix; { @@ -979,11 +963,13 @@ void DistortionRenderer::destroy() SaveGraphicsState(); GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); - + for(int eyeNum = 0; eyeNum < 2; eyeNum++) { - if (glState->SupportsVao) + if (glState->GLVersionInfo.SupportsVAO) + { glDeleteVertexArrays(1, &DistortionMeshVAOs[eyeNum]); + } DistortionMeshVAOs[eyeNum] = 0; diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h index 9189ae6..1017c6e 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h @@ -77,10 +77,7 @@ protected: void ApplyBool(GLenum Name, GLint Value, GLint index = -1); public: - GLint GlMajorVersion; - GLint GlMinorVersion; - bool SupportsVao; - bool SupportsDrawBuffers; + GLVersionAndExtensions GLVersionInfo; GLint Viewport[4]; GLfloat ClearColor[4]; diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h index 5c68c50..76e8c81 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h @@ -30,6 +30,7 @@ namespace OVR { namespace CAPI { namespace GL { "#define _VS_OUT varying\n" "#define _FS_IN varying\n" "#define _TEXTURELOD texture2DLod\n" + "#define _TEXTURE texture2D\n" "#define _FRAGCOLOR gl_FragColor\n"; static const char glsl3Prefix[] = @@ -39,6 +40,7 @@ namespace OVR { namespace CAPI { namespace GL { "#define _VS_OUT out\n" "#define _FS_IN in\n" "#define _TEXTURELOD textureLod\n" + "#define _TEXTURE texture\n" "#define _FRAGCOLOR FragColor\n"; static const char SimpleQuad_vs[] = @@ -127,7 +129,7 @@ namespace OVR { namespace CAPI { namespace GL { "void main()\n" "{\n" - " _FRAGCOLOR = oColor * texture2D(Texture0, oTexCoord);\n" + " _FRAGCOLOR = oColor * _TEXTURE(Texture0, oTexCoord);\n" "}\n"; // The following is copied from the generated D3D SimpleTexturedQuad_ps_refl.h file, with D3D_NS renamed to GL. diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp index 6c0106d..f024ac5 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp @@ -232,9 +232,6 @@ Texture* LoadTextureTga(RenderParams& rParams, int samplerMode, const uint8_t* p HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState) : OVR::CAPI::HSWDisplay(api, hmd, renderState) , RenderParams() - , GLMajorVersion(0) - , GLMinorVersion(0) - , SupportsVao(false) , FrameBuffer(0) , pTexture() , pShaderSet() @@ -276,10 +273,8 @@ bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig) if (config->OGL.Win) RenderParams.Win= config->OGL.Win; if (!RenderParams.Win) - { - int unused; RenderParams.Win = glXGetCurrentDrawable(); - } + if (!RenderParams.Win) { OVR_DEBUG_LOG(("XGetInputFocus failed.")); @@ -332,17 +327,14 @@ void HSWDisplay::UnloadGraphics() if(VAO) { #ifdef OVR_OS_MAC - if(GLMajorVersion >= 3) - { - glDeleteVertexArrays(1, &VAO); - } - else - { - glDeleteVertexArraysAPPLE(1, &VAO); - } - #else + if(GLVersionInfo.WholeVersion >= 302) + glDeleteVertexArrays(1, &VAO); + else + glDeleteVertexArraysAPPLE(1, &VAO); + #else glDeleteVertexArrays(1, &VAO); #endif + VAO = 0; VAOInitialized = false; } @@ -352,31 +344,10 @@ void HSWDisplay::UnloadGraphics() void HSWDisplay::LoadGraphics() { - const char* glVersionString = (const char*)glGetString(GL_VERSION); - - OVR_ASSERT(glVersionString); - if (glVersionString) - { - int fieldCount = sscanf(glVersionString, isdigit(*glVersionString) ? "%d.%d" : "%*[^0-9]%d.%d", &GLMajorVersion, &GLMinorVersion); // Skip all leading non-digits before reading %d. Example glVersionStrings: "1.5 ATI-1.4.18", "OpenGL ES-CM 3.2" - - if(fieldCount != 2) - { - static_assert(sizeof(GLMajorVersion) == sizeof(GLint), "type mis-match"); - glGetIntegerv(GL_MAJOR_VERSION, &GLMajorVersion); - } - } - - // SupportsVao - if(GLMajorVersion >= 3) - SupportsVao = true; - else - { - const char* extensions = (const char*)glGetString(GL_EXTENSIONS); - SupportsVao = (strstr(extensions, "GL_ARB_vertex_array_object") || strstr(extensions, "GL_APPLE_vertex_array_object")); - } - if (FrameBuffer == 0) + { glGenFramebuffers(1, &FrameBuffer); + } if (!pTexture) // To do: Add support for .dds files, which would be significantly smaller than the size of the tga. { @@ -385,12 +356,14 @@ void HSWDisplay::LoadGraphics() pTexture = *LoadTextureTga(RenderParams, Sample_Linear | Sample_Clamp, TextureData, (int)textureSize, 255); } - if(!pShaderSet) + if (!pShaderSet) + { pShaderSet = *new ShaderSet(); + } if(!pVertexShader) { - OVR::String strShader((GLMajorVersion >= 3) ? glsl3Prefix : glsl2Prefix); + OVR::String strShader((GLVersionInfo.MajorVersion >= 3) ? glsl3Prefix : glsl2Prefix); strShader += SimpleTexturedQuad_vs; pVertexShader = *new VertexShader(&RenderParams, const_cast<char*>(strShader.ToCStr()), strShader.GetLength(), SimpleTexturedQuad_vs_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_vs_refl)); @@ -399,7 +372,7 @@ void HSWDisplay::LoadGraphics() if(!pFragmentShader) { - OVR::String strShader((GLMajorVersion >= 3) ? glsl3Prefix : glsl2Prefix); + OVR::String strShader((GLVersionInfo.MajorVersion >= 3) ? glsl3Prefix : glsl2Prefix); strShader += SimpleTexturedQuad_ps; pFragmentShader = *new FragmentShader(&RenderParams, const_cast<char*>(strShader.ToCStr()), strShader.GetLength(), SimpleTexturedQuad_ps_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_ps_refl)); @@ -432,18 +405,15 @@ void HSWDisplay::LoadGraphics() } // We don't generate the vertex arrays here - if(!VAO && SupportsVao) + if (!VAO && GLVersionInfo.SupportsVAO) { OVR_ASSERT(!VAOInitialized); + #ifdef OVR_OS_MAC - if(GLMajorVersion >= 3) - { - glGenVertexArrays(1, &VAO); - } - else - { - glGenVertexArraysAPPLE(1, &VAO); - } + if(GLVersionInfo.WholeVersion >= 302) + glGenVertexArrays(1, &VAO); + else + glGenVertexArraysAPPLE(1, &VAO); #else glGenVertexArrays(1, &VAO); #endif @@ -455,9 +425,13 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) { if(RenderEnabled && eyeTexture) { - // Hack - Clear previous errors. + // glGetError clears any previous error state. We call it here in order to start with + // a clean slate, as we are asserting below that our calls do not generate errors. glGetError(); + if(GLVersionInfo.MajorVersion == 0) // If not yet initialized... + GetGLVersionAndExtensions(GLVersionInfo); + // We need to render to the eyeTexture with the texture viewport. // Setup rendering to the texture. ovrGLTexture* eyeTextureGL = const_cast<ovrGLTexture*>(reinterpret_cast<const ovrGLTexture*>(eyeTexture)); @@ -468,15 +442,19 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) // Save state // To do: Converge this with the state setting/restoring functionality present in the distortion renderer. + // Consider usage of the EXT_direct_state_access (http://www.opengl.org/registry/specs/EXT/direct_state_access.txt) extension. // Note that the glGet functions below will block until command buffer has completed. // glPushAttrib is deprecated, so we use glGet* to save/restore fixed-function settings. // https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glGet.xml // - GLint RenderModeSaved; - glGetIntegerv(GL_RENDER_MODE, &RenderModeSaved); - OVR_ASSERT(glGetError() == 0); - OVR_ASSERT(RenderModeSaved == GL_RENDER); // Make sure it's not GL_SELECT or GL_FEEDBACK. - + GLint RenderModeSaved = 0; + if(!GLVersionInfo.IsCoreProfile) // glGetIntegerv can fail if an OpenGL 3.x+ core profile is enabled due to GL_RENDER_MODE being no longer supported. + { + glGetIntegerv(GL_RENDER_MODE, &RenderModeSaved); + OVR_ASSERT(glGetError() == 0); + OVR_ASSERT(RenderModeSaved == GL_RENDER); // Make sure it's not GL_SELECT or GL_FEEDBACK. + } + GLint FrameBufferBindingSaved; // OpenGL renamed GL_FRAMEBUFFER_BINDING to GL_DRAW_FRAMEBUFFER_BINDING and adds GL_READ_FRAMEBUFFER_BINDING. glGetIntegerv(GL_FRAMEBUFFER_BINDING, &FrameBufferBindingSaved); OVR_ASSERT(glGetError() == 0); @@ -494,8 +472,8 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) OVR_ASSERT(glGetError() == 0); GLdouble DepthRangeSaved[2]; - #if defined(OVR_OS_MAC) - // Using glDepthRange as a conditional will always evaluate to true on Mac. + #if defined(OVR_OS_MAC) || defined(OVR_OS_LINUX) + // Using glDepthRange as a conditional will always evaluate to true on Mac/Linux. glGetDoublev(GL_DEPTH_RANGE, DepthRangeSaved); #else GLfloat DepthRangefSaved[2]; @@ -547,7 +525,7 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) OVR_ASSERT(glGetError() == 0); GLint SampleMaskSaved = 0; - if(((GLMajorVersion * 100) + GLMinorVersion) >= 302) // OpenGL 3.2 or later + if (GLVersionInfo.WholeVersion >= 302) // OpenGL 3.2 or later { glGetIntegerv(GL_SAMPLE_MASK, &SampleMaskSaved); OVR_ASSERT(glGetError() == 0); @@ -572,37 +550,46 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) glGetIntegerv(GL_TEXTURE_BINDING_2D, &TextureBindingSaved); OVR_ASSERT(glGetError() == 0); - // https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glVertexAttribPointer.xml + GLint VertexArrayBindingSaved = 0; + if (GLVersionInfo.SupportsVAO) + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArrayBindingSaved); + + // If the core profile is enabled then we can't get the vertex attributes unless there is + // an active VAO. Otherwise there can be an error with some OpenGL implementations (notably Apple's). + // If the core profile is not enabled then pre-OpenGL 3.0 behavior is possible in which the + // application may not be using VAOs and thus there may be active vertex attributes. GLint VertexAttribEnabledSaved[kSavedVertexAttribCount]; GLint VertexAttribSizeSaved[kSavedVertexAttribCount]; GLint VertexAttribTypeSaved[kSavedVertexAttribCount]; GLint VertexAttribNormalizedSaved[kSavedVertexAttribCount]; GLint VertexAttribStrideSaved[kSavedVertexAttribCount]; GLvoid* VertexAttribPointerSaved[kSavedVertexAttribCount]; - for(GLuint i = 0; i < kSavedVertexAttribCount; i++) + + if(VertexArrayBindingSaved || !GLVersionInfo.IsCoreProfile) { - glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &VertexAttribEnabledSaved[i]); + for(GLuint i = 0; i < kSavedVertexAttribCount; i++) + { + // https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glVertexAttribPointer.xml + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &VertexAttribEnabledSaved[i]); - glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &VertexAttribSizeSaved[i]); - glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &VertexAttribTypeSaved[i]); - glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &VertexAttribNormalizedSaved[i]); - glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &VertexAttribStrideSaved[i]); - glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &VertexAttribPointerSaved[i]); + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &VertexAttribSizeSaved[i]); + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &VertexAttribTypeSaved[i]); + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &VertexAttribNormalizedSaved[i]); + glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &VertexAttribStrideSaved[i]); + glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &VertexAttribPointerSaved[i]); - OVR_ASSERT(glGetError() == 0); + OVR_ASSERT(glGetError() == 0); + } } - - GLint VertexArrayBindingSaved = 0; - if (SupportsVao) - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArrayBindingSaved); - // // End of save state // Load the graphics if not loaded already. if (!pTexture) + { LoadGraphics(); + } // Calculate ortho projection. GetOrthoProjection(RenderState, OrthoProjection); @@ -628,10 +615,10 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) // Set fixed-function render states glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); OVR_ASSERT(glGetError() == 0); - #if defined(OVR_OS_MAC) // On Mac we are directly using OpenGL functions instead of function pointers. + #if defined(OVR_OS_MAC) || defined(OVR_OS_LINUX) // On Mac/Linux we are directly using OpenGL functions instead of function pointers. glDepthRange(0.0, 1.0); #else - if(glDepthRange) // If we can use the double version (glDepthRangef may not be available)... + if(glDepthRange) // If we can use the double version (glDepthRangef isn't available with older OpenGL, glDepthRange isn't available with OpenGL ES)... glDepthRange(0.0, 1.0); else glDepthRangef(0.f, 1.f); @@ -645,8 +632,10 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) glDisable(GL_DITHER); glDisable(GL_RASTERIZER_DISCARD); glDisable(GL_SCISSOR_TEST); - if(((GLMajorVersion * 100) + GLMinorVersion) >= 302) // OpenGL 3.2 or later + if (GLVersionInfo.WholeVersion >= 302) // OpenGL 3.2 or later + { glDisable(GL_SAMPLE_MASK); + } glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); OVR_ASSERT(glGetError() == 0); @@ -668,18 +657,15 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) // To do: We must add support for vertext array objects (VAOs) here. When using an OpenGL 3.2+ core profile, // the application is required to use vertex array objects and glVertexAttribPointer will fail otherwise. - if(SupportsVao) + if (GLVersionInfo.SupportsVAO) { OVR_ASSERT(VAO != 0); + #ifdef OVR_OS_MAC - if(GLMajorVersion >= 3) - { - glBindVertexArray(VAO); - } - else - { - glBindVertexArrayAPPLE(VAO); - } + if(GLVersionInfo.WholeVersion >= 302) + glBindVertexArray(VAO); + else + glBindVertexArrayAPPLE(VAO); #else glBindVertexArray(VAO); #endif @@ -718,19 +704,15 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); OVR_ASSERT(glGetError() == 0); - if(SupportsVao) + if (GLVersionInfo.SupportsVAO) { VAOInitialized = true; #ifdef OVR_OS_MAC - if(GLMajorVersion >= 3) - { - glBindVertexArray(0); - } - else - { + if(GLVersionInfo.WholeVersion >= 302) + glBindVertexArray(0); + else glBindVertexArrayAPPLE(0); - } #else glBindVertexArray(0); #endif @@ -740,31 +722,21 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) // We restore the state in the reverse order that we saved it. // To do: Make the code below avoid changes that are effectively no-ops. // - if (SupportsVao) + if (GLVersionInfo.SupportsVAO) { -#ifdef OVR_OS_MAC - if(GLMajorVersion >= 3) - { + #ifdef OVR_OS_MAC + if(GLVersionInfo.WholeVersion >= 302) + glBindVertexArray(VertexArrayBindingSaved); + else + glBindVertexArrayAPPLE(VertexArrayBindingSaved); + #else glBindVertexArray(VertexArrayBindingSaved); - } - else - { - glBindVertexArrayAPPLE(VertexArrayBindingSaved); - } -#else - glBindVertexArray(VertexArrayBindingSaved); -#endif + #endif } - for (GLuint i = 0; i < kSavedVertexAttribCount; i++) + if(VertexArrayBindingSaved || !GLVersionInfo.IsCoreProfile) // If the OpenGL version is older or in core profile compatibility mode, or if there's a VAO currently installed... { - // We have a problem here: if the GL context was initialized with a core profile version 3.x or later, calls to glVertexAttribPointer can fail when there is no Vertex Array Object - // in place. That case is possible here, and we don't have an easy means to detect that a core profile was specified and thus that the glVertexAttribPointer call below could fail. - // Our current solution is to call glVertexAttribPointer only if vertex array objects are not supported. We cannot simply decide based on whether the given vertex attrib was enabled - // or if there was a vertex array object installed. With our solution below a problem can occur when using OpenGL 3.x+ which supports VAOs, the user has vertex attrib pointers installed, - // the currently installed VAO is 0, and the user is somehow dependent on us returning to the user with those vertex attrib pointers reinstalled. - - if (!SupportsVao || (VertexArrayBindingSaved != 0)) // If the OpenGL version is older or in core profile compatibility mode, or if there's a VAO currently installed... + for (GLuint i = 0; i < kSavedVertexAttribCount; i++) { glVertexAttribPointer(i, VertexAttribSizeSaved[i], VertexAttribTypeSaved[i], (GLboolean)VertexAttribNormalizedSaved[i], VertexAttribStrideSaved[i], VertexAttribPointerSaved[i]); @@ -776,14 +748,14 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) OVR_ASSERT(glGetError() == 0); } } - + glBindTexture(GL_TEXTURE_2D, TextureBindingSaved); glActiveTexture(ActiveTextureSaved); glUseProgram(ProgramSaved); glBindBuffer(GL_ARRAY_BUFFER, ArrayBufferBindingSaved); glColorMask((GLboolean)ColorWriteMaskSaved[0], (GLboolean)ColorWriteMaskSaved[1], (GLboolean)ColorWriteMaskSaved[2], (GLboolean)ColorWriteMaskSaved[3]); - if(((GLMajorVersion * 100) + GLMinorVersion) >= 302) // OpenGL 3.2 or later + if (GLVersionInfo.WholeVersion >= 302) // OpenGL 3.2 or later { if(SampleMaskSaved) glEnable(GL_SAMPLE_MASK); @@ -806,7 +778,8 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) else glDisable(GL_DITHER); - glBlendFunc(BlendSrcRGBSaved, BlendDstRGBSaved); // What about BlendSrcAlphaSaved / BlendDstAlphaSaved? + // With OpenGL 4.0+, we may need to be aware of glBlendFuncSeparatei. + glBlendFuncSeparate(BlendSrcRGBSaved, BlendDstRGBSaved, BlendSrcAlphaSaved, BlendDstAlphaSaved); if(BlendSaved) glEnable(GL_BLEND); @@ -826,7 +799,7 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) glDisable(GL_DEPTH_TEST); glDepthMask(DepthWriteMaskSaved ? GL_TRUE : GL_FALSE); - #if defined(OVR_OS_MAC) // On Mac we are directly using OpenGL functions instead of function pointers. + #if defined(OVR_OS_MAC) || defined(OVR_OS_LINUX) // On Mac/Linux we are directly using OpenGL functions instead of function pointers. glDepthRange(DepthRangeSaved[0], DepthRangeSaved[1]); #else if(glDepthRange) // If we can use the double version (glDepthRangef may not be available)... @@ -839,7 +812,9 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) glViewport(ViewportSaved[0], ViewportSaved[1], ViewportSaved[2], ViewportSaved[3]); glBindTexture(GL_TEXTURE_2D, TextureBinding2DSaved); glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferBindingSaved); - //glRenderMode(RenderModeSaved); + + if(!GLVersionInfo.IsCoreProfile) + glRenderMode(RenderModeSaved); OVR_ASSERT(glGetError() == 0); // @@ -848,12 +823,4 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) } - }}} // namespace OVR::CAPI::GL - - - - - - - diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h index 3517157..4b110d5 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h @@ -55,9 +55,7 @@ namespace OVR { namespace CAPI { namespace GL { void LoadGraphics(); OVR::CAPI::GL::RenderParams RenderParams; - int GLMajorVersion; // Derived from glGetString(GL_VERSION). To consider: Move this into GL::RenderParams. - int GLMinorVersion; // - bool SupportsVao; // True if Vertex Array Objects are supported by the OpenGL version. + GLVersionAndExtensions GLVersionInfo; GLuint FrameBuffer; // This is a container for a texture, depth buffer, stencil buffer to be rendered to. To consider: Make a wrapper class, like the OculusWorldDemo RBuffer class. Ptr<OVR::CAPI::GL::Texture> pTexture; Ptr<OVR::CAPI::GL::ShaderSet> pShaderSet; diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp index 22482d8..ed9e654 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp @@ -28,7 +28,6 @@ limitations under the License. namespace OVR { namespace CAPI { namespace GL { - // GL Hooks for non-Mac. #if !defined(OVR_OS_MAC) @@ -78,6 +77,7 @@ PFNGLENABLEIPROC glEnablei; PFNGLDISABLEIPROC glDisablei; PFNGLCOLORMASKIPROC glColorMaski; PFNGLGETINTEGERI_VPROC glGetIntegeri_v; +PFNGLGETSTRINGIPROC glGetStringi; PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; PFNGLDELETESHADERPROC glDeleteShader; @@ -124,7 +124,7 @@ PFNGLUNIFORM1FVPROC glUniform1fv; PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; PFNGLBINDVERTEXARRAYPROC glBindVertexArray; -PFNGLFEEDBACKBUFFERPROC glFeedbackBuffer; +PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate; #if defined(OVR_OS_WIN32) @@ -191,6 +191,7 @@ void InitGLExtensions() glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) GetFunction("glXSwapIntervalEXT"); #endif + glGetStringi = (PFNGLGETSTRINGIPROC) GetFunction("glGetStringi"); glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) GetFunction("glGenFramebuffersEXT"); glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) GetFunction("glDeleteFramebuffersEXT"); glEnablei = (PFNGLENABLEIPROC) GetFunction("glEnableIndexedEXT"); @@ -242,7 +243,7 @@ void InitGLExtensions() glDetachShader = (PFNGLDETACHSHADERPROC) GetFunction("glDetachShader"); glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) GetFunction("glBindAttribLocation"); glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) GetFunction("glGetAttribLocation"); - glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC) GetFunction("glFeedbackBuffer"); + glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) GetFunction("glBlendFuncSeparate"); } #endif @@ -499,7 +500,7 @@ void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize) UniformData = (unsigned char*)OVR_ALLOC(UniformsSize); } -Texture::Texture(RenderParams* rp, int w, int h) : IsUserAllocated(true), pParams(rp), TexId(0), Width(w), Height(h) +Texture::Texture(RenderParams* rp, int w, int h) : IsUserAllocated(false), pParams(rp), TexId(0), Width(w), Height(h) { if (w && h) glGenTextures(1, &TexId); @@ -573,6 +574,160 @@ void Texture::UpdatePlaceholderTexture(GLuint texId, const Sizei& textureSize) } -}}} +//// GLVersion + +void GLVersionAndExtensions::ParseGLVersion() +{ + const char* version = (const char*)glGetString(GL_VERSION); + int fields = 0, major = 0, minor = 0; + bool isGLES = false; + + OVR_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" + OVR_DISABLE_MSVC_WARNING(4996) // "scanf may be unsafe" + fields = sscanf(version, isdigit(*version) ? "%d.%d" : "%*[^0-9]%d.%d", &major, &minor); + isGLES = (strstr(version, "OpenGL ES") != NULL); + OVR_RESTORE_MSVC_WARNING() + } + 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; + IsGLES = isGLES; + IsCoreProfile = (MajorVersion >= 3); // Until we get a better way to detect core profiles, we err on the conservative side and set to true if the version is >= 3. +} + + +bool GLVersionAndExtensions::HasGLExtension(const char* searchKey) const +{ + if(Extensions && Extensions[0]) // If we have an extension string to search for individual extensions... + { + const int searchKeyLen = (int)strlen(searchKey); + const char* p = Extensions; + + for (;;) + { + p = strstr(p, searchKey); + + // If not found, + if (p == NULL) + { + break; + } + + // Only match full string + if ((p == Extensions || p[-1] == ' ') && + (p[searchKeyLen] == '\0' || p[searchKeyLen] == ' ')) + { + return true; + } + + // Skip ahead + p += searchKeyLen; + } + } + else + { + if(MajorVersion >= 3) // If glGetIntegerv(GL_NUM_EXTENSIONS, ...) is supported... + { + GLint extensionCount = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); + GLenum err = glGetError(); + + if(err == 0) + { + for(GLint i = 0; i != extensionCount; ++i) + { + const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, (GLuint)i); + + if(extension) // glGetStringi returns NULL upon error. + { + if(strcmp(extension, searchKey) == 0) + return true; + } + else + break; + } + } + } + } + + return false; +} + +void GLVersionAndExtensions::ParseGLExtensions() +{ + if(MajorVersion >= 3) + { + // Set to empty because we need to use glGetStringi to read extensions on recent OpenGL. + Extensions = ""; + } + else + { + const char* extensions = (const char*)glGetString(GL_EXTENSIONS); + + OVR_ASSERT(extensions); + if (!extensions) + { + extensions = ""; // Note: glGetString() can return null + LogText("Warning: GL_EXTENSIONS was NULL\n"); + } + else + { + // Cannot print this to debug log: It's too long! + //OVR_DEBUG_LOG(("GL_EXTENSIONS: %s", (const char*)extensions)); + } + + Extensions = extensions; + } + + // To do: revise the code below to loop through calls to glGetStringi(GL_EXTENSIONS, ...) so that all extensions below + // can be searched with a single pass over the extensions instead of a full loop per HasGLExtensionCall. + + if (MajorVersion >= 3) + { + SupportsVAO = true; + } + else + { + SupportsVAO = + HasGLExtension("GL_ARB_vertex_array_object") || + HasGLExtension("GL_APPLE_vertex_array_object"); + } + + SupportsDrawBuffers = HasGLExtension("GL_EXT_draw_buffers2"); + + // Add more extension checks here... +} + +void GetGLVersionAndExtensions(GLVersionAndExtensions& versionInfo) +{ + versionInfo.ParseGLVersion(); + // GL Version must be parsed before parsing extensions: + versionInfo.ParseGLExtensions(); + // To consider: Call to glGetStringi(GL_SHADING_LANGUAGE_VERSION, ...) check/validate the GLSL support. +} +}}} // namespace OVR::CAPI::GL diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h index bc7c8ab..aa6a26b 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h @@ -58,6 +58,7 @@ limitations under the License. namespace OVR { namespace CAPI { namespace GL { + // GL extension Hooks for Non-Mac. #if !defined(OVR_OS_MAC) @@ -69,7 +70,8 @@ typedef void (__stdcall *PFNGLENABLEPROC) (GLenum); typedef void (__stdcall *PFNGLDISABLEPROC) (GLenum); typedef void (__stdcall *PFNGLGETFLOATVPROC) (GLenum, GLfloat*); typedef const GLubyte * (__stdcall *PFNGLGETSTRINGPROC) (GLenum); -typedef void (__stdcall *PFNGLGETINTEGERVPROC) (GLenum, GLint*); +typedef const GLubyte * (__stdcall *PFNGLGETSTRINGIPROC) (GLenum, GLuint); +typedef void(__stdcall *PFNGLGETINTEGERVPROC) (GLenum, GLint*); typedef void (__stdcall *PFNGLGETDOUBLEVPROC) (GLenum, GLdouble*); typedef PROC (__stdcall *PFNWGLGETPROCADDRESS) (LPCSTR); typedef void (__stdcall *PFNGLFLUSHPROC) (); @@ -91,7 +93,6 @@ typedef void (__stdcall *PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, G typedef void (__stdcall *PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); typedef void (__stdcall *PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor); typedef void (__stdcall *PFNGLFRONTFACEPROC) (GLenum mode); -typedef void (__stdcall *PFNGLFEEDBACKBUFFERPROC) (GLsizei size, GLenum type, GLfloat *buffer); typedef GLint (__stdcall *PFNGLRENDERMODEPROC) (GLenum mode); typedef void (__stdcall *PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode); @@ -138,6 +139,7 @@ extern PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; #endif // defined(OVR_OS_WIN32) +extern PFNGLGETSTRINGIPROC glGetStringi; extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; extern PFNGLDELETESHADERPROC glDeleteShader; @@ -183,7 +185,7 @@ extern PFNGLUNIFORM1FVPROC glUniform1fv; extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; -extern PFNGLFEEDBACKBUFFERPROC glFeedbackBuffer; +extern PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate; extern void InitGLExtensions(); @@ -527,6 +529,7 @@ public: OVR_UNUSED(size); success = Compile((const char*) s); OVR_ASSERT(success); + OVR_UNUSED(success); InitUniforms(refl, reflSize); } ~ShaderImpl() @@ -571,7 +574,56 @@ typedef ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER> VertexShader; typedef ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER> FragmentShader; -}}} +//// GLVersionAndExtensions +// +// FIXME: CODE DUPLICATION WARNING +// Right now we have this same code in CommonSrc and in CAPI::GL. +// At some point we need to consolidate these, in Kernel or Util. +// Be sure to update both locations for now! +// +// This class needs to be initialized at runtime with GetGLVersionAndExtensions, +// after an OpenGL context has been created. It must be re-initialized any time +// a new OpenGL context is created, as the new context may differ in version or +// supported functionality. +struct GLVersionAndExtensions +{ + // Version information + int MajorVersion; // Best guess at major version + int MinorVersion; // Best guess at 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. + + // Extension information + bool SupportsVAO; // Supports Vertex Array Objects? + bool SupportsDrawBuffers; // Supports Draw Buffers? + const char* Extensions; // Other extensions string (will not be null) + + GLVersionAndExtensions() + : MajorVersion(0), + MinorVersion(0), + WholeVersion(0), + IsGLES(false), + IsCoreProfile(false), + SupportsDrawBuffers(false), + SupportsVAO(false), + Extensions("") + { + } + + bool HasGLExtension(const char* searchKey) const; + +protected: + friend void GetGLVersionAndExtensions(GLVersionAndExtensions& versionInfo); + + void ParseGLVersion(); + void ParseGLExtensions(); +}; + +void GetGLVersionAndExtensions(GLVersionAndExtensions& versionInfo); + + +}}} // namespace OVR::CAPI::GL #endif // INC_OVR_CAPI_GL_Util_h diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h index 9dfd8f6..c18f365 100644 --- a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h +++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h @@ -2,14 +2,14 @@ #define DISTORTIONCHROMA_PS_H static const unsigned char DistortionChroma_ps[] = { - 0x44, 0x58, 0x42, 0x43, 0x2b, 0x0d, 0x42, 0xef, 0x6d, 0xea, 0x8e, 0x3c, - 0xe8, 0x90, 0x79, 0x04, 0xfe, 0x42, 0xcf, 0xba, 0x01, 0x00, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0xac, 0x01, 0x00, 0x00, 0x50, 0x02, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, - 0x94, 0x05, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x70, 0x01, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x8b, 0xb5, 0x62, 0xd4, 0xa4, 0xf3, 0xee, 0xa6, + 0x11, 0x95, 0x03, 0x4f, 0xaa, 0x21, 0xa6, 0x42, 0x01, 0x00, 0x00, 0x00, + 0x74, 0x0b, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0xbc, 0x01, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0xac, 0x02, 0x00, 0x00, + 0xf8, 0x0a, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x80, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, - 0x3c, 0x01, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x4c, 0x01, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, @@ -26,109 +26,224 @@ static const unsigned char DistortionChroma_ps[] = { 0xb7, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2c, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x4f, 0x76, 0x65, 0x72, 0x64, 0x72, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x76, - 0x52, 0x54, 0x53, 0x69, 0x7a, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, - 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x76, 0x65, 0x72, 0x64, 0x72, 0x69, 0x76, 0x65, 0x53, 0x63, 0x61, - 0x6c, 0x65, 0x73, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, - 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, - 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, - 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, - 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, - 0x9c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x03, 0x00, 0x00, - 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, - 0x92, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x92, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, - 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, - 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, - 0x52, 0x44, 0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x44, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, - 0xf0, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, - 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, - 0x00, 0x70, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0x64, 0x20, 0x00, 0x04, 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0x12, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0x62, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0xc2, 0x10, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x96, 0x15, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, + 0x6c, 0x65, 0x73, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x61, 0x44, 0x65, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x76, 0x65, 0x4d, 0x75, 0x6c, 0x74, + 0x00, 0xab, 0xab, 0xab, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, + 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x39, + 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0xab, + 0x49, 0x53, 0x47, 0x4e, 0x9c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x03, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x06, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0c, 0x0c, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, + 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, + 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0xab, 0xab, + 0x53, 0x48, 0x44, 0x52, 0x44, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x11, 0x02, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, + 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, + 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x55, 0x55, 0x00, 0x00, 0x64, 0x20, 0x00, 0x04, 0x32, 0x10, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, + 0x12, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, + 0x62, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, + 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, + 0xc2, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, + 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, + 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, + 0x08, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x96, 0x15, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, - 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, + 0xf2, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe6, 0x1a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x0b, 0x62, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa6, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x04, 0x03, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0a, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x05, + 0x22, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1a, 0x10, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x32, 0x00, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xa6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xa2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x08, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x56, 0x19, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xd6, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xf2, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x86, 0x08, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x46, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, + 0xf2, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x22, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, + 0xd2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x42, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x86, 0x06, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x96, 0x19, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x46, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xf2, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x86, 0x08, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x46, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, + 0xf2, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x22, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, + 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x66, 0x06, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x46, 0x1e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, + 0xf2, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xe6, 0x1a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x22, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, - 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x31, 0x00, 0x00, 0x08, 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x04, 0x03, - 0x3a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, - 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x7e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x22, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0x82, 0x00, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xa2, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa6, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x56, 0x19, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, + 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0xd6, 0x05, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, 0xf2, 0x00, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x66, 0x06, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0xbf, 0x46, 0x1e, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x31, 0x00, 0x00, 0x07, 0x72, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x0b, 0x72, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0xa6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf6, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x20, 0x00, 0x09, - 0x72, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, + 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xe6, 0x0a, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x22, 0x00, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x22, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xd2, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x06, 0x09, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xd2, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x09, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xd2, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x06, 0x09, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xd2, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x06, 0x09, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x0a, 0xd2, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x40, 0x00, 0x00, 0xcd, 0xcc, 0x4c, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0xcd, 0xcc, 0x4c, 0x3e, 0xcd, 0xcc, 0x4c, 0x3e, 0x4b, 0x00, 0x00, 0x05, + 0x72, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x86, 0x03, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x01, 0x36, 0x00, 0x00, 0x05, + 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x22, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x07, 0xb2, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x08, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x04, 0x03, + 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x05, + 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2d, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x07, 0x72, 0x00, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x0b, + 0x72, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x06, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x85, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x82, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3f, 0x12, 0x00, 0x00, 0x01, 0x36, 0x00, 0x00, 0x05, - 0x72, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x15, 0x00, 0x00, 0x01, 0x36, 0x00, 0x00, 0x05, 0x72, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x20, 0x00, 0x09, + 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x46, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x01, + 0x36, 0x00, 0x00, 0x05, 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x01, + 0x36, 0x00, 0x00, 0x05, 0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0x72, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, - 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh index 9886fc3..b19332c 100644 --- a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh +++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh @@ -2,11 +2,44 @@ Texture2D Texture : register(t0); Texture2D LastTexture : register(t1);
SamplerState Linear : register(s0);
-float2 OverdriveInvRTSize;
float2 OverdriveScales;
+float AaDerivativeMult;
+
+// Fast approximate gamma to linear conversion when averaging colors
+float3 ToLinear(float3 inColor) { return inColor * inColor; }
+float3 ToGamma(float3 inColor) { return sqrt(inColor); }
+
+float3 ApplyHqAa(float3 inColor, float2 oTexCoord0, float2 oTexCoord1, float2 oTexCoord2)
+{
+ float2 uvDeriv = float2(ddx(oTexCoord1.x), ddy(oTexCoord1.y)) * AaDerivativeMult;
+
+ float ResultR = Texture.SampleLevel(Linear, oTexCoord0 + float2(-uvDeriv.x, 0), 0.0).r;
+ float ResultG = Texture.SampleLevel(Linear, oTexCoord1 + float2(-uvDeriv.x, 0), 0.0).g;
+ float ResultB = Texture.SampleLevel(Linear, oTexCoord2 + float2(-uvDeriv.x, 0), 0.0).b;
+ float3 newColor0 = ToLinear(float3(ResultR, ResultG, ResultB));
+
+ ResultR = Texture.SampleLevel(Linear, oTexCoord0 + float2(uvDeriv.x, 0), 0.0).r;
+ ResultG = Texture.SampleLevel(Linear, oTexCoord1 + float2(uvDeriv.x, 0), 0.0).g;
+ ResultB = Texture.SampleLevel(Linear, oTexCoord2 + float2(uvDeriv.x, 0), 0.0).b;
+ float3 newColor1 = ToLinear(float3(ResultR, ResultG, ResultB));
+
+ ResultR = Texture.SampleLevel(Linear, oTexCoord0 + float2(0, uvDeriv.y), 0.0).r;
+ ResultG = Texture.SampleLevel(Linear, oTexCoord1 + float2(0, uvDeriv.y), 0.0).g;
+ ResultB = Texture.SampleLevel(Linear, oTexCoord2 + float2(0, uvDeriv.y), 0.0).b;
+ float3 newColor2 = ToLinear(float3(ResultR, ResultG, ResultB));
+
+ ResultR = Texture.SampleLevel(Linear, oTexCoord0 + float2(0, -uvDeriv.y), 0.0).r;
+ ResultG = Texture.SampleLevel(Linear, oTexCoord1 + float2(0, -uvDeriv.y), 0.0).g;
+ ResultB = Texture.SampleLevel(Linear, oTexCoord2 + float2(0, -uvDeriv.y), 0.0).b;
+ float3 newColor3 = ToLinear(float3(ResultR, ResultG, ResultB));
+
+ float3 outColor = ToLinear(inColor) + newColor0 + newColor1 + newColor2 + newColor3;
+ outColor = ToGamma(outColor * 0.2);
+ return outColor;
+}
void main(in float4 oPosition : SV_Position,
- in float1 oColor : COLOR,
+ in float oColor : COLOR,
in float2 oTexCoord0 : TEXCOORD0,
in float2 oTexCoord1 : TEXCOORD1,
in float2 oTexCoord2 : TEXCOORD2,
@@ -16,15 +49,22 @@ void main(in float4 oPosition : SV_Position, float ResultR = Texture.SampleLevel(Linear, oTexCoord0, 0.0).r;
float ResultG = Texture.SampleLevel(Linear, oTexCoord1, 0.0).g;
float ResultB = Texture.SampleLevel(Linear, oTexCoord2, 0.0).b;
- float3 newColor = float3(ResultR * oColor, ResultG * oColor, ResultB * oColor);
+ float3 newColor = float3(ResultR, ResultG, ResultB);
+
+ // High quality anti-aliasing in distortion
+ if(AaDerivativeMult > 0)
+ {
+ newColor = ApplyHqAa(newColor, oTexCoord0, oTexCoord1, oTexCoord2);
+ }
+ newColor = newColor * oColor.xxx;
outColor0 = float4(newColor, 1.0);
outColor1 = outColor0;
-
+
// pixel luminance overdrive
- if(OverdriveInvRTSize.x > 0)
+ if(OverdriveScales.x > 0)
{
- float3 oldColor = LastTexture.SampleLevel(Linear, oPosition.xy * OverdriveInvRTSize.xy, 0.0).rgb;
+ float3 oldColor = LastTexture.Load(int3(oPosition.xy, 0)).rgb;
float3 adjustedScales;
adjustedScales.x = newColor.x > oldColor.x ? OverdriveScales.x : OverdriveScales.y;
diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h index 1f09c5e..4c66392 100644 --- a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h +++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h @@ -2,8 +2,8 @@ const OVR::CAPI::D3D_NS::ShaderBase::Uniform DistortionChroma_ps_refl[] = { - { "OverdriveInvRTSize", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "OverdriveScales", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, + { "OverdriveScales", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "AaDerivativeMult", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 4 }, }; #endif diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h index aa5003f..72587eb 100644 --- a/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h +++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h @@ -2,8 +2,8 @@ #define DISTORTIONCHROMA_VS_H static const unsigned char DistortionChroma_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0x8e, 0x20, 0x97, 0xab, 0xce, 0xc8, 0x74, 0x3e, - 0xfe, 0xeb, 0x97, 0xa0, 0xe6, 0xca, 0x72, 0xa1, 0x01, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x0e, 0xfe, 0xef, 0x9e, 0xe4, 0xce, 0x0b, 0xf4, + 0xdc, 0xc4, 0xfc, 0x1d, 0x3a, 0xf6, 0x54, 0x11, 0x01, 0x00, 0x00, 0x00, 0x64, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 0x7c, 0x02, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, @@ -26,8 +26,8 @@ static const unsigned char DistortionChroma_vs[] = { 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, - 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x39, + 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x98, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -87,7 +87,7 @@ static const unsigned char DistortionChroma_vs[] = { 0xa6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h index 3344482..c8cd966 100644 --- a/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h +++ b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h @@ -2,11 +2,11 @@ #define DISTORTIONTIMEWARPCHROMA_VS_H static const unsigned char DistortionTimewarpChroma_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0x46, 0xb0, 0x5a, 0x1b, 0xfd, 0x8c, 0xdb, 0xa9, - 0x8d, 0x82, 0x83, 0x1f, 0xd6, 0x4f, 0x4a, 0x8f, 0x01, 0x00, 0x00, 0x00, - 0xac, 0x09, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x98, 0x01, 0x00, 0x00, 0x38, 0x02, 0x00, 0x00, 0xdc, 0x02, 0x00, 0x00, - 0x30, 0x09, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x5c, 0x01, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x80, 0x9f, 0x5c, 0x4f, 0x89, 0x6f, 0x5a, 0xbf, + 0x65, 0xe8, 0x9a, 0x58, 0x95, 0xd7, 0x18, 0x18, 0x01, 0x00, 0x00, 0x00, + 0xb0, 0x09, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x9c, 0x01, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x00, 0xe0, 0x02, 0x00, 0x00, + 0x34, 0x09, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x60, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -34,181 +34,181 @@ static const unsigned char DistortionTimewarpChroma_vs[] = { 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, - 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, - 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, - 0x49, 0x53, 0x47, 0x4e, 0x98, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0f, 0x09, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, - 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, - 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x9c, 0x00, 0x00, 0x00, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, + 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, + 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x98, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x09, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, - 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, - 0x53, 0x48, 0x44, 0x52, 0x4c, 0x06, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, - 0x93, 0x01, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x92, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x62, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0xc2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x1f, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x11, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x32, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x32, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x16, 0x85, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x85, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x22, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x42, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x92, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x82, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x22, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, - 0x42, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x96, 0x05, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0x62, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa6, 0x8b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, + 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, + 0x9c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, + 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, + 0x92, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x00, 0x00, + 0x92, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, + 0x52, 0x44, 0x00, 0xab, 0x53, 0x48, 0x44, 0x52, 0x4c, 0x06, 0x00, 0x00, + 0x40, 0x00, 0x01, 0x00, 0x93, 0x01, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, + 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x92, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x12, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x62, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x32, 0x20, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xc2, 0x20, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0xc2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x3a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x1f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x00, 0x00, 0x80, 0x3f, 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x80, 0x3f, 0x11, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x32, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x32, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0x85, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x16, 0x85, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x52, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x56, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x92, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x56, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x3a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x22, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, - 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x96, 0x05, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xa6, 0x0a, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, + 0x62, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa6, 0x8b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x32, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x11, 0x00, 0x00, 0x07, - 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x07, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x12, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x07, 0x22, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x07, - 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0b, 0xc2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x06, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, - 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0b, 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x11, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x82, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, + 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe6, 0x0a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0xc2, 0x20, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x06, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #endif diff --git a/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h index f3111a8..6c79c56 100644 --- a/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h +++ b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h @@ -2,11 +2,11 @@ #define DISTORTIONTIMEWARP_VS_H static const unsigned char DistortionTimewarp_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0x96, 0x74, 0x01, 0x0e, 0x69, 0xc5, 0xe0, 0xbd, - 0x73, 0x27, 0xa6, 0x54, 0x7e, 0xee, 0xb9, 0xb6, 0x01, 0x00, 0x00, 0x00, - 0x7c, 0x07, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x98, 0x01, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x7c, 0x02, 0x00, 0x00, - 0x00, 0x07, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x5c, 0x01, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x91, 0xed, 0x41, 0x60, 0xb0, 0x3e, 0xf0, 0x08, + 0x7a, 0xeb, 0x1b, 0xe6, 0x05, 0x4c, 0x48, 0xd2, 0x01, 0x00, 0x00, 0x00, + 0x80, 0x07, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x9c, 0x01, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, + 0x04, 0x07, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x60, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -34,134 +34,135 @@ static const unsigned char DistortionTimewarp_vs[] = { 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, - 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, - 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, - 0x49, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0f, 0x09, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, - 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, - 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, + 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, + 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, - 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, - 0x53, 0x48, 0x44, 0x52, 0x7c, 0x04, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, - 0x1f, 0x01, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x92, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x62, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x1f, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x62, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x81, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x62, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x22, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x09, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, + 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, + 0x6c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, + 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, + 0x52, 0x44, 0x00, 0xab, 0x53, 0x48, 0x44, 0x52, 0x7c, 0x04, 0x00, 0x00, + 0x40, 0x00, 0x01, 0x00, 0x1f, 0x01, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, + 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x92, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x12, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x62, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0xc2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x3a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x1f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0xc2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x62, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x81, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x92, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, - 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x96, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0x62, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa6, 0x8b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x62, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x56, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x52, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x56, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x92, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x56, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, + 0x82, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x07, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x96, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, + 0x62, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa6, 0x8b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, + 0x74, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; #endif diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_ps.h b/LibOVR/Src/CAPI/Shaders/Distortion_ps.h index a486bba..2463ff4 100644 --- a/LibOVR/Src/CAPI/Shaders/Distortion_ps.h +++ b/LibOVR/Src/CAPI/Shaders/Distortion_ps.h @@ -2,11 +2,11 @@ #define DISTORTION_PS_H static const unsigned char Distortion_ps[] = { - 0x44, 0x58, 0x42, 0x43, 0x7c, 0x85, 0xba, 0x67, 0x3a, 0xd7, 0x3f, 0x92, - 0xa7, 0x4b, 0x33, 0x10, 0x5b, 0x1b, 0x09, 0x5d, 0x01, 0x00, 0x00, 0x00, - 0xb4, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0xd8, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, - 0x38, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x9c, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x43, 0xb8, 0xfc, 0x1d, 0x5b, 0xd5, 0xae, 0xc2, + 0x67, 0xa3, 0x69, 0xc1, 0x8c, 0xb8, 0xbe, 0x9d, 0x01, 0x00, 0x00, 0x00, + 0xb8, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0xdc, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, + 0x3c, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, @@ -18,48 +18,49 @@ static const unsigned char Distortion_ps[] = { 0x61, 0x72, 0x00, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, - 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, - 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, - 0x49, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, + 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, + 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, + 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, + 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x00, 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, 0xb0, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, + 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, + 0x62, 0x10, 0x00, 0x03, 0x12, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x62, 0x10, 0x00, 0x03, 0x62, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, + 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x15, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x72, 0x20, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, + 0x74, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x06, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, - 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, - 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0xab, 0xab, - 0x53, 0x48, 0x44, 0x52, 0xb0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x2c, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, - 0x12, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, - 0x62, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x96, 0x15, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; #endif diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_vs.h b/LibOVR/Src/CAPI/Shaders/Distortion_vs.h index 8520fd9..3d3552b 100644 --- a/LibOVR/Src/CAPI/Shaders/Distortion_vs.h +++ b/LibOVR/Src/CAPI/Shaders/Distortion_vs.h @@ -2,8 +2,8 @@ #define DISTORTION_VS_H static const unsigned char Distortion_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0xfd, 0x23, 0xd7, 0xc6, 0x1a, 0x85, 0x42, 0xd8, - 0xf1, 0xf2, 0x06, 0x88, 0x86, 0xf0, 0xd9, 0xc7, 0x01, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x77, 0x9d, 0x99, 0x8c, 0xc0, 0xf3, 0x3f, 0xec, + 0xf9, 0x83, 0x0b, 0xe5, 0x85, 0x2b, 0x86, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, @@ -26,8 +26,8 @@ static const unsigned char Distortion_vs[] = { 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, - 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x39, + 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -68,7 +68,7 @@ static const unsigned char Distortion_vs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h index 796a880..2c01e6c 100644 --- a/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h +++ b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h @@ -2,8 +2,8 @@ #define SIMPLEQUAD_PS_H static const unsigned char SimpleQuad_ps[] = { - 0x44, 0x58, 0x42, 0x43, 0x8c, 0x53, 0x2f, 0x7c, 0x3d, 0xea, 0xa5, 0xb6, - 0x05, 0xb7, 0xe0, 0x83, 0x67, 0x16, 0x9c, 0x93, 0x01, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0xc5, 0x64, 0xa2, 0x55, 0x15, 0x24, 0x7d, 0xe6, + 0x27, 0xd2, 0xf4, 0x4e, 0x42, 0xb6, 0xba, 0x78, 0x01, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xc4, 0x00, 0x00, 0x00, @@ -21,9 +21,9 @@ static const unsigned char SimpleQuad_ps[] = { 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, - 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, - 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, - 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x08, 0x00, 0x00, 0x00, + 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, + 0x2e, 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, + 0x34, 0x00, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h index d3387ce..510c200 100644 --- a/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h +++ b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h @@ -2,8 +2,8 @@ #define SIMPLEQUAD_VS_H static const unsigned char SimpleQuad_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0xd5, 0x40, 0x5f, 0xa6, 0x2d, 0x0a, 0xd9, 0x2a, - 0x84, 0x41, 0x9e, 0x1f, 0xab, 0xa5, 0xa9, 0x2c, 0x01, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0xb2, 0x87, 0xff, 0xa1, 0x41, 0xd7, 0x0e, 0x94, + 0x59, 0xd6, 0x1b, 0x8c, 0x94, 0x3d, 0xb9, 0x46, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, @@ -26,8 +26,8 @@ static const unsigned char SimpleQuad_vs[] = { 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, - 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x39, + 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -50,7 +50,7 @@ static const unsigned char SimpleQuad_vs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/LibOVR/Src/CAPI/Shaders/SimpleTexturedQuad_ps.h b/LibOVR/Src/CAPI/Shaders/SimpleTexturedQuad_ps.h index dd5cae3..c8b1a82 100644 --- a/LibOVR/Src/CAPI/Shaders/SimpleTexturedQuad_ps.h +++ b/LibOVR/Src/CAPI/Shaders/SimpleTexturedQuad_ps.h @@ -2,8 +2,8 @@ #define SIMPLETEXTUREDQUAD_PS_H static const unsigned char SimpleTexturedQuad_ps[] = { - 0x44, 0x58, 0x42, 0x43, 0xbe, 0x17, 0xf1, 0xab, 0xc8, 0x62, 0x4c, 0x11, - 0xe8, 0x29, 0xb0, 0x5b, 0x0b, 0xf8, 0x73, 0x38, 0x01, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x28, 0x50, 0xb2, 0x7b, 0x03, 0x55, 0x33, 0xd0, + 0x24, 0xd2, 0xc9, 0x9f, 0x95, 0x9b, 0xa9, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x44, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x18, 0x01, 0x00, 0x00, @@ -28,9 +28,9 @@ static const unsigned char SimpleTexturedQuad_ps[] = { 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, - 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, - 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, - 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, + 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, + 0x2e, 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, + 0x34, 0x00, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, diff --git a/LibOVR/Src/CAPI/Shaders/SimpleTexturedQuad_vs.h b/LibOVR/Src/CAPI/Shaders/SimpleTexturedQuad_vs.h index 0375fdc..9f5b45d 100644 --- a/LibOVR/Src/CAPI/Shaders/SimpleTexturedQuad_vs.h +++ b/LibOVR/Src/CAPI/Shaders/SimpleTexturedQuad_vs.h @@ -2,8 +2,8 @@ #define SIMPLETEXTUREDQUAD_VS_H static const unsigned char SimpleTexturedQuad_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0xe3, 0x2d, 0x41, 0xb3, 0xee, 0x4c, 0x7d, 0xb3, - 0x80, 0x0d, 0x3a, 0x0c, 0xb6, 0x80, 0x5e, 0xb1, 0x01, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x65, 0x25, 0x0c, 0xd1, 0x14, 0xa7, 0xfd, 0xde, + 0xf4, 0x91, 0xf7, 0xf7, 0x9e, 0xd4, 0xa5, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, @@ -26,8 +26,8 @@ static const unsigned char SimpleTexturedQuad_vs[] = { 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, - 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x39, + 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -68,7 +68,7 @@ static const unsigned char SimpleTexturedQuad_vs[] = { 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/LibOVR/Src/Displays/OVR_Display.cpp b/LibOVR/Src/Displays/OVR_Display.cpp index 65f0b30..c7a624f 100644 --- a/LibOVR/Src/Displays/OVR_Display.cpp +++ b/LibOVR/Src/Displays/OVR_Display.cpp @@ -29,4 +29,8 @@ limitations under the License. namespace OVR { -} + +// Place platform-independent code here + + +} // namespace OVR diff --git a/LibOVR/Src/Displays/OVR_Display.h b/LibOVR/Src/Displays/OVR_Display.h index 3184182..bcba4bc 100644 --- a/LibOVR/Src/Displays/OVR_Display.h +++ b/LibOVR/Src/Displays/OVR_Display.h @@ -189,6 +189,10 @@ public: // Check if right now the current rendering application should be in compatibility mode static bool InCompatibilityMode( bool displaySearch = true ); + // Get/set the mode for all applications + static bool GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode); + static bool SetDriverMode(bool compatMode, bool hideDK1Mode); + static DisplaySearchHandle* GetDisplaySearchHandle(); }; diff --git a/LibOVR/Src/Displays/OVR_Win32_Display.cpp b/LibOVR/Src/Displays/OVR_Win32_Display.cpp index 8300468..6bebc7b 100644 --- a/LibOVR/Src/Displays/OVR_Win32_Display.cpp +++ b/LibOVR/Src/Displays/OVR_Win32_Display.cpp @@ -37,10 +37,14 @@ limitations under the License. #include <SetupAPI.h> #include <Mmsystem.h> #include <conio.h> + +#ifdef OVR_COMPAT_EDID_VIA_WMI # pragma comment(lib, "wbemuuid.lib") #include <wbemidl.h> -#include <AtlBase.h> -#include <AtlConv.h> +#else // OVR_COMPAT_EDID_VIA_WMI +#include <setupapi.h> +#include <initguid.h> +#endif // OVR_COMPAT_EDID_VIA_WMI // WIN32_LEAN_AND_MEAN included in OVR_Atomic.h may break 'byte' declaration. #ifdef WIN32_LEAN_AND_MEAN @@ -56,7 +60,8 @@ typedef struct UINT ExpectedWidth; UINT ExpectedHeight; HWND hWindow; - bool InCompatibilityMode; + bool CompatibilityMode; + bool HideDK1Mode; } ContextStruct; static ContextStruct GlobalDisplayContext = {0}; @@ -89,7 +94,7 @@ ULONG getRift( HANDLE hDevice, int index ) { ULONG riftCount = getRiftCount( hDevice ); DWORD bytesReturned = 0; - BOOL result; + BOOL result; if( riftCount >= (ULONG)index ) { @@ -334,11 +339,10 @@ static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwDa return TRUE; }; +#ifdef OVR_COMPAT_EDID_VIA_WMI static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, String& userFriendlyNameStr ) { - USES_CONVERSION; - IWbemLocator *pLoc = NULL; IWbemServices *pSvc = NULL; HRESULT hres; @@ -350,8 +354,10 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { - OVR_DEBUG_LOG_TEXT(("Failed to initialize COM library. Error code = 0x%x\n", hres)); - return false; + + LogError("{ERR-082} [Display] WARNING: Failed to initialize COM library. Error code = 0x%x", hres); + OVR_ASSERT(false); + return false; } hres = CoInitializeSecurity( @@ -368,10 +374,9 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S if (FAILED(hres)) { - OVR_DEBUG_LOG_TEXT(("Failed to initialize security. Error code = 0x%x\n", hres)); - //CoUninitialize(); - //return false; - selfInitialized = false; + LogError("{ERR-083} [Display] WARNING: Failed to initialize security. Error code = 0x%x", hres); + OVR_ASSERT(false); + selfInitialized = false; } initialized = true; @@ -385,8 +390,9 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S if (FAILED(hres)) { - OVR_DEBUG_LOG_TEXT(("Failed to create IWbemLocator object. Err code = 0x%x\n", hres)); - return false; + LogError("{ERR-084} [Display] WARNING: Failed to create IWbemLocator object.Err code = 0x%x", hres); + OVR_ASSERT(false); + return false; } BSTR AbackB = SysAllocString(L"root\\WMI"); @@ -407,8 +413,9 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S if (FAILED(hres)) { - OVR_DEBUG_LOG_TEXT(("Could not connect. Error code = 0x%x\n", hres)); - pLoc->Release(); + LogError("{ERR-085} [Display] WARNING: Could not connect to root\\WMI. Error code = 0x%x", hres); + OVR_ASSERT(false); + pLoc->Release(); return false; } @@ -425,8 +432,9 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S if (FAILED(hres)) { - OVR_DEBUG_LOG_TEXT(("Could not set proxy blanket. Error code = 0x%x\n", hres)); - pSvc->Release(); + LogError("{ERR-086} [Display] WARNING: Could not set proxy blanket. Error code = 0x%x", hres); + OVR_ASSERT(false); + pSvc->Release(); pLoc->Release(); return false; } @@ -446,12 +454,16 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S if (FAILED(hres)) { - OVR_DEBUG_LOG_TEXT(( "Query for operating system name failed. Error code = 0x%x\n", hres )); - pSvc->Release(); + LogError("{ERR-087} [Display] WARNING: Query for operating system name failed. Error code = 0x%x", hres); + OVR_ASSERT(false); + pSvc->Release(); pLoc->Release(); return false; } + int enumeratedCount = 0; + bool found = false; + IWbemClassObject *pclsObj = 0; while (pEnumerator) { @@ -463,29 +475,31 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S break; } - VARIANT vtProp; - hr = pclsObj->Get(L"InstanceName", 0, &vtProp, 0, 0); + ++enumeratedCount; + + VARIANT vtProp; + hr = pclsObj->Get(L"InstanceName", 0, &vtProp, 0, 0); - WCHAR* instanceName = vtProp.bstrVal; - WCHAR* nextToken = NULL; - if (SUCCEEDED(hr) && + WCHAR* instanceName = vtProp.bstrVal; + WCHAR* nextToken = NULL; + if (SUCCEEDED(hr) && wcstok_s(instanceName, L"\\", &nextToken) != NULL) - { - WCHAR* aToken = wcstok_s(NULL, L"\\", &nextToken); + { + WCHAR* aToken = wcstok_s(NULL, L"\\", &nextToken); - if (aToken != NULL) - { - VariantClear(&vtProp); + if (aToken != NULL) + { + VariantClear(&vtProp); - if (wcscmp(aToken, displayName) != 0) - { + if (wcscmp(aToken, displayName) != 0) + { pclsObj->Release(); continue; - } + } - // Read serial + // Read serial - hr = pclsObj->Get(L"SerialNumberID", 0, &vtProp, 0, 0); + hr = pclsObj->Get(L"SerialNumberID", 0, &vtProp, 0, 0); if (SUCCEEDED(hr)) { @@ -505,21 +519,21 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S } else { - OVR_DEBUG_LOG(("[Win32Display] WARNING: Wrong data format for SerialNumberID")); + LogError("{ERR-088} [Display] WARNING: Wrong data format for SerialNumberID"); } VariantClear(&vtProp); } else { - OVR_DEBUG_LOG(("[Win32Display] WARNING: Failure getting display SerialNumberID: %d", (int)hr)); + LogError("{ERR-089} [Display] WARNING: Failure getting display SerialNumberID: %d", (int)hr); } - // Read length of name + // Read length of name int userFriendlyNameLen = 0; - hr = pclsObj->Get(L"UserFriendlyNameLength", 0, &vtProp, 0, 0); + hr = pclsObj->Get(L"UserFriendlyNameLength", 0, &vtProp, 0, 0); if (SUCCEEDED(hr)) { @@ -531,24 +545,24 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S { userFriendlyNameLen = 0; - OVR_DEBUG_LOG(("[Win32Display] WARNING: UserFriendlyNameLength = 0")); + LogError("{ERR-090} [Display] WARNING: UserFriendlyNameLength = 0"); } } else { - OVR_DEBUG_LOG(("[Win32Display] WARNING: Wrong data format for UserFriendlyNameLength")); + LogError("{ERR-091} [Display] WARNING: Wrong data format for UserFriendlyNameLength"); } VariantClear(&vtProp); } else { - OVR_DEBUG_LOG(("[Win32Display] WARNING: Failure getting display UserFriendlyNameLength: %d", (int)hr)); + LogError("{ERR-092} [Display] WARNING: Failure getting display UserFriendlyNameLength: %d", (int)hr); } - // Read name + // Read name - hr = pclsObj->Get(L"UserFriendlyName", 0, &vtProp, 0, 0); + hr = pclsObj->Get(L"UserFriendlyName", 0, &vtProp, 0, 0); if (SUCCEEDED(hr) && userFriendlyNameLen > 0) { @@ -570,20 +584,23 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S { // See: https://developer.oculusvr.com/forums/viewtopic.php?f=34&t=10961 // This can happen if someone has an EDID override in the registry. - OVR_DEBUG_LOG(("[Win32Display] WARNING: Wrong data format for UserFriendlyName")); + LogError("{ERR-093} [Display] WARNING: Wrong data format for UserFriendlyName"); } VariantClear(&vtProp); } else { - OVR_DEBUG_LOG(("[Win32Display] WARNING: Failure getting display UserFriendlyName: %d", (int)hr)); + LogError("{ERR-094} [Display] WARNING: Failure getting display UserFriendlyName: %d", (int)hr); } - } + } + + found = true; + pclsObj->Release(); + break; } - pclsObj->Release(); - break; + pclsObj->Release(); } HMODULE hModule = GetModuleHandleA("wbemuuid"); @@ -596,9 +613,201 @@ static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, S pLoc->Release(); pEnumerator->Release(); - return true; + if (!found) + { + LogError("{ERR-095} [Display] WARNING: Unable to enumerate the rift via WMI (found %d monitors). This is not normally an issue. Running as a user with Administrator privileges has fixed this problem in the past.", enumeratedCount); + OVR_ASSERT(false); + } + + return found; +} + +#else // OVR_COMPAT_EDID_VIA_WMI + +#define NAME_SIZE 128 + +DEFINE_GUID(GUID_CLASS_MONITOR, + 0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, + 0x03, 0x18); + +static void truncateNonalphanum(char* str, int len) +{ + for (int i = 0; i < len; ++i) + { + char ch = str[i]; + + if ((ch < 'A' || ch > 'Z') && + (ch < 'a' || ch > 'z') && + (ch < '0' || ch > '9') && + ch != ' ') + { + str[i] = '\0'; + break; + } + } +} + +static bool AccessDeviceRegistry(IN HDEVINFO devInfo, IN PSP_DEVINFO_DATA devInfoData, + const WCHAR* displayName, String& serialNumberStr, String& userFriendlyNameStr) +{ + // Match hardware id to display name + WCHAR hardwareId[128]; + if (!SetupDiGetDeviceRegistryProperty( + devInfo, + devInfoData, + SPDRP_HARDWAREID, + NULL, + (PBYTE)hardwareId, + sizeof(hardwareId), + NULL)) + { + LogError("{ERR-096} [Display] WARNING: SetupDiGetDeviceRegistryProperty for SPDRP_HARDWAREID failed. LastErr=%d", GetLastError()); + OVR_ASSERT(false); + return false; + } + hardwareId[127] = 0; + + // If the hardware id did not match, + if (!wcsstr(hardwareId, displayName)) + { + // Stop here + return false; + } + + // Grab hardware info registry key + HKEY hDevRegKey = SetupDiOpenDevRegKey( + devInfo, + devInfoData, + DICS_FLAG_GLOBAL, + 0, + DIREG_DEV, + KEY_READ); // Only read permissions so it can be run without Administrator privs + + if (hDevRegKey == INVALID_HANDLE_VALUE) + { + LogError("{ERR-097} [Display] WARNING: SetupDiOpenDevRegKey failed. LastErr=%d", GetLastError()); + OVR_ASSERT(false); + return false; + } + + // Enumerate keys in registry + bool found = false; + + // For each key, + for (int i = 0;; i++) + { + BYTE EDIDdata[1024]; + DWORD edidsize = sizeof(EDIDdata); + + DWORD dwType, ActualValueNameLength = NAME_SIZE; + CHAR valueName[NAME_SIZE]; + + // Read the key value data + LSTATUS retValue = RegEnumValueA( + hDevRegKey, + i, + &valueName[0], + &ActualValueNameLength, + NULL, + &dwType, + EDIDdata, + &edidsize); + + if (FAILED(retValue)) + { + if (retValue == ERROR_NO_MORE_ITEMS) + { + break; + } + + LogError("{ERR-098} [Display] WARNING: RegEnumValueA failed to read a key. LastErr=%d", retValue); + OVR_ASSERT(false); + } + else if (0 == strcmp(valueName, "EDID")) // Value is EDID: + { + // Tested working for DK1 and DK2: + + char friendlyString[9]; + memcpy(friendlyString, EDIDdata + 77, 8); + truncateNonalphanum(friendlyString, 8); + friendlyString[8] = '\0'; + + char edidString[14]; + memcpy(edidString, EDIDdata + 95, 13); + truncateNonalphanum(edidString, 13); + edidString[13] = '\0'; + + serialNumberStr = edidString; + userFriendlyNameStr = friendlyString; + + found = true; + break; + } + } + + RegCloseKey(hDevRegKey); + + return found; +} + +static bool getCompatDisplayEDID(const WCHAR* displayName, String& serialNumberStr, String& userFriendlyNameStr) +{ + HDEVINFO devInfo = NULL; + + devInfo = SetupDiGetClassDevsEx( + &GUID_CLASS_MONITOR, //class GUID + NULL, //enumerator + NULL, //HWND + DIGCF_PRESENT, // Flags //DIGCF_ALLCLASSES| + NULL, // device info, create a new one. + NULL, // machine name, local machine + NULL);// reserved + + if (NULL == devInfo) + { + return false; + } + + DWORD lastError = 0; + + // For each display, + for (int i = 0;; i++) + { + SP_DEVINFO_DATA devInfoData = {}; + devInfoData.cbSize = sizeof(devInfoData); + + // Grab device info + if (SetupDiEnumDeviceInfo(devInfo, i, &devInfoData)) + { + // Access device info from registry + if (AccessDeviceRegistry(devInfo, &devInfoData, displayName, serialNumberStr, userFriendlyNameStr)) + { + return true; + } + } + else + { + lastError = GetLastError(); + + // If no more items found, + if (lastError != ERROR_NO_MORE_ITEMS) + { + LogError("{ERR-099} [Display] WARNING: SetupDiEnumDeviceInfo failed. LastErr=%d", lastError); + OVR_ASSERT(false); + } + + break; + } + } + + LogError("{ERR-100} [Display] WARNING: SetupDiEnumDeviceInfo did not return the rift display. LastErr=%d", lastError); + OVR_ASSERT(false); + + return false; } +#endif // OVR_COMPAT_EDID_VIA_WMI + // This is function that's used bool anyRiftsInExtendedMode() { @@ -797,27 +1006,28 @@ bool Display::InCompatibilityMode( bool displaySearch ) bool result = false; if( displaySearch ) { - OVR::Win32::DisplayDesc displayArray[8]; + OVR::Win32::DisplayDesc displayArray[8]; - int extendedRiftCount = discoverExtendedRifts(displayArray, 8, false); - if( extendedRiftCount ) - { - result = true; - } - else - { - result = GlobalDisplayContext.InCompatibilityMode; + int extendedRiftCount = discoverExtendedRifts(displayArray, 8, false); + if( extendedRiftCount ) + { + result = true; + } + else + { + result = GlobalDisplayContext.CompatibilityMode; } } else { - result = GlobalDisplayContext.InCompatibilityMode; + result = GlobalDisplayContext.CompatibilityMode; } return result; } #define OVR_FLAG_COMPATIBILITY_MODE 1 +#define OVR_FLAG_HIDE_DK1 2 bool Display::Initialize() { @@ -830,7 +1040,7 @@ bool Display::Initialize() if (hDevice != NULL && hDevice != INVALID_HANDLE_VALUE) { GlobalDisplayContext.hDevice = hDevice; - GlobalDisplayContext.InCompatibilityMode = FALSE; + GlobalDisplayContext.CompatibilityMode = false; DWORD bytesReturned = 0; LONG compatiblityResult = OVR_STATUS_SUCCESS; @@ -839,16 +1049,16 @@ bool Display::Initialize() &compatiblityResult, sizeof( LONG ), &bytesReturned, NULL ); if (result) { - if( compatiblityResult & OVR_FLAG_COMPATIBILITY_MODE ) - GlobalDisplayContext.InCompatibilityMode = TRUE; - } + GlobalDisplayContext.CompatibilityMode = (compatiblityResult & OVR_FLAG_COMPATIBILITY_MODE) != 0; + GlobalDisplayContext.HideDK1Mode = (compatiblityResult & OVR_FLAG_HIDE_DK1) != 0; + } else { // If calling our driver fails in any way, assume compatibility mode as well - GlobalDisplayContext.InCompatibilityMode = TRUE; + GlobalDisplayContext.CompatibilityMode = true; } - if (!GlobalDisplayContext.InCompatibilityMode) + if (!GlobalDisplayContext.CompatibilityMode) { Ptr<DisplaySearchHandle> searchHandle = *Display::GetDisplaySearchHandle(); @@ -861,19 +1071,89 @@ bool Display::Initialize() } else { - GlobalDisplayContext.InCompatibilityMode = TRUE; + GlobalDisplayContext.CompatibilityMode = true; } } } else { - GlobalDisplayContext.InCompatibilityMode = TRUE; + GlobalDisplayContext.CompatibilityMode = true; } return true; } +bool Display::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) +{ + if (GlobalDisplayContext.hDevice == NULL) + { + driverInstalled = false; + compatMode = true; + hideDK1Mode = false; + } + else + { + driverInstalled = true; + compatMode = GlobalDisplayContext.CompatibilityMode; + hideDK1Mode = GlobalDisplayContext.HideDK1Mode; + } + + return true; +} + +bool Display::SetDriverMode(bool compatMode, bool hideDK1Mode) +{ + // If device is not initialized, + if (GlobalDisplayContext.hDevice == NULL) + { + OVR_ASSERT(false); + return false; + } + + // If no change, + if ((compatMode == GlobalDisplayContext.CompatibilityMode) && + (hideDK1Mode == GlobalDisplayContext.HideDK1Mode)) + { + return true; + } + + LONG mode_flags = 0; + if (compatMode) + { + mode_flags |= OVR_FLAG_COMPATIBILITY_MODE; + } + if (hideDK1Mode) + { + mode_flags |= OVR_FLAG_HIDE_DK1; + } + + DWORD bytesReturned = 0; + LONG err = 1; + + if (!DeviceIoControl(GlobalDisplayContext.hDevice, + IOCTL_RIFTMGR_SETCOMPATIBILITYMODE, + &mode_flags, + sizeof(LONG), + &err, + sizeof(LONG), + &bytesReturned, + NULL) || + (err != 0 && err != -3)) + { + LogError("{ERR-001w} [Win32Display] Unable to set device mode to (compat=%d dk1hide=%d): err=%d", + (int)compatMode, (int)hideDK1Mode, (int)err); + return false; + } + + OVR_DEBUG_LOG(("[Win32Display] Set device mode to (compat=%d dk1hide=%d)", + (int)compatMode, (int)hideDK1Mode)); + + GlobalDisplayContext.HideDK1Mode = hideDK1Mode; + GlobalDisplayContext.CompatibilityMode = compatMode; + return true; +} + DisplaySearchHandle* Display::GetDisplaySearchHandle() { return new Win32::Win32DisplaySearchHandle(); @@ -950,10 +1230,8 @@ Ptr<Display> Display::GetDisplay(int index, DisplaySearchHandle* handle) } // FIXME: We have the EDID. Let's just use that instead. - uint32_t nativeWidth = 1080; - uint32_t nativeHeight = 1920; - uint32_t logicalWidth = 1920; - uint32_t logicalHeight = 1080; + uint32_t nativeWidth = 1080, nativeHeight = 1920; + uint32_t logicalWidth = 1920, logicalHeight = 1080; uint32_t rotation = 0; switch (dEdid.ModelNumber) diff --git a/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h b/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h index ab1582c..bdcd813 100644 --- a/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h +++ b/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h @@ -372,19 +372,31 @@ typedef struct _RIFT_STATUS_ARRAY // Enable or disable compatibility mode. Entering compatibility mode will fail if // the Rift is already actively scanning out a surface -// Input Buffer: BOOL - Nonzero if compatibility mode is desired, zero if it's not +// Input Buffer: LONG - Bit assignments: +// LSB (bit 0) is a flag for compatibility mode itself. +// 1 means compatibility mode. +// 0 means application direct mode. +// Bit 1 means "Hide DK1's". +// 1 means operate DK1's in synchronous with the compatibility mode exactly. +// 0 means operate in DK1 legacy mode. // Output Buffer: LONG - Result value (see OVR statuses) // 0 = success // -1 = general failure // -2 = failure, rift scanning out +// -3 = already active +// -4 = rift not present #define IOCTL_RIFTMGR_SETCOMPATIBILITYMODE CTL_CODE(FILE_DEVICE_VIDEO, \ FUNCTION_INDEX + 8, METHOD_NEITHER, FILE_ANY_ACCESS) // Call to obtain the current status of compatibility mode // Input Buffer: NOTHING -// Output Buffer: LONG - Result value -// 0 = Not in compatibility mode -// Non-zero = In compatibility mode +// Output Buffer: LONG - Bit assignments: +// LSB (bit 0) is a flag for compatibility mode itself. +// 1 means compatibility mode. +// 0 means application direct mode. +// Bit 1 means "Hide DK1's". +// 1 means operate DK1's in synchronous with the compatibility mode exactly. +// 0 means operate in DK1 legacy mode. #define IOCTL_RIFTMGR_GETCOMPATIBILITYMODE CTL_CODE(FILE_DEVICE_VIDEO, \ FUNCTION_INDEX + 9, METHOD_NEITHER, FILE_ANY_ACCESS) @@ -410,4 +422,4 @@ typedef struct _RIFT_STATUS_ARRAY #define IOCTL_RIFTMGR_GETEDID CTL_CODE(FILE_DEVICE_VIDEO, \ FUNCTION_INDEX + 11, METHOD_NEITHER, FILE_ANY_ACCESS) -#endif
\ No newline at end of file +#endif diff --git a/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp b/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp index 852e29e..d665546 100644 --- a/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp +++ b/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp @@ -75,6 +75,4 @@ void RenderFocusReader::OnSystemDestroy() } - - }} // namespace OVR::Win32 diff --git a/LibOVR/Src/Displays/OVR_Win32_FocusReader.h b/LibOVR/Src/Displays/OVR_Win32_FocusReader.h index f62b8de..1d58264 100644 --- a/LibOVR/Src/Displays/OVR_Win32_FocusReader.h +++ b/LibOVR/Src/Displays/OVR_Win32_FocusReader.h @@ -64,7 +64,7 @@ typedef SharedObjectReader< LocklessFocusState > SharedFocusReader; //----------------------------------------------------------------------------- // RenderFocusReader -class RenderFocusReader : public OVR::SystemSingletonBase<RenderFocusReader> +class RenderFocusReader : public OVR::SystemSingletonBase<RenderFocusReader>, public NewOverrideBase { OVR_DECLARE_SINGLETON(RenderFocusReader); diff --git a/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp b/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp index a58e40d..80b33a2 100644 --- a/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp +++ b/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp @@ -16,8 +16,7 @@ otherwise accompanies this software in either electronic or hard copy form. #include <windows.h> #include <DbgHelp.h> -#include <AtlBase.h> -#include <AtlConv.h> +#include <malloc.h> #include "OVR_Win32_Dxgi_Display.h" @@ -30,6 +29,12 @@ otherwise accompanies this software in either electronic or hard copy form. #pragma comment(lib, "DbgHelp.lib") +#define WIDE_TO_MB(wideString) \ + int wideString ## _slen = (int)wcslen(wideString); \ + char* wideString ## _cstr = (char*)alloca(wideString ## _slen * 2); \ + int count = WideCharToMultiByte(GetACP(), 0, wideString, -1, wideString ## _cstr, wideString ## _slen * 2, NULL, NULL); \ + wideString ## _cstr[count] = '\0'; + // Forward declarations // These functions are implemented in OVR_Win32_DisplayDevice.cpp. @@ -114,22 +119,63 @@ TryAgainWOW64: #define OLD_DATA_BACKUP_SIZE 16 -WinLoadLibraryA oldProcA = NULL; -WinLoadLibraryExA oldProcExA = NULL; -WinLoadLibraryW oldProcW = NULL; -WinLoadLibraryExW oldProcExW = NULL; -WinGetModuleHandleExA oldProcModExA = NULL; -WinGetModuleHandleExW oldProcModExW = NULL; -WinDirect3DCreate9 oldDirectX9Create = NULL; -BYTE oldDirectX9CreateData[OLD_DATA_BACKUP_SIZE]; -WinDirect3DCreate9Ex oldDirectX9ExCreate = NULL; -BYTE oldDirectX9ExCreateData[OLD_DATA_BACKUP_SIZE]; -WinCreateDXGIFactory oldCreateDXGIFactory = NULL; -BYTE oldCreateDXGIFactoryData[OLD_DATA_BACKUP_SIZE]; -WinCreateDXGIFactory1 oldCreateDXGIFactory1 = NULL; -BYTE oldCreateDXGIFactory1Data[OLD_DATA_BACKUP_SIZE]; -WinCreateDXGIFactory2 oldCreateDXGIFactory2 = NULL; -BYTE oldCreateDXGIFactory2Data[OLD_DATA_BACKUP_SIZE]; +static WinLoadLibraryA oldProcA = NULL; // Note: This is used to indicate that the shim is in place +static WinLoadLibraryExA oldProcExA = NULL; +static WinLoadLibraryW oldProcW = NULL; +static WinLoadLibraryExW oldProcExW = NULL; +static WinGetModuleHandleExA oldProcModExA = NULL; +static WinGetModuleHandleExW oldProcModExW = NULL; +static WinDirect3DCreate9 oldDirectX9Create = NULL; +static BYTE oldDirectX9CreateData[OLD_DATA_BACKUP_SIZE]; +static WinDirect3DCreate9Ex oldDirectX9ExCreate = NULL; +static BYTE oldDirectX9ExCreateData[OLD_DATA_BACKUP_SIZE]; +static WinCreateDXGIFactory oldCreateDXGIFactory = NULL; +static BYTE oldCreateDXGIFactoryData[OLD_DATA_BACKUP_SIZE]; +static WinCreateDXGIFactory1 oldCreateDXGIFactory1 = NULL; +static BYTE oldCreateDXGIFactory1Data[OLD_DATA_BACKUP_SIZE]; +static WinCreateDXGIFactory2 oldCreateDXGIFactory2 = NULL; +static BYTE oldCreateDXGIFactory2Data[OLD_DATA_BACKUP_SIZE]; + +#define NUM_LOADER_LIBS 4 + +static const char* loaderLibraryList[NUM_LOADER_LIBS] = { + "kernel32.dll", + "api-ms-win-core-libraryloader-l1-2-0.dll", + "api-ms-win-core-libraryloader-l1-1-0.dll", + "api-ms-win-core-libraryloader-l1-1-1.dll" +}; + +enum ShimedLibraries +{ + ShimLibDXGI = 0, + ShimLibD3D9 = 1, + ShimLibD3D11 = 2, + ShimLibDXGIDebug = 3, + ShimLibD3D10Core = 4, + ShimLibD3D10 = 5, + ShimLibGL = 6, + ShimCountMax = 7 +}; + +static const char* dllList[ShimCountMax] = { + "dxgi.dll", + "d3d9.dll", + "d3d11.dll", + "dxgidebug.dll", + "d3d10core.dll", + "d3d10.dll", + "opengl32.dll" +}; + +static HINSTANCE oldLoaderInstances[ShimCountMax] = { NULL }; +static PROC oldLoaderProcA[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; +static PROC oldLoaderProcW[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; +static PROC oldLoaderProcExA[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; +static PROC oldLoaderProcExW[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; +static PROC oldLoaderProcModExA[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; +static PROC oldLoaderProcModExW[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; + +static HMODULE rtFilterModule = NULL; static bool checkForOverride( LPCSTR libFileName, OVRTargetAPI& targetApi ) { @@ -249,15 +295,15 @@ static HMODULE __in LPCWSTR lpLibFileName ) { - USES_CONVERSION; + WIDE_TO_MB(lpLibFileName); // Convert lpLibFileName -> lpLibFileName_cstr OVRTargetAPI targetAPI = DirectX; - bool needShim = checkForOverride( W2A( lpLibFileName ), targetAPI ); + bool needShim = checkForOverride( lpLibFileName_cstr, targetAPI ); if( !needShim ) return (*oldProcW)( lpLibFileName ); - return createShim( W2A( lpLibFileName ), targetAPI ); + return createShim( lpLibFileName_cstr, targetAPI ); } static HMODULE @@ -287,16 +333,16 @@ static HMODULE __in DWORD dwFlags ) { - USES_CONVERSION; + WIDE_TO_MB(lpLibFileName); // Convert lpLibFileName -> lpLibFileName_cstr OVRTargetAPI targetAPI = DirectX; - bool needShim = checkForOverride( W2A( lpLibFileName ), targetAPI ); + bool needShim = checkForOverride( lpLibFileName_cstr, targetAPI ); if( !needShim ) return (*oldProcExW)( lpLibFileName, hFile, dwFlags ); // FIXME: Don't throw away the flags parameter - return createShim( W2A( lpLibFileName ), targetAPI ); + return createShim( lpLibFileName_cstr, targetAPI ); } static BOOL WINAPI OVRGetModuleHandleExA( @@ -324,17 +370,17 @@ static BOOL WINAPI OVRGetModuleHandleExW( __out HMODULE *phModule ) { - USES_CONVERSION; + WIDE_TO_MB(lpModuleName); // Convert lpModuleName -> lpModuleName_cstr - OVRTargetAPI targetAPI = DirectX; + OVRTargetAPI targetAPI = DirectX; - bool needShim = checkForOverride( W2A( lpModuleName ), targetAPI ); + bool needShim = checkForOverride( lpModuleName_cstr, targetAPI ); if( !needShim ) { return (*oldProcModExW)( dwFlags, lpModuleName, phModule ); } - *phModule = createShim( W2A( lpModuleName ), targetAPI ); + *phModule = createShim( lpModuleName_cstr, targetAPI ); return TRUE; } @@ -465,7 +511,6 @@ HRESULT APIENTRY OVRDirect3DCreate9Ex(UINT SDKVersion, void** aDevice) } else { - HMODULE rtFilterModule = (*oldProcA)(RTFilter); WinDirect3DCreate9Ex createFunction = (WinDirect3DCreate9Ex)GetProcAddress(rtFilterModule, "Direct3DCreate9Ex"); result = (*createFunction)(SDKVersion, aDevice); } @@ -501,7 +546,6 @@ HRESULT APIENTRY OVRCreateDXGIFactory( } else { - HMODULE rtFilterModule = (*oldProcA)(RTFilter); WinCreateDXGIFactory createFunction = (WinCreateDXGIFactory)GetProcAddress(rtFilterModule, "CreateDXGIFactory"); result = (*createFunction)(riid, ppFactory); } @@ -528,7 +572,6 @@ HRESULT APIENTRY OVRCreateDXGIFactory1( } else { - HMODULE rtFilterModule = (*oldProcA)(RTFilter); WinCreateDXGIFactory1 createFunction = (WinCreateDXGIFactory1)GetProcAddress(rtFilterModule, "CreateDXGIFactory1"); result = (*createFunction)(riid, ppFactory); } @@ -556,7 +599,6 @@ HRESULT APIENTRY OVRCreateDXGIFactory2( } else { - HMODULE rtFilterModule = (*oldProcA)(RTFilter); WinCreateDXGIFactory2 createFunction = (WinCreateDXGIFactory2)GetProcAddress(rtFilterModule, "CreateDXGIFactory2"); result = (*createFunction)(flags, riid, ppFactory); } @@ -659,43 +701,27 @@ static PROC SetProcAddressA( return pfnHookAPIAddr; } -enum ShimedLibraries -{ - ShimLibDXGI = 0, - ShimLibD3D9 = 1, - ShimLibD3D11 = 2, - ShimLibDXGIDebug = 3, - ShimLibD3D10Core = 4, - ShimLibD3D10 = 5, - ShimLibGL = 6, - ShimCountMax = 7 -}; -void checkUMDriverOverrides( void* context ) +void checkUMDriverOverrides(void* context) { lastContext = context; if( oldProcA == NULL ) { - char* dllList[ShimCountMax] = { "dxgi.dll", "d3d9.dll", "d3d11.dll", "dxgidebug.dll", "d3d10core.dll", "d3d10.dll", "opengl32.dll" }; - PreloadLibraryRTFn loadFunc = NULL; for( int i = 0; i < ShimCountMax; ++i ) { - HINSTANCE hInst = GetModuleHandleA( dllList[i] ); - if( hInst == NULL ) + HINSTANCE hInst = NULL; + try + { + hInst = LoadLibraryA(dllList[i]); + } + catch(...) { - try - { - hInst = LoadLibraryA(dllList[i]); - } - catch(...) - { - - } - } + oldLoaderInstances[i] = hInst; + if( hInst ) { ShimedLibraries libCount = (ShimedLibraries)i; @@ -714,52 +740,75 @@ void checkUMDriverOverrides( void* context ) break; } - char* loaderLibraryList[4] = {"kernel32.dll", "api-ms-win-core-libraryloader-l1-2-0.dll", "api-ms-win-core-libraryloader-l1-1-0.dll", "api-ms-win-core-libraryloader-l1-1-1.dll"}; - - for( int j = 0; j < 4; ++j ) - { - char* loaderLibrary = loaderLibraryList[j]; + for (int j = 0; j < NUM_LOADER_LIBS; ++j) + { + const char* loaderLibrary = loaderLibraryList[j]; PROC temp = NULL; - temp = SetProcAddressA( hInst, loaderLibrary, "LoadLibraryA", (PROC)OVRLoadLibraryA ); - if( !oldProcA ) - oldProcA = (WinLoadLibraryA)temp; - - temp = SetProcAddressA( hInst, loaderLibrary, "LoadLibraryW", (PROC)OVRLoadLibraryW ); - if( !oldProcW ) - oldProcW = (WinLoadLibraryW)temp; - - temp = SetProcAddressA( hInst, loaderLibrary, "LoadLibraryExA", (PROC)OVRLoadLibraryExA ); - if( !oldProcExA ) - oldProcExA = (WinLoadLibraryExA)temp; - - temp = SetProcAddressA( hInst, loaderLibrary, "LoadLibraryExW", (PROC)OVRLoadLibraryExW ); - if( !oldProcExW ) - oldProcExW = (WinLoadLibraryExW)temp; - - temp = SetProcAddressA( hInst, loaderLibrary, "GetModuleHandleExA", (PROC)OVRGetModuleHandleExA ); - if( !oldProcModExA ) - oldProcModExA = (WinGetModuleHandleExA)temp; - - temp = SetProcAddressA( hInst, loaderLibrary, "GetModuleHandleExW", (PROC)OVRGetModuleHandleExW ); - if( !oldProcModExW ) - oldProcModExW = (WinGetModuleHandleExW)temp; - } - - if( loadFunc == NULL ) - loadFunc = (PreloadLibraryRTFn)GetProcAddress( hInst, "PreloadLibraryRT" ); + temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryA", (PROC)OVRLoadLibraryA); + if (!oldProcA) + { + oldProcA = (WinLoadLibraryA)temp; + } + oldLoaderProcA[i][j] = temp; + + temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryW", (PROC)OVRLoadLibraryW); + if (!oldProcW) + { + oldProcW = (WinLoadLibraryW)temp; + } + oldLoaderProcW[i][j] = temp; + + temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExA", (PROC)OVRLoadLibraryExA); + if (!oldProcExA) + { + oldProcExA = (WinLoadLibraryExA)temp; + } + oldLoaderProcExA[i][j] = temp; + + temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExW", (PROC)OVRLoadLibraryExW); + if (!oldProcExW) + { + oldProcExW = (WinLoadLibraryExW)temp; + } + oldLoaderProcExW[i][j] = temp; + + temp = SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExA", (PROC)OVRGetModuleHandleExA); + if (!oldProcModExA) + { + oldProcModExA = (WinGetModuleHandleExA)temp; + } + oldLoaderProcModExA[i][j] = temp; + + temp = SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExW", (PROC)OVRGetModuleHandleExW); + if (!oldProcModExW) + { + oldProcModExW = (WinGetModuleHandleExW)temp; + } + oldLoaderProcModExW[i][j] = temp; + } + + if (loadFunc == NULL) + { + loadFunc = (PreloadLibraryRTFn)GetProcAddress(hInst, "PreloadLibraryRT"); + } } } - HMODULE rtFilterModule = (*oldProcA)( RTFilter ); + rtFilterModule = (*oldProcA)( RTFilter ); - if( loadFunc == NULL ) - loadFunc = (PreloadLibraryRTFn)GetProcAddress( rtFilterModule, "PreloadLibraryRT" ); - IsCreatingBackBuffer backBufferFunc = (IsCreatingBackBuffer)GetProcAddress( rtFilterModule, "OVRIsCreatingBackBuffer" ); - ShouldVSync shouldVSyncFunc = (ShouldVSync)GetProcAddress( rtFilterModule, "OVRShouldVSync" ); + IsCreatingBackBuffer backBufferFunc = NULL; + ShouldVSync shouldVSyncFunc = NULL; - if( loadFunc ) - { + if (rtFilterModule != NULL) + { + loadFunc = (PreloadLibraryRTFn)GetProcAddress(rtFilterModule, "PreloadLibraryRT"); + backBufferFunc = (IsCreatingBackBuffer)GetProcAddress(rtFilterModule, "OVRIsCreatingBackBuffer"); + shouldVSyncFunc = (ShouldVSync)GetProcAddress(rtFilterModule, "OVRShouldVSync"); + } + + if (loadFunc != NULL) + { appDriver.version = 1; appDriver.context = lastContext; @@ -786,3 +835,99 @@ void checkUMDriverOverrides( void* context ) } } } + +void clearUMDriverOverrides() +{ + if (oldProcA != NULL) + { + // Unpatch all the things. + + if (oldCreateDXGIFactory) + { + restoreFunction((PROC)oldCreateDXGIFactory, oldCreateDXGIFactoryData); + } + if (oldCreateDXGIFactory1) + { + restoreFunction((PROC)oldCreateDXGIFactory1, oldCreateDXGIFactory1Data); + } + if (oldCreateDXGIFactory2) + { + restoreFunction((PROC)oldCreateDXGIFactory2, oldCreateDXGIFactory2Data); + } + if (oldDirectX9Create) + { + restoreFunction((PROC)oldDirectX9Create, oldDirectX9CreateData); + } + if (oldDirectX9ExCreate) + { + restoreFunction((PROC)oldDirectX9ExCreate, oldDirectX9ExCreateData); + } + if (oldCreateDXGIFactory2) + { + restoreFunction((PROC)oldCreateDXGIFactory2, oldCreateDXGIFactory2Data); + } + + for (int i = 0; i < ShimCountMax; ++i) + { + HINSTANCE hInst = oldLoaderInstances[i]; + + if (hInst != NULL) + { + for (int j = 0; j < NUM_LOADER_LIBS; ++j) + { + const char* loaderLibrary = loaderLibraryList[j]; + + if (oldLoaderProcA[j]) + { + SetProcAddressA(hInst, loaderLibrary, "LoadLibraryA", oldLoaderProcA[i][j]); + } + if (oldLoaderProcW[j]) + { + SetProcAddressA(hInst, loaderLibrary, "LoadLibraryW", oldLoaderProcW[i][j]); + } + if (oldLoaderProcExA[j]) + { + SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExA", oldLoaderProcExA[i][j]); + } + if (oldLoaderProcExW[j]) + { + SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExW", oldLoaderProcExW[i][j]); + } + if (oldLoaderProcModExA[j]) + { + SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExA", oldLoaderProcModExA[i][j]); + } + if (oldLoaderProcModExW[j]) + { + SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExW", oldLoaderProcModExW[i][j]); + } + } + + FreeLibrary(hInst); + } + } + + if (rtFilterModule != NULL) + { + LPFNCANUNLOADNOW pfnCanUnloadNow = (LPFNCANUNLOADNOW)GetProcAddress(rtFilterModule, "DllCanUnloadNow"); + if (pfnCanUnloadNow && pfnCanUnloadNow() == S_OK) + { + FreeLibrary(rtFilterModule); + rtFilterModule = NULL; + } + } + + oldProcA = NULL; + oldProcExA = NULL; + oldProcW = NULL; + oldProcExW = NULL; + oldProcModExA = NULL; + oldProcModExW = NULL; + oldDirectX9Create = NULL; + oldDirectX9ExCreate = NULL; + oldCreateDXGIFactory = NULL; + oldCreateDXGIFactory1 = NULL; + oldCreateDXGIFactory2 = NULL; + lastContext = NULL; + } +} diff --git a/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp b/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp index 9e5442c..907dc13 100644 --- a/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp +++ b/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp @@ -31,7 +31,8 @@ limitations under the License. #include "OVR_Win32_FocusReader.h" // Exported -extern void checkUMDriverOverrides( void* context ); +extern void checkUMDriverOverrides(void* context); +extern void clearUMDriverOverrides(); #include <stdio.h> #include <tchar.h> @@ -203,6 +204,8 @@ bool DisplayShim::Initialize( bool inCompatibility ) bool DisplayShim::Shutdown() { + clearUMDriverOverrides(); + return true; } diff --git a/LibOVR/Src/Kernel/OVR_Atomic.cpp b/LibOVR/Src/Kernel/OVR_Atomic.cpp index 9ea6e76..079792e 100644 --- a/LibOVR/Src/Kernel/OVR_Atomic.cpp +++ b/LibOVR/Src/Kernel/OVR_Atomic.cpp @@ -107,7 +107,7 @@ Lock* SharedLock::GetLockAddRef() do { oldUseCount = UseCount; - if (oldUseCount == LockInitMarker) + if (oldUseCount == (int)LockInitMarker) continue; if (oldUseCount == 0) @@ -137,7 +137,7 @@ void SharedLock::ReleaseLock(Lock* plock) do { oldUseCount = UseCount; - OVR_ASSERT(oldUseCount != LockInitMarker); + OVR_ASSERT(oldUseCount != (int)LockInitMarker); if (oldUseCount == 1) { diff --git a/LibOVR/Src/Kernel/OVR_Atomic.h b/LibOVR/Src/Kernel/OVR_Atomic.h index 6ef862d..47e76e0 100644 --- a/LibOVR/Src/Kernel/OVR_Atomic.h +++ b/LibOVR/Src/Kernel/OVR_Atomic.h @@ -42,6 +42,10 @@ limitations under the License. #include <pthread.h> #endif +#ifdef OVR_CC_MSVC +#include <intrin.h> +#pragma intrinsic(_ReadBarrier, _WriteBarrier, _ReadWriteBarrier) +#endif namespace OVR { @@ -118,7 +122,6 @@ struct AtomicOpsRawBase struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("dmb\n"); } }; struct ReleaseSync { inline ReleaseSync() { asm volatile("dmb\n"); } }; - #elif defined(OVR_CC_GNU) && (__GNUC__ >= 4) // __sync functions are already full sync struct FullSync { inline FullSync() { } }; @@ -138,7 +141,7 @@ struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase // *** Thread - Safe Atomic Versions. -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_WIN32) // Use special defined for VC6, where volatile is not used and // InterlockedCompareExchange is declared incorrectly. @@ -403,7 +406,7 @@ struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase typedef uint64_t T; // *** Thread - Safe OS specific versions. -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_WIN32) // This is only for 64-bit systems. typedef LONG64 T; @@ -537,7 +540,22 @@ struct AtomicOpsRaw_DefImpl : public O #else inline static void Store_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); *p = val; } #endif - inline static O_T Load_Acquire(const volatile O_T* p) { O_AcquireSync sync; OVR_UNUSED(sync); return *p; } + inline static O_T Load_Acquire(const volatile O_T* p) + { + O_AcquireSync sync; + OVR_UNUSED(sync); + +#if defined(OVR_CC_MSVC) + _ReadBarrier(); // Compiler fence and load barrier +#elif defined(OVR_CC_INTEL) + __memory_barrier(); // Compiler fence +#else + // GCC-compatible: + asm volatile ("" : : : "memory"); // Compiler fence +#endif + + return *p; + } }; @@ -819,7 +837,7 @@ public: inline void Unlock() { } // Windows. -#elif defined(OVR_OS_WIN32) +#elif defined(OVR_OS_WIN32) CRITICAL_SECTION cs; public: diff --git a/LibOVR/Src/Kernel/OVR_FileFILE.cpp b/LibOVR/Src/Kernel/OVR_FileFILE.cpp index 86096a9..b2a6f68 100644 --- a/LibOVR/Src/Kernel/OVR_FileFILE.cpp +++ b/LibOVR/Src/Kernel/OVR_FileFILE.cpp @@ -219,7 +219,7 @@ void FILEFile::init() else if (OpenFlags & Open_Write) omode = "r+b"; -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) SysErrorModeDisabler disabler(FileName.ToCStr()); #endif @@ -574,7 +574,7 @@ Ptr<File> FileFILEOpen(const String& path, int flags, int mode) // Helper function: obtain file information time. bool SysFile::GetFileStat(FileStat* pfileStat, const String& path) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) // 64-bit implementation on Windows. struct __stat64 fileStat; // Stat returns 0 for success. diff --git a/LibOVR/Src/Kernel/OVR_Lockless.cpp b/LibOVR/Src/Kernel/OVR_Lockless.cpp index 67c9260..c227cec 100644 --- a/LibOVR/Src/Kernel/OVR_Lockless.cpp +++ b/LibOVR/Src/Kernel/OVR_Lockless.cpp @@ -37,7 +37,7 @@ namespace OVR { namespace LocklessTest { const int TestIterations = 10000000; -// Use volatile dummys to force compiler to do spinning. +// Use volatile dummies to force compiler to do spinning. volatile int Dummy1; int Unused1[32]; volatile int Dummy2; @@ -89,7 +89,7 @@ struct TestData volatile bool FirstItemWritten = false; -LocklessUpdater<TestData> TestDataUpdater; +LocklessUpdater<TestData, TestData> TestDataUpdater; // Use this lock to verify that testing algorithm is otherwise correct... Lock TestLock; @@ -213,13 +213,10 @@ void StartLocklessTest() producerThread->Start(); consumerThread->Start(); - /* while (!producerThread->IsFinished() && consumerThread->IsFinished()) { Thread::MSleep(500); - } */ - - // TBD: Cleanup + } } diff --git a/LibOVR/Src/Kernel/OVR_Lockless.h b/LibOVR/Src/Kernel/OVR_Lockless.h index 72b6b31..400b198 100644 --- a/LibOVR/Src/Kernel/OVR_Lockless.h +++ b/LibOVR/Src/Kernel/OVR_Lockless.h @@ -59,7 +59,7 @@ public: OVR_COMPILER_ASSERT(sizeof(T) <= sizeof(SlotType)); } - T GetState() const + T GetState() const { // Copy the state out, then retry with the alternate slot // if we determine that our copy may have been partially @@ -71,9 +71,9 @@ public: { // 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.ExchangeAdd_Sync(0); + end = UpdateEnd.Load_Acquire(); state = Slots[ end & 1 ]; - begin = UpdateBegin.ExchangeAdd_Sync(0); + begin = UpdateBegin.Load_Acquire(); if ( begin == end ) { break; } @@ -81,7 +81,7 @@ public: // 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.ExchangeAdd_NoSync(0); + final = UpdateBegin.Load_Acquire(); if ( final == begin ) { break; } @@ -100,9 +100,9 @@ public: UpdateEnd.ExchangeAdd_Sync(1); } - mutable AtomicInt<int> UpdateBegin; - mutable AtomicInt<int> UpdateEnd; - SlotType Slots[2]; + AtomicInt<int> UpdateBegin; + AtomicInt<int> UpdateEnd; + SlotType Slots[2]; }; diff --git a/LibOVR/Src/Kernel/OVR_Log.cpp b/LibOVR/Src/Kernel/OVR_Log.cpp index c81845e..7266497 100644 --- a/LibOVR/Src/Kernel/OVR_Log.cpp +++ b/LibOVR/Src/Kernel/OVR_Log.cpp @@ -29,7 +29,7 @@ limitations under the License. #include <stdarg.h> #include <stdio.h> -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) #define WIN32_LEAN_AND_MEAN #include <windows.h> #elif defined(OVR_OS_ANDROID) diff --git a/LibOVR/Src/Kernel/OVR_SharedMemory.cpp b/LibOVR/Src/Kernel/OVR_SharedMemory.cpp index b314e58..edb7931 100644 --- a/LibOVR/Src/Kernel/OVR_SharedMemory.cpp +++ b/LibOVR/Src/Kernel/OVR_SharedMemory.cpp @@ -30,8 +30,6 @@ limitations under the License. #include "OVR_String.h" #include "OVR_Array.h" -#undef new - #if defined(OVR_OS_WIN32) && !defined(OVR_FAKE_SHAREDMEMORY) #include <Sddl.h> // ConvertStringSecurityDescriptorToSecurityDescriptor #endif // OVR_OS_WIN32 diff --git a/LibOVR/Src/Kernel/OVR_SharedMemory.h b/LibOVR/Src/Kernel/OVR_SharedMemory.h index d18b583..f0ecbe6 100644 --- a/LibOVR/Src/Kernel/OVR_SharedMemory.h +++ b/LibOVR/Src/Kernel/OVR_SharedMemory.h @@ -155,14 +155,18 @@ protected: { // Configure open parameters based on read-only mode SharedMemory::OpenParameters params; - params.globalName = name; - // FIXME: This is a hack. We currently need to open this for read-write even when just reading from - // it because the LocklessUpdater class technically writes to it (increments by 0). - //params.accessMode = readOnly ? SharedMemory::AccessMode_ReadOnly : SharedMemory::AccessMode_ReadWrite; - //params.remoteMode = SharedMemory::RemoteMode_ReadOnly; - params.accessMode = SharedMemory::AccessMode_ReadWrite; - params.remoteMode = SharedMemory::RemoteMode_ReadWrite; - params.minSizeBytes = RegionSize; + + // 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 diff --git a/LibOVR/Src/Kernel/OVR_Std.cpp b/LibOVR/Src/Kernel/OVR_Std.cpp index 5f47015..f9d1645 100644 --- a/LibOVR/Src/Kernel/OVR_Std.cpp +++ b/LibOVR/Src/Kernel/OVR_Std.cpp @@ -37,7 +37,7 @@ namespace OVR { // Case insensitive compare implemented in platform-specific way. int OVR_CDECL OVR_stricmp(const char* a, const char* b) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) return ::_stricmp(a, b); #else @@ -51,7 +51,7 @@ int OVR_CDECL OVR_stricmp(const char* a, const char* b) int OVR_CDECL OVR_strnicmp(const char* a, const char* b, size_t count) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) return ::_strnicmp(a, b, count); #else @@ -122,7 +122,7 @@ wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src size_t OVR_CDECL OVR_wcslen(const wchar_t* str) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) return wcslen(str); #else size_t i = 0; @@ -134,7 +134,7 @@ size_t OVR_CDECL OVR_wcslen(const wchar_t* str) int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b) { -#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX) +#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX) return wcscmp(a, b); #else // not supported, use custom implementation @@ -161,7 +161,7 @@ int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b) int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) return ::_wcsicmp(a, b); #else diff --git a/LibOVR/Src/Kernel/OVR_Std.h b/LibOVR/Src/Kernel/OVR_Std.h index d421ca7..cc2de04 100644 --- a/LibOVR/Src/Kernel/OVR_Std.h +++ b/LibOVR/Src/Kernel/OVR_Std.h @@ -46,7 +46,7 @@ limitations under the License. namespace OVR { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) inline char* OVR_CDECL OVR_itoa(int val, char *dest, size_t destsize, int radix) { #if defined(OVR_MSVC_SAFESTRING) @@ -352,7 +352,7 @@ int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b); inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b) { -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) return ::_wcsicoll(a, b); #else @@ -366,7 +366,7 @@ inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b) inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b) { -#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX) +#if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX) return wcscoll(a, b); #else // not supported, use regular wcscmp diff --git a/LibOVR/Src/Kernel/OVR_String.h b/LibOVR/Src/Kernel/OVR_String.h index 25c4b68..850118a 100644 --- a/LibOVR/Src/Kernel/OVR_String.h +++ b/LibOVR/Src/Kernel/OVR_String.h @@ -192,6 +192,7 @@ public: // Returns number of characters size_t GetLength() const; + int GetLengthI() const { return (int)GetLength(); } // Returns character at the specified index uint32_t GetCharAt(size_t index) const; diff --git a/LibOVR/Src/Kernel/OVR_System.cpp b/LibOVR/Src/Kernel/OVR_System.cpp index 8fb93b5..1b8d801 100644 --- a/LibOVR/Src/Kernel/OVR_System.cpp +++ b/LibOVR/Src/Kernel/OVR_System.cpp @@ -51,25 +51,25 @@ void SystemSingletonInternal::PushDestroyCallbacks() } void System::DirectDisplayInitialize() -{ +{ #ifdef OVR_OS_WIN32 // Set up display code for Windows Win32::DisplayShim::GetInstance(); - // This code will look for the first display. If it's a display - // that's extending the destkop, the code will assume we're in - // compatibility mode. Compatibility mode prevents shim loading - // and renders only to extended Rifts. - // If we find a display and it's application exclusive, - // we load the shim so we can render to it. - // If no display is available, we revert to whatever the - // driver tells us we're in + // This code will look for the first display. If it's a display + // that's extending the destkop, the code will assume we're in + // compatibility mode. Compatibility mode prevents shim loading + // and renders only to extended Rifts. + // If we find a display and it's application exclusive, + // we load the shim so we can render to it. + // If no display is available, we revert to whatever the + // driver tells us we're in bool anyExtendedRifts = anyRiftsInExtendedMode() || Display::InCompatibilityMode( false ); Win32::DisplayShim::GetInstance().Initialize(anyExtendedRifts); #endif - } +} // Initializes System core, installing allocator. void System::Init(Log* log, Allocator *palloc) diff --git a/LibOVR/Src/Kernel/OVR_System.h b/LibOVR/Src/Kernel/OVR_System.h index 3bc2254..66ecfe9 100644 --- a/LibOVR/Src/Kernel/OVR_System.h +++ b/LibOVR/Src/Kernel/OVR_System.h @@ -111,7 +111,7 @@ template<class T> OVR::AtomicPtr<T> OVR::SystemSingletonBase<T>::SingletonInstan friend class OVR::SystemSingletonBase<T>; \ private: \ T(); \ - ~T(); \ + virtual ~T(); \ virtual void OnSystemDestroy(); // Place this in the singleton class source file diff --git a/LibOVR/Src/Kernel/OVR_Threads.h b/LibOVR/Src/Kernel/OVR_Threads.h index 0ecc152..301b84f 100644 --- a/LibOVR/Src/Kernel/OVR_Threads.h +++ b/LibOVR/Src/Kernel/OVR_Threads.h @@ -325,13 +325,13 @@ public: // and set to the return value if Run function after the thread is finished. inline int GetExitCode() const { return ExitCode; } // Returns an OS handle -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) void* GetOSHandle() const { return ThreadHandle; } #else pthread_t GetOSHandle() const { return ThreadHandle; } #endif -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) ThreadId GetThreadId() const { return IdValue; } #else ThreadId GetThreadId() const { return (ThreadId)GetOSHandle(); } @@ -369,7 +369,7 @@ protected: int Processor; ThreadPriority Priority; -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) void* ThreadHandle; volatile ThreadId IdValue; diff --git a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp index 25c4d2b..c1a368a 100644 --- a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp +++ b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp @@ -886,9 +886,8 @@ bool Thread::Start(ThreadState initialState) ExitCode = 0; SuspendCount = 0; ThreadFlags = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED; - ThreadHandle = (HANDLE) _beginthreadex(0, (unsigned)StackSize, - Thread_Win32StartFn, this, 0, (unsigned*)&IdValue); + Thread_Win32StartFn, this, 0, (unsigned*)&IdValue); // Failed? Fail the function if (ThreadHandle == 0) diff --git a/LibOVR/Src/Kernel/OVR_Timer.cpp b/LibOVR/Src/Kernel/OVR_Timer.cpp index 5269106..50f4c1f 100644 --- a/LibOVR/Src/Kernel/OVR_Timer.cpp +++ b/LibOVR/Src/Kernel/OVR_Timer.cpp @@ -27,7 +27,7 @@ limitations under the License. #include "OVR_Timer.h" #include "OVR_Log.h" -#if defined (OVR_OS_WIN32) +#if defined (OVR_OS_WIN32) #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <MMSystem.h> @@ -99,7 +99,7 @@ uint64_t Timer::GetTicksNanos() //------------------------------------------------------------------------ // *** Win32 Specific Timer -#elif defined (OVR_OS_WIN32) +#elif defined (OVR_OS_WIN32) // This helper class implements high-resolution wrapper that combines timeGetTime() output @@ -154,7 +154,6 @@ PerformanceTimer Win32_PerfTimer; void PerformanceTimer::Initialize() { - MMRESULT mmr = timeBeginPeriod(1); OVR_ASSERT(TIMERR_NOERROR == mmr); OVR_UNUSED(mmr); @@ -164,13 +163,16 @@ void PerformanceTimer::Initialize() getFrequency(); // Set Vista flag. On Vista, we can just use QPC() without all the extra work - UsingVista = false; - OSVERSIONINFOA vi; - vi.dwOSVersionInfoSize = sizeof(vi); - if (GetVersionExA(&vi)) - { - UsingVista = vi.dwMajorVersion >= 6; - } + OSVERSIONINFOEX ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOEX)); + ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + ver.dwMajorVersion = 6; // Vista+ + + DWORDLONG condMask = 0; + VER_SET_CONDITION(condMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + + // VerifyVersionInfo returns true if the OS meets the conditions set above + UsingVista = VerifyVersionInfo(&ver, VER_MAJORVERSION, condMask) != 0; OVR_DEBUG_LOG(("Performance timer Vista flag = %d", (int)UsingVista)); } @@ -178,7 +180,6 @@ void PerformanceTimer::Initialize() void PerformanceTimer::Shutdown() { DeleteCriticalSection(&TimeCS); - MMRESULT mmr = timeEndPeriod(1); OVR_ASSERT(TIMERR_NOERROR == mmr); OVR_UNUSED(mmr); @@ -211,6 +212,7 @@ uint64_t PerformanceTimer::GetTimeNanos() // Get raw value and perf counter "At the same time". QueryPerformanceCounter(&li); + DWORD mmTimeMs = timeGetTime(); if (OldMMTimeMs > mmTimeMs) MMTimeWrapCounter++; diff --git a/LibOVR/Src/Kernel/OVR_Types.h b/LibOVR/Src/Kernel/OVR_Types.h index 9126f78..ce8053d 100644 --- a/LibOVR/Src/Kernel/OVR_Types.h +++ b/LibOVR/Src/Kernel/OVR_Types.h @@ -30,6 +30,7 @@ limitations under the License. #include "OVR_Compiler.h" + // Unsupported compiler configurations #if _MSC_VER == 0x1600 # if _MSC_FULL_VER < 160040219 @@ -163,16 +164,6 @@ limitations under the License. # define _CRTDBG_MAP_ALLOC # include <stdlib.h> # include <crtdbg.h> - -#if 0 -// Uncomment this to help debug memory leaks under Visual Studio in OVR apps only. -// This shouldn't be defined in customer releases. -# ifndef OVR_DEFINE_NEW -# define OVR_DEFINE_NEW new(__FILE__, __LINE__) -# define new OVR_DEFINE_NEW -# endif -#endif - #endif @@ -205,7 +196,7 @@ typedef size_t UPInt; typedef ptrdiff_t SPInt; -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) typedef char SByte; // 8 bit Integer (Byte) typedef unsigned char UByte; @@ -241,6 +232,15 @@ 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 int64 +#ifdef OVR_OS_WIN32 +//process ID representation +typedef unsigned long pid_t; +#endif struct OVR_GUID { @@ -306,7 +306,7 @@ struct OVR_GUID #define OVR_BIG_ENDIAN 2 -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) // ***** Win32 @@ -508,7 +508,7 @@ struct OVR_GUID #else // Microsoft Win32 specific debugging support -#if defined(OVR_OS_WIN32) +#if defined(OVR_OS_WIN32) # ifdef OVR_CPU_X86 # if defined(__cplusplus_cli) # define OVR_DEBUG_BREAK do { __debugbreak(); } while(0) @@ -578,6 +578,29 @@ struct OVR_GUID #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_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 + + // ------------------------------------------------------------------------ // ***** OVR_ARRAY_COUNT // @@ -720,5 +743,30 @@ struct OVR_GUID // +//----------------------------------------------------------------------------------- +// ***** 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 + + #endif // OVR_Types_h diff --git a/LibOVR/Src/Net/OVR_NetworkPlugin.h b/LibOVR/Src/Net/OVR_NetworkPlugin.h index c56eda3..b5675b6 100644 --- a/LibOVR/Src/Net/OVR_NetworkPlugin.h +++ b/LibOVR/Src/Net/OVR_NetworkPlugin.h @@ -32,6 +32,7 @@ limitations under the License. namespace OVR { namespace Net { namespace Plugins { + //----------------------------------------------------------------------------- // NetworkPlugin diff --git a/LibOVR/Src/Net/OVR_RPC1.cpp b/LibOVR/Src/Net/OVR_RPC1.cpp index 0568e2f..477884c 100644 --- a/LibOVR/Src/Net/OVR_RPC1.cpp +++ b/LibOVR/Src/Net/OVR_RPC1.cpp @@ -58,7 +58,7 @@ RPC1::~RPC1() delete blockingReturnValue; } -void RPC1::RegisterSlot(OVR::String sharedIdentifier, OVR::Observer<RPCSlot> *rpcSlotObserver ) +void RPC1::RegisterSlot(OVR::String sharedIdentifier, OVR::Observer<RPCSlot>* rpcSlotObserver ) { slotHash.AddObserverToSubject(sharedIdentifier, rpcSlotObserver); } @@ -77,7 +77,7 @@ void RPC1::UnregisterBlockingFunction(OVR::String uniqueID) registeredBlockingFunctions.Remove(uniqueID); } -bool RPC1::CallBlocking( OVR::String uniqueID, OVR::Net::BitStream * bitStream, Ptr<Connection> pConnection, OVR::Net::BitStream *returnData ) +bool RPC1::CallBlocking( OVR::String uniqueID, OVR::Net::BitStream* bitStream, Ptr<Connection> pConnection, OVR::Net::BitStream* returnData ) { // If invalid parameters, if (!pConnection) @@ -133,7 +133,7 @@ bool RPC1::CallBlocking( OVR::String uniqueID, OVR::Net::BitStream * bitStream, return true; } -bool RPC1::Signal(OVR::String sharedIdentifier, OVR::Net::BitStream * bitStream, Ptr<Connection> pConnection) +bool RPC1::Signal(OVR::String sharedIdentifier, OVR::Net::BitStream* bitStream, Ptr<Connection> pConnection) { OVR::Net::BitStream out; out.Write((MessageID) OVRID_RPC1); @@ -150,7 +150,7 @@ bool RPC1::Signal(OVR::String sharedIdentifier, OVR::Net::BitStream * bitStream, int32_t bytesSent = pSession->Send(&sp); return bytesSent == sp.Bytes; } -void RPC1::BroadcastSignal(OVR::String sharedIdentifier, OVR::Net::BitStream * bitStream) +void RPC1::BroadcastSignal(OVR::String sharedIdentifier, OVR::Net::BitStream* bitStream) { OVR::Net::BitStream out; out.Write((MessageID) OVRID_RPC1); diff --git a/LibOVR/Src/Net/OVR_RPC1.h b/LibOVR/Src/Net/OVR_RPC1.h index 2e5b1db..d24f26c 100644 --- a/LibOVR/Src/Net/OVR_RPC1.h +++ b/LibOVR/Src/Net/OVR_RPC1.h @@ -44,7 +44,7 @@ typedef Delegate2<void, BitStream*, ReceivePayload*> RPCSlot; // typedef void ( *Slot ) ( OVR::Net::BitStream *userData, OVR::Net::ReceivePayload *pPayload ); /// NetworkPlugin that maps strings to function pointers. Can invoke the functions using blocking calls with return values, or signal/slots. Networked parameters serialized with BitStream -class RPC1 : public NetworkPlugin +class RPC1 : public NetworkPlugin, public NewOverrideBase { public: RPC1(); diff --git a/LibOVR/Src/Net/OVR_Session.cpp b/LibOVR/Src/Net/OVR_Session.cpp index 29c96e6..db370b4 100644 --- a/LibOVR/Src/Net/OVR_Session.cpp +++ b/LibOVR/Src/Net/OVR_Session.cpp @@ -55,10 +55,17 @@ bool RPC_C2S_Hello::Validate() HelloString.CompareNoCase(OfficialHelloString) == 0; } -void RPC_S2C_Authorization::Generate(Net::BitStream* bs) +void RPC_S2C_Authorization::Generate(Net::BitStream* bs, String errorString) { RPC_S2C_Authorization auth; - auth.AuthString = OfficialAuthorizedString; + if (errorString.IsEmpty()) + { + auth.AuthString = OfficialAuthorizedString; + } + else + { + auth.AuthString = errorString; + } auth.MajorVersion = RPCVersion_Major; auth.MinorVersion = RPCVersion_Minor; auth.PatchVersion = RPCVersion_Patch; @@ -169,17 +176,25 @@ SessionResult Session::Connect(ConnectParameters *cp) AllConnections.PushBack(c); } - + if (cp2->Blocking) { c->WaitOnConnecting(); + } - if (c->State == State_Connected) - return SessionResult_OK; - else - return SessionResult_ConnectFailure; + if (c->State == State_Connected) + { + return SessionResult_OK; } - } + else if (c->State == Client_Connecting) + { + return SessionResult_ConnectInProgress; + } + else + { + return SessionResult_ConnectFailure; + } + } else if (cp->Transport == TransportType_Loopback) { if (HasLoopbackListener) @@ -284,8 +299,10 @@ int Session::Send(SendParameters *payload) rp.pData = (uint8_t*)payload->pData; // FIXME ListenerReceiveResult lrr = LRR_CONTINUE; sl->OnReceive(&rp, &lrr); - if (lrr==LRR_RETURN) - return payload->Bytes; + if (lrr == LRR_RETURN) + { + return payload->Bytes; + } else if (lrr == LRR_BREAK) { break; @@ -522,11 +539,10 @@ void Session::TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead) if (!auth.Deserialize(&bsIn) || !auth.Validate()) { + LogError("{ERR-001} [Session] REJECTED: OVRService did not authorize us: %s", auth.AuthString.ToCStr()); + conn->SetState(State_Zombie); invokeSessionEvent(&SessionListener::OnIncompatibleProtocol, conn); - - LogError("[Session] REJECTED: Server did not respond with a valid authorization message"); - AllConnections.RemoveAtUnordered(connIndex); } else { @@ -550,13 +566,16 @@ void Session::TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead) if (!hello.Deserialize(&bsIn) || !hello.Validate()) { - conn->SetState(State_Zombie); - invokeSessionEvent(&SessionListener::OnIncompatibleProtocol, conn); - - LogError("[Session] REJECTED: Rift application is using an incompatible version %d.%d.%d (my version=%d.%d.%d)", + LogError("{ERR-002} [Session] REJECTED: Rift application is using an incompatible version %d.%d.%d (my version=%d.%d.%d)", hello.MajorVersion, hello.MinorVersion, hello.PatchVersion, RPCVersion_Major, RPCVersion_Minor, RPCVersion_Patch); - AllConnections.RemoveAtUnordered(connIndex); + + conn->SetState(State_Zombie); + + // Send auth response + BitStream bsOut; + RPC_S2C_Authorization::Generate(&bsOut, "Incompatible protocol version. Please make sure your OVRService and SDK are both up to date."); + conn->pSocket->Send(bsOut.GetData(), bsOut.GetNumberOfBytesUsed()); } else { @@ -612,6 +631,7 @@ void Session::TCP_OnClosed(TCPSocket* s) invokeSessionEvent(&SessionListener::OnHandshakeAttemptFailed, conn); break; case State_Connected: + case State_Zombie: invokeSessionEvent(&SessionListener::OnDisconnected, conn); break; default: diff --git a/LibOVR/Src/Net/OVR_Session.h b/LibOVR/Src/Net/OVR_Session.h index 8f709eb..8bd0b24 100644 --- a/LibOVR/Src/Net/OVR_Session.h +++ b/LibOVR/Src/Net/OVR_Session.h @@ -44,11 +44,13 @@ class Session; // Based on Semantic Versioning ( http://semver.org/ ) // // Please update changelog below: -// 1.0.0 - Initial DK2 release version (July 21, 2014) -catid +// 1.0.0 - [SDK 0.4.0] Initial version (July 21, 2014) +// 1.1.0 - Add Get/SetDriverMode_1, HMDCountUpdate_1 +// Version mismatch results (July 28, 2014) //----------------------------------------------------------------------------- static const uint16_t RPCVersion_Major = 1; // MAJOR version when you make incompatible API changes, -static const uint16_t RPCVersion_Minor = 0; // MINOR version when you add functionality in a backwards-compatible manner, and +static const uint16_t RPCVersion_Minor = 1; // MINOR version when you add functionality in a backwards-compatible manner, and static const uint16_t RPCVersion_Patch = 0; // PATCH version when you make backwards-compatible bug fixes. // Client starts communication by sending its version number. @@ -118,7 +120,7 @@ struct RPC_S2C_Authorization return bs->Read(PatchVersion); } - static void Generate(Net::BitStream* bs); + static void Generate(Net::BitStream* bs, String errorString = ""); bool Validate(); }; @@ -132,6 +134,7 @@ enum SessionResult SessionResult_BindFailure, SessionResult_ListenFailure, SessionResult_ConnectFailure, + SessionResult_ConnectInProgress, SessionResult_AlreadyConnected, }; @@ -196,28 +199,37 @@ protected: } public: - virtual void SetState(EConnectionState s) { - if (s==State) - return; + virtual void SetState(EConnectionState s) + { + if (s != State) + { + Mutex::Locker locker(&StateMutex); - Mutex::Locker locker(&StateMutex); - State = s; - if (State != Client_Connecting) - ConnectingWait.NotifyAll(); + if (s != State) + { + State = s; + + if (State != Client_Connecting) + { + ConnectingWait.NotifyAll(); + } + } + } } - void WaitOnConnecting() { + void WaitOnConnecting() + { + Mutex::Locker locker(&StateMutex); + while (State == Client_Connecting) { - Mutex::Locker locker(&StateMutex); ConnectingWait.Wait(&StateMutex); } } - SockAddr Address; - - OVR::Mutex StateMutex; - OVR::WaitCondition ConnectingWait; + SockAddr Address; + Mutex StateMutex; + WaitCondition ConnectingWait; }; diff --git a/LibOVR/Src/Net/OVR_Win32_Socket.cpp b/LibOVR/Src/Net/OVR_Win32_Socket.cpp index e2705fe..36b83ca 100644 --- a/LibOVR/Src/Net/OVR_Win32_Socket.cpp +++ b/LibOVR/Src/Net/OVR_Win32_Socket.cpp @@ -65,7 +65,7 @@ void WSAStartupSingleton::AddRef() // If an error code is returned if (errCode != 0) { - LogError("[Socket] Unable to initialize Winsock %d", errCode); + LogError("{ERR-007w} [Socket] Unable to initialize Winsock %d", errCode); } } } @@ -135,6 +135,9 @@ BitStream& operator>>(BitStream& in, SockAddr& out) SockAddr::SockAddr() { WSAStartupSingleton::AddRef(); + + // Zero out the address to squelch static analysis tools + ZeroMemory(&Addr6, sizeof(Addr6)); } SockAddr::SockAddr(SockAddr* address) @@ -197,7 +200,7 @@ void SockAddr::Set(const char* hostAddress, uint16_t port, int sockType) if (0 != errcode) { - OVR::LogError("getaddrinfo error: %s", gai_strerror(errcode)); + OVR::LogError("{ERR-008w} getaddrinfo error: %s", gai_strerror(errcode)); } OVR_ASSERT(0 != servinfo); @@ -266,25 +269,29 @@ bool SockAddr::operator<( const SockAddr& right ) const return memcmp(&Addr6, &right.Addr6, sizeof(Addr6)) < 0; } - -static void SetSocketOptions(SocketHandle sock) +static bool SetSocketOptions(SocketHandle sock) { + int result = 0; int sock_opt; // This doubles the max throughput rate sock_opt=1024*256; - setsockopt(sock, SOL_SOCKET, SO_RCVBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) ); + result |= setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)& sock_opt, sizeof (sock_opt)); // Immediate hard close. Don't linger the socket, or recreating the socket quickly on Vista fails. // Fail with voice sock_opt=0; - setsockopt(sock, SOL_SOCKET, SO_LINGER, ( char * ) & sock_opt, sizeof ( sock_opt ) ); + result |= setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)& sock_opt, sizeof (sock_opt)); // This doesn't make much difference: 10% maybe // Not supported on console 2 sock_opt=1024*16; - setsockopt(sock, SOL_SOCKET, SO_SNDBUF, ( char * ) & sock_opt, sizeof ( sock_opt ) ); + result |= setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)& sock_opt, sizeof (sock_opt)); + + // If all the setsockopt() returned 0 there were no failures, so return true for success, else false + return result == 0; } + void _Ioctlsocket(SocketHandle sock, unsigned long nonblocking) { ioctlsocket( sock, FIONBIO, &nonblocking ); @@ -311,7 +318,7 @@ static SocketHandle BindShared(int ai_family, int ai_socktype, BerkleyBindParame if (0 != errcode) { - OVR::LogError("getaddrinfo error: %s", gai_strerror(errcode)); + OVR::LogError("{ERR-020w} getaddrinfo error: %s", gai_strerror(errcode)); } for (aip = servinfo; aip != NULL; aip = aip->ai_next) @@ -319,10 +326,9 @@ static SocketHandle BindShared(int ai_family, int ai_socktype, BerkleyBindParame // Open socket. The address type depends on what // getaddrinfo() gave us. sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); - if (sock != 0) + if (sock != INVALID_SOCKET) { - int ret = bind( sock, aip->ai_addr, (int) aip->ai_addrlen ); - if (ret>=0) + if (bind(sock, aip->ai_addr, (int)aip->ai_addrlen) != SOCKET_ERROR) { // The actual socket is always non-blocking // I control blocking or not using WSAEventSelect @@ -330,12 +336,10 @@ static SocketHandle BindShared(int ai_family, int ai_socktype, BerkleyBindParame freeaddrinfo(servinfo); return sock; } - else - { + closesocket(sock); } } - } if (servinfo) { freeaddrinfo(servinfo); } return INVALID_SOCKET; @@ -583,7 +587,7 @@ void TCPSocketPollState::HandleEvent(TCPSocket* tcpSocket, SocketEvent_TCP* even socklen_t sockAddrSize = sizeof(sockAddr); SocketHandle newSock = accept(handle, (sockaddr*)&sockAddr, (socklen_t*)&sockAddrSize); - if (newSock > 0) + if (newSock != INVALID_SOCKET) { SockAddr sa(&sockAddr); eventHandler->TCP_OnAccept(tcpSocket, &sa, newSock); diff --git a/LibOVR/Src/OVR_CAPI.cpp b/LibOVR/Src/OVR_CAPI.cpp index b9b693a..83d0583 100644 --- a/LibOVR/Src/OVR_CAPI.cpp +++ b/LibOVR/Src/OVR_CAPI.cpp @@ -110,6 +110,7 @@ TrackingState::TrackingState(const ovrTrackingState& s) LeveledCameraPose = s.LeveledCameraPose; RawSensorData = s.RawSensorData; StatusFlags = s.StatusFlags; + LastVisionProcessingTime = s.LastVisionProcessingTime; } TrackingState::operator ovrTrackingState() const @@ -120,6 +121,7 @@ TrackingState::operator ovrTrackingState() const result.LeveledCameraPose = LeveledCameraPose; result.RawSensorData = RawSensorData; result.StatusFlags = StatusFlags; + result.LastVisionProcessingTime = LastVisionProcessingTime; return result; } @@ -221,14 +223,14 @@ OVR_EXPORT double ovr_GetTimeInSeconds() // Waits until the specified absolute time. OVR_EXPORT double ovr_WaitTillTime(double absTime) { - volatile int i; double initialTime = ovr_GetTimeInSeconds(); double newTime = initialTime; while(newTime < absTime) { - for (int j = 0; j < 50; j++) - i = 0; + for (int j = 0; j < 5; j++) + OVR_PROCESSOR_PAUSE(); + newTime = ovr_GetTimeInSeconds(); } @@ -248,7 +250,7 @@ static OVR::Service::NetClient* CAPI_pNetClient = 0; OVR_EXPORT void ovr_InitializeRenderingShim() { - OVR::System::DirectDisplayInitialize(); + OVR::System::DirectDisplayInitialize(); } OVR_EXPORT ovrBool ovr_Initialize() @@ -270,7 +272,7 @@ OVR_EXPORT ovrBool ovr_Initialize() // If the server could not start running, if (Service::NetServer::GetInstance()->IsInitialized()) { - CAPI_pNetClient->Connect(); + CAPI_pNetClient->Connect(true); } else { @@ -278,13 +280,13 @@ OVR_EXPORT ovrBool ovr_Initialize() // or another SingleProcess-mode app is running in the background. // In this case, it's using the hardware and we should not also attempt to use // the hardware. - LogError("[LibOVR] Server is already running"); + LogError("{ERR-079} [LibOVR] Server is already running"); } #else - CAPI_pNetClient->Connect(); + CAPI_pNetClient->Connect(true); #endif - CAPI_ovrInitializeCalled = 1; + CAPI_ovrInitializeCalled = 1; return 1; } @@ -292,13 +294,13 @@ OVR_EXPORT ovrBool ovr_Initialize() OVR_EXPORT void ovr_Shutdown() { // We should clean up the system to be complete - if (OVR::System::IsInitialized() && CAPI_SystemInitCalled) + if (OVR::System::IsInitialized() && CAPI_SystemInitCalled) { - OVR::System::Destroy(); - } + OVR::System::Destroy(); + } CAPI_SystemInitCalled = 0; - CAPI_ovrInitializeCalled = 0; + CAPI_ovrInitializeCalled = 0; } @@ -313,10 +315,10 @@ OVR_EXPORT void ovr_Shutdown() OVR_EXPORT int ovrHmd_Detect() { - if (!CAPI_ovrInitializeCalled) + if (!CAPI_ovrInitializeCalled) return 0; - return CAPI_pNetClient->Hmd_Detect(); + return CAPI_pNetClient->Hmd_Detect(); } @@ -341,6 +343,15 @@ OVR_EXPORT ovrHmd ovrHmd_Create(int index) // If two seconds elapse and still no HMD detected, if (Timer::GetSeconds() - t0 > 2.) { + if (!NetClient::GetInstance()->IsConnected(false, false)) + { + NetClient::GetInstance()->SetLastError("Not connected to service"); + } + else + { + NetClient::GetInstance()->SetLastError("No HMD Detected"); + } + return 0; } } @@ -350,6 +361,8 @@ OVR_EXPORT ovrHmd ovrHmd_Create(int index) if (!hmds) { CAPI_pNetClient->Hmd_Release(netInfo.NetId); + + NetClient::GetInstance()->SetLastError("Unable to create HMD state"); return 0; } @@ -361,17 +374,17 @@ OVR_EXPORT ovrHmd ovrHmd_Create(int index) OVR_EXPORT ovrBool ovrHmd_AttachToWindow( ovrHmd hmd, void* window, - const ovrRecti* destMirrorRect, - const ovrRecti* sourceRenderTargetRect ) + const ovrRecti* destMirrorRect, + const ovrRecti* sourceRenderTargetRect ) { - OVR_UNUSED( destMirrorRect ); - OVR_UNUSED( sourceRenderTargetRect ); + OVR_UNUSED( destMirrorRect ); + OVR_UNUSED( sourceRenderTargetRect ); - if (!CAPI_ovrInitializeCalled) - return false; + if (!CAPI_ovrInitializeCalled) + return false; - if (!hmd || !hmd->Handle) - return false; + if (!hmd || !hmd->Handle) + return false; #ifdef OVR_OS_WIN32 HMDState* hmds = (HMDState*)hmd->Handle; @@ -379,16 +392,19 @@ OVR_EXPORT ovrBool ovrHmd_AttachToWindow( ovrHmd hmd, void* window, hmds->pWindow = window; Win32::DisplayShim::GetInstance().hWindow = (HWND)window; +#else + OVR_UNUSED(window); #endif - return true; + + return true; } OVR_EXPORT ovrHmd ovrHmd_CreateDebug(ovrHmdType type) { - if (!CAPI_ovrInitializeCalled) + if (!CAPI_ovrInitializeCalled) return 0; - HMDState* hmds = HMDState::CreateHMDState(type); + HMDState* hmds = HMDState::CreateHMDState(type); return hmds->pHmdDesc; } @@ -427,20 +443,25 @@ OVR_EXPORT const char* ovrHmd_GetLastError(ovrHmd hmddesc) return "System initialize not called"; } + VirtualHmdId netId = InvalidVirtualHmdId; + if (hmddesc && hmddesc->Handle) { HMDState* p = (HMDState*)hmddesc->Handle; - return CAPI_pNetClient->Hmd_GetLastError(p->GetNetId()); + netId = p->GetNetId(); } - return "Uninitialized Hmd"; + return CAPI_pNetClient->Hmd_GetLastError(netId); } +#define OVR_VERSION_LIBOVR_PFX "libOVR:" + // Returns version string representing libOVR version. Static, so // string remains valid for app lifespan OVR_EXPORT const char* ovr_GetVersionString() { - return "libOVR:" OVR_VERSION_STRING; + static const char* version = OVR_VERSION_LIBOVR_PFX OVR_VERSION_STRING; + return version + sizeof(OVR_VERSION_LIBOVR_PFX) - 1; } @@ -486,18 +507,18 @@ OVR_EXPORT void ovrHmd_SetEnabledCaps(ovrHmd hmddesc, unsigned int capsBits) OVR_EXPORT ovrBool ovrHmd_ConfigureTracking(ovrHmd hmddesc, unsigned int supportedCaps, unsigned int requiredCaps) { - if (hmddesc) - { + if (hmddesc) + { HMDState* p = (HMDState*)hmddesc->Handle; return p->ConfigureTracking(supportedCaps, requiredCaps); } - return 0; + return 0; } OVR_EXPORT void ovrHmd_RecenterPose(ovrHmd hmddesc) { - if (hmddesc) + if (hmddesc) { HMDState* p = (HMDState*)hmddesc->Handle; p->TheSensorStateReader.RecenterPose(); @@ -506,7 +527,7 @@ OVR_EXPORT void ovrHmd_RecenterPose(ovrHmd hmddesc) OVR_EXPORT ovrTrackingState ovrHmd_GetTrackingState(ovrHmd hmddesc, double absTime) { - ovrTrackingState result = {0}; + ovrTrackingState result = {0}; if (hmddesc) { @@ -515,11 +536,11 @@ OVR_EXPORT ovrTrackingState ovrHmd_GetTrackingState(ovrHmd hmddesc, double absTi } #ifdef OVR_OS_WIN32 - // Set up display code for Windows - Win32::DisplayShim::GetInstance().Active = (result.StatusFlags & ovrStatus_HmdConnected) != 0; + // Set up display code for Windows + Win32::DisplayShim::GetInstance().Active = (result.StatusFlags & ovrStatus_HmdConnected) != 0; #endif - return result; + return result; } @@ -530,7 +551,7 @@ OVR_EXPORT ovrTrackingState ovrHmd_GetTrackingState(ovrHmd hmddesc, double absTi OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmddesc, ovrEyeType eye, ovrFovPort fov, float pixelsPerDisplayPixel) { - ovrHmdStruct * hmd = hmddesc->Handle; + ovrHmdStruct * hmd = hmddesc->Handle; if (!hmd) return Sizei(0); HMDState* hmds = (HMDState*)hmd; @@ -548,7 +569,7 @@ ovrBool ovrHmd_ConfigureRendering( ovrHmd hmddesc, const ovrFovPort eyeFovIn[2], ovrEyeRenderDesc eyeRenderDescOut[2] ) { - ovrHmdStruct * hmd = hmddesc->Handle; + ovrHmdStruct * hmd = hmddesc->Handle; if (!hmd) return 0; return ((HMDState*)hmd)->ConfigureRendering(eyeRenderDescOut, eyeFovIn, apiConfig, distortionCaps); @@ -559,7 +580,7 @@ ovrBool ovrHmd_ConfigureRendering( ovrHmd hmddesc, // TBD: MA - Deprecated, need alternative void ovrHmd_SetVsync(ovrHmd hmddesc, ovrBool vsync) { - ovrHmdStruct * hmd = hmddesc->Handle; + ovrHmdStruct * hmd = hmddesc->Handle; if (!hmd) return; return ((HMDState*)hmd)->TimeManager.SetVsync(vsync? true : false); @@ -604,21 +625,11 @@ OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmddesc, hmds->pRenderer->SetLatencyTestColor(hmds->LatencyTestActive ? hmds->LatencyTestDrawColor : NULL); - // TBD: Move directly into renderer - bool dk2LatencyTest = (hmds->EnabledHmdCaps & ovrHmdCap_DynamicPrediction) != 0; - if (dk2LatencyTest) - { - hmds->TimeManager.GetFrameLatencyTestDrawColor(hmds->LatencyTest2DrawColor); - hmds->pRenderer->SetLatencyTest2Color(hmds->LatencyTest2DrawColor); - } - else - { - hmds->pRenderer->SetLatencyTest2Color(NULL); - } + ovrHmd_GetLatencyTest2DrawColor(hmddesc, NULL); // We don't actually need to draw color, so send NULL if (hmds->pRenderer) - { - hmds->pRenderer->SaveGraphicsState(); + { + hmds->pRenderer->SaveGraphicsState(); // See if we need to show the HSWDisplay. if (hmds->pHSWDisplay) // Until we know that these are valid, assume any of them can't be. @@ -634,19 +645,11 @@ OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmddesc, } hmds->pRenderer->EndFrame(true); - hmds->pRenderer->RestoreGraphicsState(); + hmds->pRenderer->RestoreGraphicsState(); } // Call after present ovrHmd_EndFrameTiming(hmddesc); - if (dk2LatencyTest) - { - Util::FrameTimeRecordSet recordset; - hmds->TheLatencyTestStateReader.GetRecordSet(recordset); - hmds->TimeManager.UpdateFrameLatencyTrackingAfterEndFrame( hmds->LatencyTest2DrawColor, - recordset); - } - // Out of BeginFrame hmds->BeginFrameThreadId = 0; hmds->BeginFrameCalled = false; @@ -673,7 +676,7 @@ OVR_EXPORT void ovrHmd_RegisterPostDistortionCallback(ovrHmd hmddesc, PostDistor OVR_EXPORT ovrFrameTiming ovrHmd_GetFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) { - ovrHmdStruct * hmd = hmddesc->Handle; + ovrHmdStruct * hmd = hmddesc->Handle; ovrFrameTiming f; memset(&f, 0, sizeof(f)); @@ -702,7 +705,7 @@ OVR_EXPORT ovrFrameTiming ovrHmd_GetFrameTiming(ovrHmd hmddesc, unsigned int fra OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) { - ovrHmdStruct * hmd = hmddesc->Handle; + ovrHmdStruct * hmd = hmddesc->Handle; ovrFrameTiming f; memset(&f, 0, sizeof(f)); @@ -748,6 +751,15 @@ OVR_EXPORT void ovrHmd_EndFrameTiming(ovrHmd hmddesc) hmds->TimeManager.EndFrame(); hmds->BeginFrameTimingCalled = false; + + bool dk2LatencyTest = (hmds->EnabledHmdCaps & ovrHmdCap_DynamicPrediction) != 0; + if (dk2LatencyTest) + { + Util::FrameTimeRecordSet recordset; + hmds->TheLatencyTestStateReader.GetRecordSet(recordset); + hmds->TimeManager.UpdateFrameLatencyTrackingAfterEndFrame( hmds->LatencyTest2DrawColor, + recordset); + } } @@ -766,7 +778,7 @@ OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmddesc, unsigned int frameIndex ovrPosef ovrHmd_GetEyePose(ovrHmd hmd, ovrEyeType eye) { - HMDState* hmds = (HMDState*)hmd->Handle; + HMDState* hmds = (HMDState*)hmd->Handle; if (!hmds) return ovrPosef(); // This isn't a great place, but since we removed ovrHmd_BeginEyeRender... @@ -777,7 +789,7 @@ ovrPosef ovrHmd_GetEyePose(ovrHmd hmd, ovrEyeType eye) } hmds->checkBeginFrameTimingScope("ovrHmd_GetEyePose"); - return hmds->TimeManager.GetEyePredictionPose(hmd, eye); + return hmds->TimeManager.GetEyePredictionPose(hmd, eye); } @@ -788,7 +800,7 @@ OVR_EXPORT void ovrHmd_AddDistortionTimeMeasurement(ovrHmd hmddesc, double disto HMDState* hmds = (HMDState*)hmddesc->Handle; hmds->checkBeginFrameTimingScope("ovrHmd_GetTimewarpEyeMatrices"); - hmds->TimeManager.AddDistortionTimeMeasurement(distortionTimeSeconds); + hmds->TimeManager.AddDistortionTimeMeasurement(distortionTimeSeconds); } @@ -798,7 +810,7 @@ OVR_EXPORT void ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmddesc, ovrEyeType eye, { if (!hmddesc) return; - HMDState* hmds = (HMDState*)hmddesc->Handle; + HMDState* hmds = (HMDState*)hmddesc->Handle; // Debug checks: BeginFrame was called, on the same thread. hmds->checkBeginFrameTimingScope("ovrHmd_GetTimewarpEyeMatrices"); @@ -845,15 +857,14 @@ OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmddesc, ovrDistortionMesh *meshData) { // The 'internal' function below can be found in CAPI_HMDState. - // Not ideal, but navigating the convolutions of what compiles - // where, meant they are in the few places which actually lets these compile. - // Please relocate (if you wish) to a more meaningful place if you can navigate the compiler gymnastics :) - return(ovrHmd_CreateDistortionMeshInternal( hmddesc->Handle, + // Not ideal, but navigating the convolutions of what compiles + // where, meant they are in the few places which actually lets these compile. + // Please relocate (if you wish) to a more meaningful place if you can navigate the compiler gymnastics :) + return(ovrHmd_CreateDistortionMeshInternal( hmddesc->Handle, eyeType, fov, distortionCaps, meshData, - 0)); - + 0)); } @@ -916,6 +927,36 @@ OVR_EXPORT const char* ovrHmd_GetLatencyTestResult(ovrHmd hmddesc) return NetClient::GetInstance()->LatencyUtil_GetResultsString(); } +OVR_EXPORT ovrBool ovrHmd_GetLatencyTest2DrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]) +{ + HMDState* hmds = (HMDState*)hmddesc->Handle; + if (!hmds) return false; + + // TBD: Move directly into renderer + bool dk2LatencyTest = (hmds->EnabledHmdCaps & ovrHmdCap_DynamicPrediction) != 0; + if (dk2LatencyTest) + { + hmds->TimeManager.GetFrameLatencyTestDrawColor(hmds->LatencyTest2DrawColor); + if(rgbColorOut != NULL) + { + rgbColorOut[0] = hmds->LatencyTest2DrawColor[0]; + rgbColorOut[1] = hmds->LatencyTest2DrawColor[1]; + rgbColorOut[2] = hmds->LatencyTest2DrawColor[2]; + } + + if(hmds->pRenderer != NULL) + hmds->pRenderer->SetLatencyTest2Color(hmds->LatencyTest2DrawColor); + } + else + { + if(hmds->pRenderer != NULL) + hmds->pRenderer->SetLatencyTest2Color(NULL); + } + + return dk2LatencyTest; +} + + OVR_EXPORT double ovrHmd_GetMeasuredLatencyTest2(ovrHmd hmddesc) { HMDState* p = (HMDState*)hmddesc->Handle; @@ -936,8 +977,8 @@ OVR_EXPORT void ovrHmd_GetHSWDisplayState(ovrHmd hmd, ovrHSWDisplayState *hswDis { OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; - if (pHMDState) - { + if (pHMDState) + { OVR::CAPI::HSWDisplay* pHSWDisplay = pHMDState->pHSWDisplay; if(pHSWDisplay) @@ -949,8 +990,8 @@ OVR_EXPORT ovrBool ovrHmd_DismissHSWDisplay(ovrHmd hmd) { OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; - if (pHMDState) - { + if (pHMDState) + { OVR::CAPI::HSWDisplay* pHSWDisplay = pHMDState->pHSWDisplay; if(pHSWDisplay) @@ -963,136 +1004,189 @@ OVR_EXPORT ovrBool ovrHmd_DismissHSWDisplay(ovrHmd hmd) // ----------------------------------------------------------------------------------- // ***** Property Access -OVR_EXPORT ovrBool ovrHmd_GetBool(ovrHmd hmddesc, const char* propertyName, ovrBool defaultVal) +OVR_EXPORT ovrBool ovrHmd_GetBool(ovrHmd hmddesc, + const char* propertyName, + ovrBool defaultVal) +{ + OVR_ASSERT(propertyName); + if (hmddesc) { - OVR_ASSERT(hmddesc && propertyName); - HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); if (hmds) { return hmds->getBoolValue(propertyName, (defaultVal != 0)); } + } - return defaultVal; + return NetClient::GetInstance()->GetBoolValue(InvalidVirtualHmdId, propertyName, (defaultVal != 0)) ? 1 : 0; } -OVR_EXPORT ovrBool ovrHmd_SetBool(ovrHmd hmddesc, const char* propertyName, ovrBool value) +OVR_EXPORT ovrBool ovrHmd_SetBool(ovrHmd hmddesc, + const char* propertyName, + ovrBool value) +{ + OVR_ASSERT(propertyName); + if (hmddesc) { - OVR_ASSERT(hmddesc && propertyName); - HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); if (hmds) { return hmds->setBoolValue(propertyName, value != 0) ? 1 : 0; } - return false; } -OVR_EXPORT int ovrHmd_GetInt(ovrHmd hmddesc, const char* propertyName, int defaultVal) -{ - OVR_ASSERT(hmddesc && propertyName); + return NetClient::GetInstance()->SetBoolValue(InvalidVirtualHmdId, propertyName, (value != 0)) ? 1 : 0; +} +OVR_EXPORT int ovrHmd_GetInt(ovrHmd hmddesc, + const char* propertyName, + int defaultVal) +{ + OVR_ASSERT(propertyName); + if (hmddesc) + { HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); if (hmds) { return hmds->getIntValue(propertyName, defaultVal); } + } - return defaultVal; + return NetClient::GetInstance()->GetIntValue(InvalidVirtualHmdId, propertyName, defaultVal); } -OVR_EXPORT ovrBool ovrHmd_SetInt(ovrHmd hmddesc, const char* propertyName, int value) +OVR_EXPORT ovrBool ovrHmd_SetInt(ovrHmd hmddesc, + const char* propertyName, + int value) +{ + OVR_ASSERT(propertyName); + if (hmddesc) { - OVR_ASSERT(hmddesc && propertyName); - HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); if (hmds) { - return hmds->setIntValue(propertyName, value); + return hmds->setIntValue(propertyName, value) ? 1 : 0; } - return false; } -OVR_EXPORT float ovrHmd_GetFloat(ovrHmd hmddesc, const char* propertyName, float defaultVal) -{ - OVR_ASSERT(hmddesc && propertyName); + return NetClient::GetInstance()->SetIntValue(InvalidVirtualHmdId, propertyName, value) ? 1 : 0; +} +OVR_EXPORT float ovrHmd_GetFloat(ovrHmd hmddesc, + const char* propertyName, + float defaultVal) +{ + OVR_ASSERT(propertyName); + if (hmddesc) + { HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); if (hmds) { return hmds->getFloatValue(propertyName, defaultVal); } + } - return defaultVal; + return (float)NetClient::GetInstance()->GetNumberValue(InvalidVirtualHmdId, propertyName, defaultVal); } -OVR_EXPORT ovrBool ovrHmd_SetFloat(ovrHmd hmddesc, const char* propertyName, float value) +OVR_EXPORT ovrBool ovrHmd_SetFloat(ovrHmd hmddesc, + const char* propertyName, + float value) +{ + OVR_ASSERT(propertyName); + if (hmddesc) { - OVR_ASSERT(hmddesc && propertyName); - HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); if (hmds) { - return hmds->setFloatValue(propertyName, value); + return hmds->setFloatValue(propertyName, value) ? 1 : 0; } - return false; } -OVR_EXPORT unsigned int ovrHmd_GetFloatArray(ovrHmd hmddesc, const char* propertyName, - float values[], unsigned int arraySize) -{ - OVR_ASSERT(hmddesc && propertyName); + return NetClient::GetInstance()->SetNumberValue(InvalidVirtualHmdId, propertyName, value) ? 1 : 0; +} +OVR_EXPORT unsigned int ovrHmd_GetFloatArray(ovrHmd hmddesc, + const char* propertyName, + float values[], + unsigned int arraySize) +{ + OVR_ASSERT(propertyName); + OVR_ASSERT(hmddesc); + if (hmddesc) + { HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); if (hmds) { return hmds->getFloatArray(propertyName, values, arraySize); } + } + // FIXME: Currently it takes a few lines of code to do this, so just not supported for now. return 0; } // Modify float[] property; false if property doesn't exist or is readonly. -OVR_EXPORT ovrBool ovrHmd_SetFloatArray(ovrHmd hmddesc, const char* propertyName, - float values[], unsigned int arraySize) +OVR_EXPORT ovrBool ovrHmd_SetFloatArray(ovrHmd hmddesc, + const char* propertyName, + float values[], + unsigned int arraySize) +{ + OVR_ASSERT(propertyName); + OVR_ASSERT(hmddesc); + if (hmddesc) { - OVR_ASSERT(hmddesc && propertyName); - HMDState* hmds = (HMDState*)hmddesc->Handle; + OVR_ASSERT(hmds); if (hmds) { - return hmds->setFloatArray(propertyName, values, arraySize); + return hmds->setFloatArray(propertyName, values, arraySize) ? 1 : 0; + } } + // FIXME: Currently it takes a few lines of code to do this, so just not supported for now. return 0; } -OVR_EXPORT const char* ovrHmd_GetString(ovrHmd hmddesc, const char* propertyName, +OVR_EXPORT const char* ovrHmd_GetString(ovrHmd hmddesc, + const char* propertyName, const char* defaultVal) { - OVR_ASSERT(hmddesc && propertyName); - + OVR_ASSERT(propertyName); + if (hmddesc) + { HMDState* hmds = (HMDState*)hmddesc->Handle; if (hmds) { return hmds->getString(propertyName, defaultVal); } + } - return defaultVal; + return NetClient::GetInstance()->GetStringValue(InvalidVirtualHmdId, propertyName, defaultVal); } -OVR_EXPORT ovrBool ovrHmd_SetString(ovrHmd hmddesc, const char* propertyName, +OVR_EXPORT ovrBool ovrHmd_SetString(ovrHmd hmddesc, + const char* propertyName, const char* value) { - OVR_ASSERT(hmddesc && propertyName); - + OVR_ASSERT(propertyName); + if (hmddesc) + { HMDState* hmds = (HMDState*)hmddesc->Handle; if (hmds) { return hmds->setString(propertyName, value) ? 1 : 0; } + } - return 0; + return NetClient::GetInstance()->SetStringValue(InvalidVirtualHmdId, propertyName, value) ? 1 : 0; } diff --git a/LibOVR/Src/OVR_CAPI.h b/LibOVR/Src/OVR_CAPI.h index 2efeb15..09a06e2 100644 --- a/LibOVR/Src/OVR_CAPI.h +++ b/LibOVR/Src/OVR_CAPI.h @@ -193,6 +193,7 @@ typedef enum ovrDistortionCap_FlipInput = 0x20, /// Flip the vertical texture coordinate of input images. ovrDistortionCap_SRGB = 0x40, /// Assume input images are in sRGB gamma-corrected color space. ovrDistortionCap_Overdrive = 0x80, /// Overdrive brightness transitions to reduce artifacts on DK2+ displays + ovrDistortionCap_HqDistortion = 0x100, /// High-quality sampling of distortion buffer for anti-aliasing ovrDistortionCap_ProfileNoTimewarpSpinWaits = 0x10000, /// Use when profiling with timewarp to remove false positives } ovrDistortionCaps; @@ -319,6 +320,11 @@ typedef struct ovrTrackingState_ /// Tracking status described by ovrStatusBits. unsigned int StatusFlags; + + //// 0.4.1 + + /// Time spent processing the last vision frame + double LastVisionProcessingTime; } ovrTrackingState; @@ -465,7 +471,7 @@ extern "C" { // Either ovr_InitializeRenderingShim() or ovr_Initialize() must be called before any // Direct3D or OpenGL initilization is done by applictaion (creation of devices, etc). // ovr_Initialize() must still be called after to use the rest of LibOVR APIs. -OVR_EXPORT void ovr_InitializeRenderingShim(); +OVR_EXPORT void ovr_InitializeRenderingShim(); // Library init/shutdown, must be called around all other OVR code. // No other functions calls besides ovr_InitializeRenderingShim are allowed @@ -776,6 +782,9 @@ OVR_EXPORT ovrBool ovrHmd_ProcessLatencyTest(ovrHmd hmd, unsigned char rgbC /// Buffer is valid until next call. OVR_EXPORT const char* ovrHmd_GetLatencyTestResult(ovrHmd hmd); +/// Returns the latency testing color in rgbColorOut to render when using a DK2 +/// Returns false if this feature is disabled or not-applicable (e.g. using a DK1) +OVR_EXPORT ovrBool ovrHmd_GetLatencyTest2DrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]); //------------------------------------------------------------------------------------- @@ -849,27 +858,30 @@ OVR_EXPORT ovrBool ovrHmd_DismissHSWDisplay(ovrHmd hmd); // For now, access profile entries; this will change. #if !defined(OVR_KEY_USER) - #define OVR_KEY_USER "User" - #define OVR_KEY_NAME "Name" - #define OVR_KEY_GENDER "Gender" - #define OVR_KEY_PLAYER_HEIGHT "PlayerHeight" - #define OVR_KEY_EYE_HEIGHT "EyeHeight" - #define OVR_KEY_IPD "IPD" - #define OVR_KEY_NECK_TO_EYE_DISTANCE "NeckEyeDistance" - - // TODO: remove this duplication with OVR_Profile.h - // Default measurements empirically determined at Oculus to make us happy - // The neck model numbers were derived as an average of the male and female averages from ANSUR-88 - // NECK_TO_EYE_HORIZONTAL = H22 - H43 = INFRAORBITALE_BACK_OF_HEAD - TRAGION_BACK_OF_HEAD - // NECK_TO_EYE_VERTICAL = H21 - H15 = GONION_TOP_OF_HEAD - ECTOORBITALE_TOP_OF_HEAD - // These were determined to be the best in a small user study, clearly beating out the previous default values - #define OVR_DEFAULT_GENDER "Unknown" - #define OVR_DEFAULT_PLAYER_HEIGHT 1.778f - #define OVR_DEFAULT_EYE_HEIGHT 1.675f - #define OVR_DEFAULT_IPD 0.064f - #define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.0805f - #define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.075f - #define OVR_DEFAULT_EYE_RELIEF_DIAL 3 +#define OVR_KEY_USER "User" +#define OVR_KEY_NAME "Name" +#define OVR_KEY_GENDER "Gender" +#define OVR_KEY_PLAYER_HEIGHT "PlayerHeight" +#define OVR_KEY_EYE_HEIGHT "EyeHeight" +#define OVR_KEY_IPD "IPD" +#define OVR_KEY_NECK_TO_EYE_DISTANCE "NeckEyeDistance" +#define OVR_KEY_CAMERA_POSITION "CenteredFromWorld" + +// TODO: remove this duplication with OVR_Profile.h +// Default measurements empirically determined at Oculus to make us happy +// The neck model numbers were derived as an average of the male and female averages from ANSUR-88 +// NECK_TO_EYE_HORIZONTAL = H22 - H43 = INFRAORBITALE_BACK_OF_HEAD - TRAGION_BACK_OF_HEAD +// NECK_TO_EYE_VERTICAL = H21 - H15 = GONION_TOP_OF_HEAD - ECTOORBITALE_TOP_OF_HEAD +// These were determined to be the best in a small user study, clearly beating out the previous default values +#define OVR_DEFAULT_GENDER "Unknown" +#define OVR_DEFAULT_PLAYER_HEIGHT 1.778f +#define OVR_DEFAULT_EYE_HEIGHT 1.675f +#define OVR_DEFAULT_IPD 0.064f +#define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.0805f +#define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.075f +#define OVR_DEFAULT_EYE_RELIEF_DIAL 3 +#define OVR_DEFAULT_CAMERA_POSITION {0,0,0,1,0,0,0} + #endif /// Get boolean property. Returns first element if property is a boolean array. diff --git a/LibOVR/Src/OVR_CAPI_D3D.h b/LibOVR/Src/OVR_CAPI_D3D.h index 330615d..fbbd1f5 100644 --- a/LibOVR/Src/OVR_CAPI_D3D.h +++ b/LibOVR/Src/OVR_CAPI_D3D.h @@ -41,10 +41,8 @@ limitations under the License. //----------------------------------------------------------------------------------- // ***** D3D11 Specific - #include <d3d11.h> - /// Used to configure slave D3D rendering (i.e. for devices created externally). struct ovrD3D11ConfigData { diff --git a/LibOVR/Src/OVR_Profile.cpp b/LibOVR/Src/OVR_Profile.cpp index b22477f..fdcc5ba 100644 --- a/LibOVR/Src/OVR_Profile.cpp +++ b/LibOVR/Src/OVR_Profile.cpp @@ -136,7 +136,7 @@ String GetBaseOVRPath(bool create_dir) CreateDirectory(wpath, NULL); } } - + #elif defined(OVR_OS_MAC) const char* home = getenv("HOME"); @@ -158,8 +158,7 @@ String GetBaseOVRPath(bool create_dir) #else - passwd* pwd = getpwuid(getuid()); - const char* home = pwd->pw_dir; + const char* home = getenv("HOME"); path = home; path += "/.config/Oculus"; @@ -183,7 +182,7 @@ String GetBaseOVRPath(bool create_dir) String ProfileManager::GetProfilePath() { - return BasePath + "/ProfileDB.json"; + return BasePath + "/ProfileDB.json"; } static JSON* FindTaggedData(JSON* data, const char** tag_names, const char** qtags, int num_qtags) @@ -274,10 +273,10 @@ template<> ProfileManager* OVR::SystemSingletonBase<ProfileManager>::SlowGetInst } ProfileManager::ProfileManager(bool sys_register) : - Changed(false) + Changed(false) { - // Attempt to get the base path automatically, but this may fail - BasePath = GetBaseOVRPath(false); + // Attempt to get the base path automatically, but this may fail + BasePath = GetBaseOVRPath(false); if (sys_register) PushDestroyCallbacks(); @@ -296,11 +295,11 @@ void ProfileManager::OnSystemDestroy() // In the service process it is important to set the base path because this cannot be detected automatically void ProfileManager::SetBasePath(String basePath) { - if (basePath != BasePath) - { - BasePath = basePath; - LoadCache(false); - } + if (basePath != BasePath) + { + BasePath = basePath; + LoadCache(false); + } } // Clear the local profile cache @@ -315,10 +314,10 @@ void ProfileManager::ClearProfileData() // Serializes the profiles to disk. void ProfileManager::Save() { - Lock::Locker lockScope(&ProfileLock); + Lock::Locker lockScope(&ProfileLock); - if (ProfileCache == NULL) - return; + if (ProfileCache == NULL) + return; // Save the profile to disk BasePath = GetBaseOVRPath(true); // create the base directory if it doesn't exist @@ -357,7 +356,7 @@ Profile* ProfileManager::GetDefaultProfile(HmdTypeEnum device) // TODO: These defaults are a little bogus and designed for continuity with 0.3 // eye-relief values. We need better measurement-based numbers in future releases - float max_eye_plate[2] = { 0.01965f + 0.017f, 0.01965f + 0.017f }; + float max_eye_plate[2] = { 0.01965f + 0.018f, 0.01965f + 0.018f }; profile->SetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, max_eye_plate, 2); } else @@ -789,8 +788,8 @@ bool ProfileManager::SetDefaultUser(const ProfileDeviceKey& deviceKey, const cha const char* tag_names[2] = {"Product", "Serial"}; const char* tags[2]; - const char* product_str = deviceKey.ProductName.IsEmpty() ? NULL : deviceKey.ProductName.ToCStr(); - const char* serial_str = deviceKey.PrintedSerial.IsEmpty() ? NULL : deviceKey.PrintedSerial.ToCStr(); + const char* product_str = deviceKey.ProductName.IsEmpty() ? NULL : deviceKey.ProductName.ToCStr(); + const char* serial_str = deviceKey.PrintedSerial.IsEmpty() ? NULL : deviceKey.PrintedSerial.ToCStr(); if (product_str && serial_str) { @@ -985,7 +984,7 @@ bool ProfileManager::SetTaggedProfile(const char** tag_names, const char** tags, //----------------------------------------------------------------------------- Profile* ProfileManager::GetDefaultUserProfile(const ProfileDeviceKey& deviceKey) { - const char* userName = GetDefaultUser(deviceKey); + const char* userName = GetDefaultUser(deviceKey); Profile* profile = GetProfile(deviceKey, userName); @@ -1009,11 +1008,11 @@ Profile* ProfileManager::GetProfile(const ProfileDeviceKey& deviceKey, const cha return NULL; } - Profile* profile = new Profile(BasePath); + Profile* profile = new Profile(BasePath); - if (deviceKey.Valid) + if (deviceKey.Valid) { - if (!profile->LoadDeviceProfile(deviceKey) && (user == NULL)) + if (!profile->LoadDeviceProfile(deviceKey) && (user == NULL)) { profile->Release(); return NULL; @@ -1022,8 +1021,8 @@ Profile* ProfileManager::GetProfile(const ProfileDeviceKey& deviceKey, const cha if (user) { - const char* product_str = deviceKey.ProductName.IsEmpty() ? NULL : deviceKey.ProductName.ToCStr(); - const char* serial_str = deviceKey.PrintedSerial.IsEmpty() ? NULL : deviceKey.PrintedSerial.ToCStr(); + const char* product_str = deviceKey.ProductName.IsEmpty() ? NULL : deviceKey.ProductName.ToCStr(); + const char* serial_str = deviceKey.PrintedSerial.IsEmpty() ? NULL : deviceKey.PrintedSerial.ToCStr(); if (!profile->LoadProfile(ProfileCache.GetPtr(), user, product_str, serial_str)) { @@ -1084,7 +1083,7 @@ void Profile::CopyItems(JSON* root, String prefix) //----------------------------------------------------------------------------- bool Profile::LoadDeviceFile(unsigned int productId, const char* printedSerialNumber) { - if (printedSerialNumber[0] == 0) + if (printedSerialNumber[0] == 0) return false; String path = BasePath + "/Devices.json"; @@ -1115,7 +1114,7 @@ bool Profile::LoadDeviceFile(unsigned int productId, const char* printedSerialNu JSON* product_item = device->GetItemByName("ProductID"); JSON* serial_item = device->GetItemByName("Serial"); if (product_item && serial_item && - (product_item->dValue == productId) && (serial_item->Value == printedSerialNumber)) + (product_item->dValue == productId) && (serial_item->Value == printedSerialNumber)) { // found the entry for this device so recursively copy all the settings to the profile CopyItems(device, ""); @@ -1144,7 +1143,7 @@ static int BCDByte(unsigned int byte) bool Profile::LoadDeviceProfile(const ProfileDeviceKey& deviceKey) { bool success = false; - if (!deviceKey.Valid) + if (!deviceKey.Valid) return false; #if 0 @@ -1162,7 +1161,7 @@ bool Profile::LoadDeviceProfile(const ProfileDeviceKey& deviceKey) #endif // Grab the model and serial number from the device and use it to access the device // profile file stored on the local machine - success = LoadDeviceFile(deviceKey.ProductId, deviceKey.PrintedSerial); + success = LoadDeviceFile(deviceKey.ProductId, deviceKey.PrintedSerial); //} return success; @@ -1390,10 +1389,7 @@ int Profile::GetDoubleValues(const char* key, double* values, int num_vals) cons return count; } - else - { - return 0; - } + return 0; } //----------------------------------------------------------------------------- @@ -1576,7 +1572,7 @@ void Profile::SetDoubleValues(const char* key, const double* vals, int num_vals) //------------------------------------------------------------------------------ bool Profile::IsDefaultProfile() { - return 0 == OVR::String::CompareNoCase("Default", GetValue(OVR_KEY_NAME)); + return 0 == OVR::String::CompareNoCase("Default", GetValue(OVR_KEY_NAME)); } diff --git a/LibOVR/Src/OVR_Profile.h b/LibOVR/Src/OVR_Profile.h index a11e9c4..cb6a2f5 100644 --- a/LibOVR/Src/OVR_Profile.h +++ b/LibOVR/Src/OVR_Profile.h @@ -96,7 +96,7 @@ class ProfileManager : public NewOverrideBase, public SystemSingletonBase<Profil protected: ProfileManager(bool sys_register); - ~ProfileManager(); + virtual ~ProfileManager(); virtual void OnSystemDestroy(); protected: @@ -227,6 +227,7 @@ protected: #define OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE "MaxEyeToPlateDist" #define OVR_KEY_EYE_CUP "EyeCup" #define OVR_KEY_CUSTOM_EYE_RENDER "CustomEyeRender" +#define OVR_KEY_CAMERA_POSITION "CenteredFromWorld" // Default measurements empirically determined at Oculus to make us happy // The neck model numbers were derived as an average of the male and female averages from ANSUR-88 @@ -240,6 +241,7 @@ protected: #define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.0805f #define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.075f #define OVR_DEFAULT_EYE_RELIEF_DIAL 3 +#define OVR_DEFAULT_CAMERA_POSITION {0,0,0,1,0,0,0} #endif // OVR_KEY_USER diff --git a/LibOVR/Src/OVR_SerialFormat.cpp b/LibOVR/Src/OVR_SerialFormat.cpp index abe68e5..027aed2 100644 --- a/LibOVR/Src/OVR_SerialFormat.cpp +++ b/LibOVR/Src/OVR_SerialFormat.cpp @@ -27,6 +27,10 @@ limitations under the License. #include "OVR_SerialFormat.h" +#ifdef SERIAL_FORMAT_UNIT_TEST +#include "Kernel/OVR_Log.h" +#endif + namespace OVR { @@ -229,7 +233,7 @@ bool DK2PrintedSerialFormat::FromBase32(const char* str, bool allowUnknownTypes) // Product Id - int productId = Base32FromChar[str[0]]; + int productId = Base32FromChar[(unsigned char)str[0]]; if (productId < 0 || (!allowUnknownTypes && !ValidDK2ProductId(productId))) { return false; @@ -239,7 +243,7 @@ bool DK2PrintedSerialFormat::FromBase32(const char* str, bool allowUnknownTypes) // Label Type - int labelType = Base32FromChar[str[1]]; + int labelType = Base32FromChar[(unsigned char)str[1]]; if (labelType < 0 || (!allowUnknownTypes && !ValidDK2PartId(labelType))) { return false; @@ -250,7 +254,7 @@ bool DK2PrintedSerialFormat::FromBase32(const char* str, bool allowUnknownTypes) uint8_t dataBytes[7]; for (int ii = 0; ii < 7; ++ii) { - int c = Base32FromChar[str[2 + ii]]; + int c = Base32FromChar[(unsigned char)str[2 + ii]]; if (c < 0) return false; dataBytes[ii] = (uint8_t)c; } @@ -267,7 +271,7 @@ bool DK2PrintedSerialFormat::FromBase32(const char* str, bool allowUnknownTypes) for (int ii = 0; ii < 3; ++ii) { - int c = Base32FromChar[str[9 + ii]]; + int c = Base32FromChar[(unsigned char)str[9 + ii]]; if (c < 0) { return false; @@ -353,90 +357,563 @@ void DK2PrintedSerialFormat::FromBinary(const DK2BinarySerialFormat& bin) } -//// Unit Tests +//// Human Strings -#ifdef SERIAL_FORMAT_UNIT_TEST +// For generator polynomial 101111b: +static const uint8_t GF32_LOG_TABLE[32] = { + 64, 31, 1, 12, 2, 24, 13, 27, 3, 8, 25, 10, 14, 18, 28, 5, + 4, 17, 9, 7, 26, 23, 11, 30, 15, 21, 19, 20, 29, 22, 6, 16 +}; +static const uint8_t GF32_ALOG_TABLE[129] = { + 1, 2, 4, 8, 16, 15, 30, 19, 9, 18, 11, 22, 3, 6, 12, 24, + 31, 17, 13, 26, 27, 25, 29, 21, 5, 10, 20, 7, 14, 28, 23, 1, + 2, 4, 8, 16, 15, 30, 19, 9, 18, 11, 22, 3, 6, 12, 24, 31, + 17, 13, 26, 27, 25, 29, 21, 5, 10, 20, 7, 14, 28, 23, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; +static const uint8_t GF32_INV_TABLE[32] = { + 0, 1, 23, 26, 28, 19, 13, 16, 14, 21, 30, 25, 17, 6, 8, 20, + 7, 12, 29, 5, 15, 9, 27, 2, 31, 11, 3, 22, 4, 18, 10, 24 +}; -int DecodeBase32(char ch) +// Multiplication in GF(32) : x * y = e^(log(x) + log(y)) +OVR_FORCE_INLINE uint8_t GF32Multiply(uint8_t x, uint8_t y) { - if (ch >= '2' && ch <= '9') - return 2 + ch - '2'; - if (ch >= 'a' && ch <= 'h') - return 10 + ch - 'a'; - if (ch >= 'A' && ch <= 'H') - return 10 + ch - 'A'; - if (ch >= 'j' && ch <= 'k') - return 18 + ch - 'j'; - if (ch >= 'J' && ch <= 'K') - return 18 + ch - 'J'; - if (ch >= 'm' && ch <= 'n') - return 20 + ch - 'm'; - if (ch >= 'M' && ch <= 'N') - return 20 + ch - 'M'; - if (ch >= 'p' && ch <= 't') - return 22 + ch - 'p'; - if (ch >= 'P' && ch <= 'T') - return 22 + ch - 'P'; - if (ch >= 'v' && ch <= 'z') - return 27 + ch - 'v'; - if (ch >= 'V' && ch <= 'Z') - return 27 + ch - 'V'; - - switch (ch) - { - case '0': - case 'o': - case 'O': - return 0; - case '1': - case 'i': - case '|': - case 'I': - case 'L': - case 'l': - return 1; - } - - return -1; + return GF32_ALOG_TABLE[GF32_LOG_TABLE[x] + GF32_LOG_TABLE[y]]; +} +OVR_FORCE_INLINE uint8_t GF32Divide(uint8_t x, uint8_t y) +{ + return GF32_ALOG_TABLE[GF32_LOG_TABLE[x] + 31 - GF32_LOG_TABLE[y]]; } -void TestSerialFormatStuff() +// Normally these inputs are constant so this is just useful for development +static bool ValidateHumanStringBits(int dataBits, int checkBits) { - for (int ii = 0; ii < 256; ++ii) - { - OVR_ASSERT(Base32FromChar[ii] == (char)DecodeBase32((char)ii)); - } + // If no data bits or data bits leave no room for a checksum, + if (dataBits < 1 || dataBits >= 160) + { + OVR_ASSERT(false); + return false; + } + + // If no check bits or check bits leave no room for a checksum, + if (checkBits < 1 || checkBits >= 160) + { + OVR_ASSERT(false); + return false; + } + // Note: It's recommended to have at least 5 check bits so that + // character typos can be caught. + + // The sum of check bits and data bits must be a multiple of 5! + if ((checkBits + dataBits) % 5 != 0) + { + OVR_ASSERT(false); + return false; + } + + // The total number of human string digits cannot exceed 32. + if ((checkBits + dataBits + 4) / 5 > 32) + { + OVR_ASSERT(false); + return false; + } + + return true; +} - DK2BinarySerialFormat sa; - sa.ProductId = DK2ProductId_DK2; - sa.PartId = DK2PartId_HMD; - sa.MinutesSinceEpoch = 65000; - sa.UnitNumber = 2; - sa.MacHash[0] = 0xa1; - sa.MacHash[1] = 0xb2; - sa.MacHash[2] = 0xc3; - sa.MacHash[3] = 0xd4; - sa.MacHash[4] = 0xe5; +// Generate check buffer +static void GenerateChecks(const uint8_t* data, int dataCount, uint8_t* checks, int checkCount, int msbCount) +{ + // For each check symbol to generate, + for (int i = 0; i < checkCount; ++i) + { + // Matrix multiplication inner loop + uint8_t x = 0; + for (int j = 0; j < dataCount; ++j) + { + // GF(32): x += d[i,j] * k, k = 1 / (j - i), ie. Cauchy matrix + x ^= GF32Multiply(data[j], GF32_INV_TABLE[(checkCount + j) ^ i]); + } + checks[i] = x; + } + + // Clear high bits of checks + if (msbCount > 0) + { + checks[checkCount - 1] &= (1 << msbCount) - 1; + } +} - uint8_t buffer[12]; - sa.ToBuffer(buffer); +// Generates a Human-readable labels with built-in checksums +// Returns false on error +bool GenerateHumanString(int dataBits, // Number of bits to store + int checkBits, // Number of extra bits of checksum data + const unsigned char* input, // Bytes stored LSB-first + const int dataBytes, // Size of data buffer in bytes + String& resultStr) // Output string +{ + if (!ValidateHumanStringBits(dataBits, checkBits)) + { + return false; + } + + // If the buffer is the wrong size, + if (dataBytes < (dataBits + 7) / 8) + { + OVR_ASSERT(false); + return false; + } + + resultStr.Clear(); + + // Copy data bits + int dataCount = (dataBits + 4) / 5; + uint8_t data[32] = { 0 }; // Initialized to zeros + for (int i = 0; i < dataBits; ++i) + { + // Grab bit + int bit = (input[i / 8] >> (i % 8)) & 1; + + // Copy to data + data[i / 5] |= bit << (i % 5); + } + + // Generate checks + int checkCount = (checkBits + 4) / 5; + uint8_t checks[32]; + GenerateChecks(data, dataCount, checks, checkCount, checkBits % 5); + + // Copy full parts of checks after the partial character (if it exists) + int fullCheckCount = checkBits / 5; + for (int i = 0; i < fullCheckCount; ++i) + { + data[dataCount + i] = checks[i]; + } + + // If there is a partial check character, + int partialCheckBits = checkBits % 5; + if (partialCheckBits > 0) + { + // Write the high bits of the partial high symbol there + int word = checks[fullCheckCount] << (5 - partialCheckBits); + word &= 0x1f; + data[dataCount - 1] |= word; + } + + // Write base-32 representation of data + int outCount = (dataBits + checkBits) / 5; + for (int i = 0; i < outCount; ++i) + { + resultStr += CharFromBase32[data[i]]; + } + + return true; +} - DK2BinarySerialFormat sb; - OVR_ASSERT(sb.FromBuffer(buffer)); +// Fix errors in data found by checks +static bool FixHumanChecksum(uint8_t* data, int dataCount, uint8_t* checks, int checkCount, int msbCount) +{ + uint8_t actualChecks[32]; + GenerateChecks(data, dataCount, actualChecks, checkCount, msbCount); + + // Search for check mismatches + int checkFails = 0; + for (int i = 0; i < checkCount; ++i) + { + if (actualChecks[i] != checks[i]) + { + ++checkFails; + } + } + + // Calculate full check count + int fullCheckCount = checkCount; + if (msbCount > 0) + { + fullCheckCount--; + } + + // If there is a lot of full check data, + if (fullCheckCount >= 2) + { + // Accept one error in the checks + if (checkFails <= 1) + { + return true; + } + + // Attempt to correct single errors: + for (int errPosition = 0; errPosition < dataCount; ++errPosition) + { + uint8_t oldData = data[errPosition]; + + // Use the first check symbol for corrections + uint8_t x = 0; + for (int j = 0; j < dataCount; ++j) + { + if (j != errPosition) + { + x ^= GF32Multiply(data[j], GF32_INV_TABLE[checkCount + j]); + } + } + x ^= checks[0]; + + // Calculate missing symbol + data[errPosition] = GF32Divide(x, GF32_INV_TABLE[checkCount + errPosition]); + + GenerateChecks(data, dataCount, actualChecks, checkCount, msbCount); + + // Search for check mismatches again: + int checkFails = 0; + for (int i = 0; i < checkCount; ++i) + { + if (actualChecks[i] != checks[i]) + { + // Ignore the partial checksum in case it got corrupted too + if (msbCount > 0 && + errPosition == dataCount - 1 && + i == checkCount - 1) + { + continue; + } + ++checkFails; + break; + } + } + + // Accept the correction if all checks agree now + if (checkFails == 0) + { + // Keep the correction if it succeeded + return true; + } + + data[errPosition] = oldData; + } + } + else + { + // Do not accept any check fails + if (checkFails <= 0) + { + return true; + } + } + + return false; +} - OVR_ASSERT(sa == sb); +// Returns number of bytes written to result, or zero on failure +int ProcessHumanString(int dataBits, // Number of bits to expect + int checkBits, // Number of extra bits of checksum data + String humanStr, // Human readable input string + unsigned char* result, // Output data buffer stored LSB-first + const int resultBytes) // Size of result buffer in bytes +{ + if (!ValidateHumanStringBits(dataBits, checkBits)) + { + return 0; + } + + // If the string is not precisely the right length, + if (humanStr.GetLengthI() != (dataBits + checkBits + 4) / 5) + { + return 0; + } + + // If the result buffer is not large enough, + int dataBytes = (dataBits + 7) / 8; + if (dataBytes > resultBytes) + { + OVR_ASSERT(false); // Programming error + return 0; + } + + // Convert human string to 5-bit symbols + uint8_t data[32]; + const char* cHumanStr = humanStr.ToCStr(); + for (int i = 0; i < humanStr.GetLengthI(); ++i) + { + char word = Base32FromChar[(unsigned char)cHumanStr[i]]; + if (word < 0) + { + // Attempt to replace invalid characters, + // and rely on error correction to fix it. + word = 0; + } + data[i] = word; + } + + // Extract checks from data + int dataCount = (dataBits + 4) / 5; + int checkCount = (checkBits + 4) / 5; + uint8_t checks[32]; + + // Copy full check characters + int fullCheckCount = checkBits / 5; + for (int i = 0; i < fullCheckCount; ++i) + { + checks[i] = data[dataCount + i]; + } + + // If there is a partial check character, + int partialCheckBits = checkBits % 5; + if (partialCheckBits > 0) + { + // Read high bits as the check high partial symbol + uint8_t word = data[dataCount - 1] >> (5 - partialCheckBits); + checks[fullCheckCount] = word; + + // Clear high bits of data that contain check bits + data[dataCount - 1] ^= word << (5 - partialCheckBits); + } + + // Fuzzy accept input + if (!FixHumanChecksum(data, (dataBits + 4) / 5, checks, checkCount, checkBits % 5)) + { + return 0; + } + + // Copy data bits to output buffer + memset(result, 0, resultBytes); + for (int i = 0; i < dataBits; ++i) + { + // Grab data bit + int bit = (data[i / 5] >> (i % 5)) & 1; + + // Write it into result + result[i / 8] |= bit << (i % 8); + } + + return dataBytes; +} - DK2PrintedSerialFormat psn; - psn.FromBinary(sb); - OVR_ASSERT(psn == sa); +//// Unit Tests - String s = psn.ToBase32(); +#ifdef SERIAL_FORMAT_UNIT_TEST - DK2PrintedSerialFormat psn2; - psn2.FromBase32(s.ToCStr()); +int DecodeBase32(char ch) +{ + if (ch >= '2' && ch <= '9') + return 2 + ch - '2'; + if (ch >= 'a' && ch <= 'h') + return 10 + ch - 'a'; + if (ch >= 'A' && ch <= 'H') + return 10 + ch - 'A'; + if (ch >= 'j' && ch <= 'k') + return 18 + ch - 'j'; + if (ch >= 'J' && ch <= 'K') + return 18 + ch - 'J'; + if (ch >= 'm' && ch <= 'n') + return 20 + ch - 'm'; + if (ch >= 'M' && ch <= 'N') + return 20 + ch - 'M'; + if (ch >= 'p' && ch <= 't') + return 22 + ch - 'p'; + if (ch >= 'P' && ch <= 'T') + return 22 + ch - 'P'; + if (ch >= 'v' && ch <= 'z') + return 27 + ch - 'v'; + if (ch >= 'V' && ch <= 'Z') + return 27 + ch - 'V'; + + switch (ch) + { + case '0': + case 'o': + case 'O': + return 0; + case '1': + case 'i': + case '|': + case 'I': + case 'L': + case 'l': + return 1; + } + + return -1; +} - OVR_ASSERT(psn == psn2); +void TestSerialFormatStuff() +{ + for (int ii = 0; ii < 256; ++ii) + { + OVR_ASSERT(Base32FromChar[ii] == (char)DecodeBase32((char)ii)); + } + + DK2BinarySerialFormat sa; + sa.ProductId = DK2ProductId_DK2; + sa.PartId = DK2PartId_HMD; + sa.MinutesSinceEpoch = 65000; + sa.UnitNumber = 2; + sa.MacHash[0] = 0xa1; + sa.MacHash[1] = 0xb2; + sa.MacHash[2] = 0xc3; + sa.MacHash[3] = 0xd4; + sa.MacHash[4] = 0xe5; + + uint8_t buffer[12]; + sa.ToBuffer(buffer); + + DK2BinarySerialFormat sb; + bool success = sb.FromBuffer(buffer); + OVR_ASSERT(success); + OVR_UNUSED(success); + + OVR_ASSERT(sa == sb); + + DK2PrintedSerialFormat psn; + psn.FromBinary(sb); + + OVR_ASSERT(psn == sa); + + String s = psn.ToBase32(); + + DK2PrintedSerialFormat psn2; + psn2.FromBase32(s.ToCStr()); + + OVR_ASSERT(psn == psn2); + + unsigned char data[32]; + unsigned char result[32]; + + int trials = 0; + int trial_failures = 0; + + for (int seed = 0; seed < 20; ++seed) + { + srand(seed); + + for (int dataBits = 1; dataBits < 160; ++dataBits) + { + for (int checkBits = 1; checkBits < 160 - dataBits; ++checkBits) + { + String human; + + int fillCheckBits = (checkBits + dataBits) % 5; + if (fillCheckBits > 0) + { + fillCheckBits = 5 - fillCheckBits + checkBits; + } + else + { + fillCheckBits = checkBits; + } + + for (int i = 0; i < sizeof(data); ++i) + { + data[i] = (unsigned char)rand(); + if (seed == 1) + { + data[i] = 0; + } + else if (seed == 0) + { + data[i] = 0xff; + } + } + + if (dataBits % 8 != 0) + { + data[dataBits / 8] &= (1 << (dataBits % 8)) - 1; + } + + if (!GenerateHumanString(dataBits, fillCheckBits, data, sizeof(data), human)) + { + OVR_ASSERT(false); + } + + int bytes = ProcessHumanString(dataBits, fillCheckBits, human, result, sizeof(result)); + + if (bytes <= 0) + { + OVR_ASSERT(false); + } + + OVR_ASSERT(bytes == (dataBits + 7) / 8); + + for (int i = 0; i < bytes; ++i) + { + OVR_ASSERT(data[i] == result[i]); + } + + // Produce maximal failures and verify that we catch them: + + if (fillCheckBits >= 5) + { + char* cstr = (char*)human.ToCStr(); + + for (int i = 0; i < fillCheckBits / 5; ++i) + { + cstr[i] ^= 1; + } + + trials++; + bytes = ProcessHumanString(dataBits, fillCheckBits, cstr, result, sizeof(result)); + + // Undo errors + for (int i = 0; i < fillCheckBits / 5; ++i) + { + cstr[i] ^= 1; + } + + if (bytes > 0) + { + for (int i = 0; i < bytes; ++i) + { + if (data[i] != result[i]) + { + trial_failures++; + break; + } + } + } + + // If enough check bits, + if (fillCheckBits >= 10) + { + // Introduce one error at all positions and verify it is corrected: + char* cstr = (char*)human.ToCStr(); + + for (int j = 0; j < human.GetLengthI(); ++j) + { + if (dataBits % 5 != 0 && j == (dataBits / 5)) + { + // Note: Corrupting a shared character + // effectively breaks two symbols at once and recovery is not possible.. + continue; + } + + cstr[j] ^= 1; + + bytes = ProcessHumanString(dataBits, fillCheckBits, cstr, result, sizeof(result)); + + OVR_ASSERT(bytes > 0); + + for (int i = 0; i < bytes; ++i) + { + OVR_ASSERT(data[i] == result[i]); + } + + cstr[j] ^= 1; + } + } + } + } + } + } + + // Allow some number of false positives in exchange for error correction + OVR_ASSERT(trial_failures <= 0.008 * trials); + + LogText("[SerialFormatUnitTest] Success: False accept rate = %d / %d\n", trial_failures, trials); } #endif // SERIAL_FORMAT_UNIT_TEST diff --git a/LibOVR/Src/OVR_SerialFormat.h b/LibOVR/Src/OVR_SerialFormat.h index 1050e74..22151f7 100644 --- a/LibOVR/Src/OVR_SerialFormat.h +++ b/LibOVR/Src/OVR_SerialFormat.h @@ -117,11 +117,28 @@ public: }; +// Generates a Human-readable labels with built-in checksums +// Returns false on error +bool GenerateHumanString(int dataBits, // Number of bits to store + int checkBits, // Number of extra bits of checksum data + const unsigned char* input, // Bytes stored LSB-first + int dataBytes, // Size of data buffer in bytes + String& resultStr); // Output string + +// Returns number of bytes written to result, or zero on failure +int ProcessHumanString(int dataBits, // Number of bits to expect + int checkBits, // Number of extra bits of checksum data + String humanStr, // Human readable input string + unsigned char* result, // Output data buffer stored LSB-first + int resultBytes); // Size of result buffer in bytes + + //#define SERIAL_FORMAT_UNIT_TEST #ifdef SERIAL_FORMAT_UNIT_TEST void TestSerialFormatStuff(); #endif + } // OVR #endif // OVR_SerialFormat_h diff --git a/LibOVR/Src/OVR_Stereo.cpp b/LibOVR/Src/OVR_Stereo.cpp index 5f4cae3..beb936b 100644 --- a/LibOVR/Src/OVR_Stereo.cpp +++ b/LibOVR/Src/OVR_Stereo.cpp @@ -1036,7 +1036,35 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI numDistortions = 0; - distortions[numDistortions].EyeRelief = 0.010f; + distortions[numDistortions].EyeRelief = 0.008f; + distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.036f; + // TODO: Need to retune this distortion for minimum eye relief + distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10; + distortions[numDistortions].Config.K[0] = 1.003f; + distortions[numDistortions].Config.K[1] = 1.02f; + distortions[numDistortions].Config.K[2] = 1.042f; + distortions[numDistortions].Config.K[3] = 1.066f; + distortions[numDistortions].Config.K[4] = 1.094f; + distortions[numDistortions].Config.K[5] = 1.126f; + distortions[numDistortions].Config.K[6] = 1.162f; + distortions[numDistortions].Config.K[7] = 1.203f; + distortions[numDistortions].Config.K[8] = 1.25f; + distortions[numDistortions].Config.K[9] = 1.31f; + distortions[numDistortions].Config.K[10] = 1.38f; + distortions[numDistortions].MaxRadius = 1.0f; + + distortions[numDistortions].Config.ChromaticAberration[0] = -0.0112f; + distortions[numDistortions].Config.ChromaticAberration[1] = -0.015f; + distortions[numDistortions].Config.ChromaticAberration[2] = 0.0187f; + distortions[numDistortions].Config.ChromaticAberration[3] = 0.015f; + + numDistortions++; + + + + + + distortions[numDistortions].EyeRelief = 0.018f; distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.036f; distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10; @@ -1044,15 +1072,23 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI distortions[numDistortions].Config.K[1] = 1.02f; distortions[numDistortions].Config.K[2] = 1.042f; distortions[numDistortions].Config.K[3] = 1.066f; - distortions[numDistortions].Config.K[4] = 1.094f; //1.0945f; - distortions[numDistortions].Config.K[5] = 1.126f; //1.127f; - distortions[numDistortions].Config.K[6] = 1.162f; //1.167f; - distortions[numDistortions].Config.K[7] = 1.203f; //1.218f; - distortions[numDistortions].Config.K[8] = 1.25f; //1.283f; - distortions[numDistortions].Config.K[9] = 1.31f; //1.37f; - distortions[numDistortions].Config.K[10] = 1.38f; //1.48f; + distortions[numDistortions].Config.K[4] = 1.094f; + distortions[numDistortions].Config.K[5] = 1.126f; + distortions[numDistortions].Config.K[6] = 1.162f; + distortions[numDistortions].Config.K[7] = 1.203f; + distortions[numDistortions].Config.K[8] = 1.25f; + distortions[numDistortions].Config.K[9] = 1.31f; + distortions[numDistortions].Config.K[10] = 1.38f; distortions[numDistortions].MaxRadius = 1.0f; + distortions[numDistortions].Config.ChromaticAberration[0] = -0.015f; + distortions[numDistortions].Config.ChromaticAberration[1] = -0.02f; + distortions[numDistortions].Config.ChromaticAberration[2] = 0.025f; + distortions[numDistortions].Config.ChromaticAberration[3] = 0.02f; + + defaultDistortion = numDistortions; // this is the default + numDistortions++; + /* // Orange Lens on DK2 distortions[numDistortions].EyeRelief = 0.010f; @@ -1072,22 +1108,6 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI distortions[numDistortions].Config.K[10] = 1.56f; distortions[numDistortions].MaxRadius = 1.0f; */ - - defaultDistortion = numDistortions; // this is the default - numDistortions++; - - distortions[numDistortions] = distortions[0]; - distortions[numDistortions].EyeRelief = 0.020f; - numDistortions++; - - // Chromatic aberration doesn't seem to change with eye relief. - for ( int i = 0; i < numDistortions; i++ ) - { - distortions[i].Config.ChromaticAberration[0] = -0.015f; - distortions[i].Config.ChromaticAberration[1] = -0.02f; - distortions[i].Config.ChromaticAberration[2] = 0.025f; - distortions[i].Config.ChromaticAberration[3] = 0.02f; - } } else { diff --git a/LibOVR/Src/Service/Service_NetClient.cpp b/LibOVR/Src/Service/Service_NetClient.cpp index b0fa464..8c3e232 100644 --- a/LibOVR/Src/Service/Service_NetClient.cpp +++ b/LibOVR/Src/Service/Service_NetClient.cpp @@ -27,6 +27,9 @@ limitations under the License. #include "Service_NetClient.h" #include "../Net/OVR_MessageIDTypes.h" +#ifdef OVR_OS_MAC +#define GetCurrentProcessId getpid +#endif OVR_DEFINE_SINGLETON(OVR::Service::NetClient); namespace OVR { namespace Service { @@ -37,7 +40,9 @@ using namespace OVR::Net; //// NetClient NetClient::NetClient() : - LatencyTesterAvailable(false) + LatencyTesterAvailable(false), + HMDCount(0), + EdgeTriggeredHMDCount(false) { GetSession()->AddSessionListener(this); @@ -69,10 +74,14 @@ int NetClient::Run() while (!Terminated) { - if (GetSession()->GetActiveSocketsCount()==0) - Thread::MSleep(10); + // Note: There is no watchdog here because the watchdog is part of the private code GetSession()->Poll(false); + + if (GetSession()->GetActiveSocketsCount() == 0) + { + Thread::MSleep(10); + } } return 0; @@ -82,7 +91,6 @@ void NetClient::OnReceive(ReceivePayload* pPayload, ListenerReceiveResult* lrrOu { OVR_UNUSED(lrrOut); OVR_UNUSED(pPayload); - } void NetClient::OnDisconnected(Connection* conn) @@ -90,13 +98,8 @@ void NetClient::OnDisconnected(Connection* conn) OVR_UNUSED(conn); OVR_DEBUG_LOG(("[NetClient] Disconnected")); -} -void NetClient::OnConnectionAttemptFailed(Net::Connection* conn) -{ - OVR_UNUSED(conn); - - OVR_DEBUG_LOG(("[NetClient] OnConnectionAttemptFailed")); + EdgeTriggeredHMDCount = false; } void NetClient::OnConnected(Connection* conn) @@ -106,9 +109,11 @@ void NetClient::OnConnected(Connection* conn) OVR_DEBUG_LOG(("[NetClient] Connected to a server running version %d.%d.%d (my version=%d.%d.%d)", conn->RemoteMajorVersion, conn->RemoteMinorVersion, conn->RemotePatchVersion, RPCVersion_Major, RPCVersion_Minor, RPCVersion_Patch)); + + EdgeTriggeredHMDCount = false; } -bool NetClient::Connect() +bool NetClient::Connect(bool blocking) { // Set up bind parameters OVR::Net::BerkleyBindParameters bbp; @@ -118,7 +123,12 @@ bool NetClient::Connect() sa.Set("::1", VRServicePort, SOCK_STREAM); // Attempt to connect - return GetSession()->ConnectPTCP(&bbp, &sa, true) == Net::SessionResult_OK; + OVR::Net::SessionResult result = GetSession()->ConnectPTCP(&bbp, &sa, blocking); + + // Already connected counts as success too + return result == Net::SessionResult_OK || + result == Net::SessionResult_AlreadyConnected || + result == Net::SessionResult_ConnectInProgress; } void NetClient::Disconnect() @@ -126,7 +136,7 @@ void NetClient::Disconnect() GetSession()->Shutdown(); } -bool NetClient::IsConnected(bool attemptReconnect) +bool NetClient::IsConnected(bool attemptReconnect, bool blockOnReconnect) { // If it was able to connect, if (GetSession()->GetConnectionCount() > 0) @@ -136,7 +146,7 @@ bool NetClient::IsConnected(bool attemptReconnect) else if (attemptReconnect) { // Attempt to connect here - Connect(); + Connect(blockOnReconnect); // If it connected, if (GetSession()->GetConnectionCount() > 0) @@ -176,8 +186,10 @@ bool NetClient::GetRemoteProtocolVersion(int& major, int& minor, int& patch) const char* NetClient::GetStringValue(VirtualHmdId hmd, const char* key, const char* default_val) { - if (!IsConnected(true)) + if (!IsConnected(true, true)) + { return ""; + } ProfileGetValue1_Str = default_val; @@ -197,8 +209,10 @@ const char* NetClient::GetStringValue(VirtualHmdId hmd, const char* key, const c } bool NetClient::GetBoolValue(VirtualHmdId hmd, const char* key, bool default_val) { - if (!IsConnected(true)) + if (!IsConnected(true, true)) + { return default_val; + } OVR::Net::BitStream bsOut, returnData; bsOut.Write(hmd); @@ -217,8 +231,10 @@ bool NetClient::GetBoolValue(VirtualHmdId hmd, const char* key, bool default_val } int NetClient::GetIntValue(VirtualHmdId hmd, const char* key, int default_val) { - if (!IsConnected(true)) + if (!IsConnected(true, true)) + { return default_val; + } OVR::Net::BitStream bsOut, returnData; bsOut.Write(hmd); @@ -237,8 +253,10 @@ int NetClient::GetIntValue(VirtualHmdId hmd, const char* key, int default_val) } double NetClient::GetNumberValue(VirtualHmdId hmd, const char* key, double default_val) { - if (!IsConnected(true)) + if (!IsConnected(true, true)) + { return default_val; + } OVR::Net::BitStream bsOut, returnData; bsOut.Write(hmd); @@ -254,8 +272,10 @@ double NetClient::GetNumberValue(VirtualHmdId hmd, const char* key, double defau } int NetClient::GetNumberValues(VirtualHmdId hmd, const char* key, double* values, int num_vals) { - if (!IsConnected(true)) + if (!IsConnected(true, true)) + { return 0; + } OVR::Net::BitStream bsOut, returnData; bsOut.Write(hmd); @@ -294,10 +314,13 @@ int NetClient::GetNumberValues(VirtualHmdId hmd, const char* key, double* values return out; } -void NetClient::SetStringValue(VirtualHmdId hmd, const char* key, const char* val) + +bool NetClient::SetStringValue(VirtualHmdId hmd, const char* key, const char* val) { - if (!IsConnected(true)) - return; + if (!IsConnected(true, true)) + { + return false; + } OVR::Net::BitStream bsOut; bsOut.Write(hmd); @@ -308,12 +331,18 @@ void NetClient::SetStringValue(VirtualHmdId hmd, const char* key, const char* va if (!GetRPC1()->Signal("SetStringValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) { OVR_ASSERT(false); + return false; } + + return true; } -void NetClient::SetBoolValue(VirtualHmdId hmd, const char* key, bool val) + +bool NetClient::SetBoolValue(VirtualHmdId hmd, const char* key, bool val) { - if (!IsConnected(true)) - return; + if (!IsConnected(true, true)) + { + return false; + } OVR::Net::BitStream bsOut; bsOut.Write(hmd); @@ -325,12 +354,18 @@ void NetClient::SetBoolValue(VirtualHmdId hmd, const char* key, bool val) if (!GetRPC1()->Signal("SetBoolValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) { OVR_ASSERT(false); + return false; } + + return true; } -void NetClient::SetIntValue(VirtualHmdId hmd, const char* key, int val) + +bool NetClient::SetIntValue(VirtualHmdId hmd, const char* key, int val) { - if (!IsConnected(true)) - return; + if (!IsConnected(true, true)) + { + return false; + } OVR::Net::BitStream bsOut; bsOut.Write(hmd); @@ -342,12 +377,18 @@ void NetClient::SetIntValue(VirtualHmdId hmd, const char* key, int val) if (!GetRPC1()->Signal("SetIntValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) { OVR_ASSERT(false); + return false; } + + return true; } -void NetClient::SetNumberValue(VirtualHmdId hmd, const char* key, double val) + +bool NetClient::SetNumberValue(VirtualHmdId hmd, const char* key, double val) { - if (!IsConnected(true)) - return; + if (!IsConnected(true, true)) + { + return false; + } OVR::Net::BitStream bsOut; bsOut.Write(hmd); @@ -358,13 +399,17 @@ void NetClient::SetNumberValue(VirtualHmdId hmd, const char* key, double val) if (!GetRPC1()->Signal("SetNumberValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) { OVR_ASSERT(false); + return false; } + + return true; } -void NetClient::SetNumberValues(VirtualHmdId hmd, const char* key, const double* vals, int num_vals) + +bool NetClient::SetNumberValues(VirtualHmdId hmd, const char* key, const double* vals, int num_vals) { - if (!IsConnected(true)) + if (!IsConnected(true, true)) { - return; + return false; } OVR::Net::BitStream bsOut; @@ -382,16 +427,28 @@ void NetClient::SetNumberValues(VirtualHmdId hmd, const char* key, const double* if (!GetRPC1()->Signal("SetNumberValues_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) { OVR_ASSERT(false); + return false; } + + return true; } int NetClient::Hmd_Detect() { - if (!IsConnected(true)) + if (!IsConnected(true, false)) { return 0; } + // If using edge-triggered HMD counting, + if (EdgeTriggeredHMDCount) + { + // Return the last update from the server + return HMDCount; + } + + // Otherwise: We need to ask the first time + OVR::Net::BitStream bsOut, returnData; if (!GetRPC1()->CallBlocking("Hmd_Detect_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) @@ -405,12 +462,14 @@ int NetClient::Hmd_Detect() { OVR_ASSERT(false); } + HMDCount = out; + EdgeTriggeredHMDCount = true; return out; } bool NetClient::Hmd_Create(int index, HMDNetworkInfo* netInfo) { - if (!IsConnected(true)) + if (!IsConnected(true, true)) { return false; } @@ -420,9 +479,9 @@ bool NetClient::Hmd_Create(int index, HMDNetworkInfo* netInfo) int32_t w = (int32_t)index; bsOut.Write(w); -#ifdef OVR_OS_WIN32 +#if defined(OVR_OS_WIN32) || defined(OVR_OS_MAC) // Need the Pid for driver mode - DWORD pid = GetCurrentProcessId(); + pid_t pid = GetCurrentProcessId(); bsOut.Write(pid); #endif @@ -435,10 +494,78 @@ bool NetClient::Hmd_Create(int index, HMDNetworkInfo* netInfo) return netInfo->Deserialize(&returnData); } -void NetClient::Hmd_AttachToWindow(VirtualHmdId hmd, void* hWindow) +bool NetClient::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) { - if (!IsConnected()) - return; + if (!IsConnected(true, true)) + { + return false; + } + + OVR::Net::BitStream bsOut, returnData; + + bsOut.Write(InvalidVirtualHmdId); + + if (!GetRPC1()->CallBlocking("GetDriverMode_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + OVR_ASSERT(false); + return false; + } + + int32_t w_driverInstalled = 0; + int32_t w_compatMode = 0; + int32_t w_hideDK1Mode = 0; + returnData.Read(w_driverInstalled); + returnData.Read(w_compatMode); + if (!returnData.Read(w_hideDK1Mode)) + { + return false; + } + + driverInstalled = w_driverInstalled != 0; + compatMode = w_compatMode != 0; + hideDK1Mode = w_hideDK1Mode != 0; + return true; +} + +bool NetClient::SetDriverMode(bool compatMode, bool hideDK1Mode) +{ + if (!IsConnected(true, true)) + { + return false; + } + + OVR::Net::BitStream bsOut, returnData; + + bsOut.Write(InvalidVirtualHmdId); + + int32_t w_compatMode, w_hideDK1Mode; + w_compatMode = compatMode ? 1 : 0; + w_hideDK1Mode = hideDK1Mode ? 1 : 0; + bsOut.Write(w_compatMode); + bsOut.Write(w_hideDK1Mode); + + if (!GetRPC1()->CallBlocking("SetDriverMode_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + OVR_ASSERT(false); + return false; + } + + int32_t out = 0; + if (!returnData.Read(out)) + { + OVR_ASSERT(false); + return false; + } + + return out != 0; +} + +bool NetClient::Hmd_AttachToWindow(VirtualHmdId hmd, void* hWindow) +{ + if (!IsConnected(false, false)) + { + return false; + } OVR::Net::BitStream bsOut; bsOut.Write(hmd); @@ -449,13 +576,18 @@ void NetClient::Hmd_AttachToWindow(VirtualHmdId hmd, void* hWindow) if (!GetRPC1()->CallBlocking("Hmd_AttachToWindow_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) { OVR_ASSERT(false); + return false; } + + return true; } void NetClient::Hmd_Release(VirtualHmdId hmd) { - if (!IsConnected()) - return; + if (!IsConnected(false, false)) + { + return; + } OVR::Net::BitStream bsOut; bsOut.Write(hmd); @@ -465,10 +597,15 @@ void NetClient::Hmd_Release(VirtualHmdId hmd) } } +void NetClient::SetLastError(String str) +{ + Hmd_GetLastError_Str = str; +} + // Last string is cached locally. const char* NetClient::Hmd_GetLastError(VirtualHmdId hmd) { - if (!IsConnected()) + if (hmd == InvalidVirtualHmdId || !IsConnected(false, false)) { return Hmd_GetLastError_Str.ToCStr(); } @@ -492,7 +629,7 @@ const char* NetClient::Hmd_GetLastError(VirtualHmdId hmd) // The actual descriptor is a par bool NetClient::Hmd_GetHmdInfo(VirtualHmdId hmd, HMDInfo* hmdInfo) { - if (!IsConnected()) + if (!IsConnected(false, false)) { return false; } @@ -512,7 +649,7 @@ bool NetClient::Hmd_GetHmdInfo(VirtualHmdId hmd, HMDInfo* hmdInfo) //------------------------------------------------------------------------------------- unsigned int NetClient::Hmd_GetEnabledCaps(VirtualHmdId hmd) { - if (!IsConnected()) + if (!IsConnected(false, false)) { return 0; } @@ -536,7 +673,7 @@ unsigned int NetClient::Hmd_GetEnabledCaps(VirtualHmdId hmd) // Returns new caps after modification unsigned int NetClient::Hmd_SetEnabledCaps(VirtualHmdId hmd, unsigned int hmdCaps) { - if (!IsConnected()) + if (!IsConnected(false, false)) { return 0; } @@ -567,7 +704,7 @@ unsigned int NetClient::Hmd_SetEnabledCaps(VirtualHmdId hmd, unsigned int hmdCap bool NetClient::Hmd_ConfigureTracking(VirtualHmdId hmd, unsigned supportedCaps, unsigned requiredCaps) { - if (!IsConnected()) + if (!IsConnected(false, false)) { return false; } @@ -598,7 +735,7 @@ bool NetClient::Hmd_ConfigureTracking(VirtualHmdId hmd, unsigned supportedCaps, void NetClient::Hmd_ResetTracking(VirtualHmdId hmd) { - if (!IsConnected()) + if (!IsConnected(false, false)) { return; } @@ -614,7 +751,7 @@ void NetClient::Hmd_ResetTracking(VirtualHmdId hmd) bool NetClient::LatencyUtil_ProcessInputs(double startTestSeconds, unsigned char rgbColorOut[3]) { - if (!IsConnected()) + if (!IsConnected(false, false)) { return false; } @@ -648,7 +785,7 @@ bool NetClient::LatencyUtil_ProcessInputs(double startTestSeconds, unsigned char const char* NetClient::LatencyUtil_GetResultsString() { - if (!IsConnected()) + if (!IsConnected(false, false)) { return NULL; } @@ -670,7 +807,7 @@ const char* NetClient::LatencyUtil_GetResultsString() bool NetClient::ShutdownServer() { - if (!IsConnected()) + if (!IsConnected(false, false)) { return false; } @@ -692,7 +829,7 @@ void NetClient::registerRPC() // Register RPC functions: RPC_REGISTER_SLOT(InitialServerStateScope, InitialServerState_1); RPC_REGISTER_SLOT(LatencyTesterAvailableScope, LatencyTesterAvailable_1); - + RPC_REGISTER_SLOT(HMDCountUpdateScope, HMDCountUpdate_1); } void NetClient::InitialServerState_1(BitStream* userData, ReceivePayload* pPayload) @@ -714,6 +851,20 @@ void NetClient::LatencyTesterAvailable_1(BitStream* userData, ReceivePayload* pP LatencyTesterAvailable = (b != 0); } +void NetClient::HMDCountUpdate_1(BitStream* userData, ReceivePayload* pPayload) +{ + OVR_UNUSED(pPayload); + + int32_t hmdCount = 0; + if (!userData->Read(hmdCount)) + { + OVR_ASSERT(false); + return; + } + + HMDCount = hmdCount; + EdgeTriggeredHMDCount = true; +} }} // namespace OVR::Service diff --git a/LibOVR/Src/Service/Service_NetClient.h b/LibOVR/Src/Service/Service_NetClient.h index 6be6de8..96a8ad9 100644 --- a/LibOVR/Src/Service/Service_NetClient.h +++ b/LibOVR/Src/Service/Service_NetClient.h @@ -50,35 +50,42 @@ class NetClient : public NetSessionCommon, // Status bool LatencyTesterAvailable; + int HMDCount; + bool EdgeTriggeredHMDCount; virtual void OnReceive(Net::ReceivePayload* pPayload, Net::ListenerReceiveResult* lrrOut); virtual void OnDisconnected(Net::Connection* conn); virtual void OnConnected(Net::Connection* conn); - virtual void OnConnectionAttemptFailed(Net::Connection* conn); virtual int Run(); public: - bool Connect(); - bool IsConnected(bool attemptReconnect = false); + bool Connect(bool blocking); + bool IsConnected(bool attemptReconnect, bool blockOnReconnect); void Disconnect(); void GetLocalProtocolVersion(int& major, int& minor, int& patch); // This function may fail if it is not connected bool GetRemoteProtocolVersion(int& major, int& minor, int& patch); + void SetLastError(String str); + public: - // Key-value storage + // Persistent key-value storage const char* GetStringValue(VirtualHmdId hmd, const char* key, const char* default_val); bool GetBoolValue(VirtualHmdId hmd, const char* key, bool default_val); int GetIntValue(VirtualHmdId hmd, const char* key, int default_val); double GetNumberValue(VirtualHmdId hmd, const char* key, double default_val); int GetNumberValues(VirtualHmdId hmd, const char* key, double* values, int num_vals); - void SetStringValue(VirtualHmdId hmd, const char* key, const char* val); - void SetBoolValue(VirtualHmdId hmd, const char* key, bool val); - void SetIntValue(VirtualHmdId hmd, const char* key, int val); - void SetNumberValue(VirtualHmdId hmd, const char* key, double val); - void SetNumberValues(VirtualHmdId hmd, const char* key, const double* vals, int num_vals); + + bool SetStringValue(VirtualHmdId hmd, const char* key, const char* val); + bool SetBoolValue(VirtualHmdId hmd, const char* key, bool val); + bool SetIntValue(VirtualHmdId hmd, const char* key, int val); + bool SetNumberValue(VirtualHmdId hmd, const char* key, double val); + bool SetNumberValues(VirtualHmdId hmd, const char* key, const double* vals, int num_vals); + + bool GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode); + bool SetDriverMode(bool compatMode, bool hideDK1Mode); int Hmd_Detect(); bool Hmd_Create(int index, HMDNetworkInfo* netInfo); @@ -99,7 +106,7 @@ public: unsigned int Hmd_SetEnabledCaps(VirtualHmdId hmd, unsigned int hmdCaps); // Updates driver render target - void Hmd_AttachToWindow(VirtualHmdId hmd, void* hWindow); + bool Hmd_AttachToWindow(VirtualHmdId hmd, void* hWindow); //------------------------------------------------------------------------------------- // *** Tracking Setup @@ -123,11 +130,14 @@ protected: void registerRPC(); - ObserverScope<OVR::Net::Plugins::RPCSlot> InitialServerStateScope; + ObserverScope<Net::Plugins::RPCSlot> InitialServerStateScope; void InitialServerState_1(BitStream* userData, ReceivePayload* pPayload); - ObserverScope<OVR::Net::Plugins::RPCSlot> LatencyTesterAvailableScope; + ObserverScope<Net::Plugins::RPCSlot> LatencyTesterAvailableScope; void LatencyTesterAvailable_1(BitStream* userData, ReceivePayload* pPayload); + + ObserverScope<Net::Plugins::RPCSlot> HMDCountUpdateScope; + void HMDCountUpdate_1(BitStream* userData, ReceivePayload* pPayload); }; diff --git a/LibOVR/Src/Tracking/Tracking_PoseState.h b/LibOVR/Src/Tracking/Tracking_PoseState.h index c22395c..393d483 100644 --- a/LibOVR/Src/Tracking/Tracking_PoseState.h +++ b/LibOVR/Src/Tracking/Tracking_PoseState.h @@ -43,7 +43,7 @@ public: typedef typename CompatibleTypes<Pose<T> >::Type CompatibleType; PoseState() : TimeInSeconds(0.0) { } - PoseState(Pose<T> pose, double time) : TimeInSeconds(time), ThePose(pose) { } + PoseState(Pose<T> pose, double time) : ThePose(pose), TimeInSeconds(time) { } // float <-> double conversion constructor. explicit PoseState(const PoseState<typename Math<T>::OtherFloatType> &src) diff --git a/LibOVR/Src/Tracking/Tracking_SensorState.h b/LibOVR/Src/Tracking/Tracking_SensorState.h index 12072c0..b7c87ea 100644 --- a/LibOVR/Src/Tracking/Tracking_SensorState.h +++ b/LibOVR/Src/Tracking/Tracking_SensorState.h @@ -89,6 +89,11 @@ public: // Sensor status described by ovrStatusBits. uint32_t StatusFlags; + + //// 0.4.1 + + // Time spent processing the last vision frame + double LastVisionProcessingTime; }; @@ -110,6 +115,7 @@ struct LocklessSensorState // ImuFromCpf for HMD pose tracking Posed ImuFromCpf; + double LastVisionProcessingTime; // Initialized to invalid state LocklessSensorState() : @@ -119,7 +125,7 @@ struct LocklessSensorState LocklessSensorState& operator = (const LocklessSensorStatePadding& rhs); }; - + // 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. diff --git a/LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp b/LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp index b290480..bad4ffc 100644 --- a/LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp +++ b/LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp @@ -98,7 +98,6 @@ void SensorStateReader::RecenterPose() const LocklessSensorState lstate = Updater->SharedSensorState.GetState(); Posed worldFromCpf = lstate.WorldFromImu.ThePose * lstate.ImuFromCpf; - double hmdYaw, hmdPitch, hmdRoll; worldFromCpf.Rotation.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&hmdYaw, &hmdPitch, &hmdRoll); @@ -138,7 +137,7 @@ bool SensorStateReader::GetSensorStateAtTime(double absoluteTime, TrackingState& return false; } - // Delta time from the last available data + // Delta time from the last available data double pdt = absoluteTime - lstate.WorldFromImu.TimeInSeconds; static const double maxPdt = 0.1; @@ -167,6 +166,7 @@ bool SensorStateReader::GetSensorStateAtTime(double absoluteTime, TrackingState& ss.LeveledCameraPose = Posef(CenteredFromWorld * worldFromLeveledCamera); ss.RawSensorData = lstate.RawSensorData; + ss.LastVisionProcessingTime = lstate.LastVisionProcessingTime; return true; } @@ -203,5 +203,28 @@ uint32_t SensorStateReader::GetStatus() const return lstate.StatusFlags; } +void SensorStateReader::LoadProfileCenteredFromWorld(Profile* profile) +{ + double camerastate[7]; + if (profile->GetDoubleValues(OVR_KEY_CAMERA_POSITION, camerastate, 7) == 0) + { + for (int i = 0; i < 7; i++) camerastate[i] = 0; + camerastate[3] = 1;//no offset. by default, give the quaternion w component value 1 + } + + OVR::Quatd orientation = OVR::Quatd(camerastate[0], camerastate[1], camerastate[2], camerastate[3]); + OVR::Vector3d position = OVR::Vector3d(camerastate[4], camerastate[5], camerastate[6]); + + CenteredFromWorld = OVR::Posed(orientation, position); + +} + +void SensorStateReader::SaveProfileCenteredFromWorld(Profile* profile) +{ + OVR::Quatd rot = CenteredFromWorld.Rotation; + OVR::Vector3d trans = CenteredFromWorld.Translation; + double vals[7] = { rot.x, rot.y, rot.z, rot.w, trans.x, trans.y, trans.z }; + profile->SetDoubleValues(OVR_KEY_CAMERA_POSITION, vals, 7); +} }} // namespace OVR::Tracking diff --git a/LibOVR/Src/Tracking/Tracking_SensorStateReader.h b/LibOVR/Src/Tracking/Tracking_SensorStateReader.h index f1aa5f9..53b6efe 100644 --- a/LibOVR/Src/Tracking/Tracking_SensorStateReader.h +++ b/LibOVR/Src/Tracking/Tracking_SensorStateReader.h @@ -30,6 +30,8 @@ limitations under the License. #include "../Kernel/OVR_Lockless.h" #include "Tracking_SensorState.h" +#include "../OVR_Profile.h" + namespace OVR { namespace Tracking { @@ -42,12 +44,13 @@ class SensorStateReader : public NewOverrideBase protected: const CombinedSharedStateUpdater *Updater; - // Transform from real-world coordinates to centered coordinates - Posed CenteredFromWorld; // Last latency warning time mutable double LastLatWarnTime; + // Transform from real-world coordinates to centered coordinates + Posed CenteredFromWorld; + public: SensorStateReader(); @@ -66,6 +69,9 @@ public: // Get the sensor status (same as GetSensorStateAtTime(...).Status) uint32_t GetStatus() const; + + void LoadProfileCenteredFromWorld(Profile* profile); + void SaveProfileCenteredFromWorld(Profile* profile); }; diff --git a/LibOVR/Src/Util/Util_LongPollThread.cpp b/LibOVR/Src/Util/Util_LongPollThread.cpp deleted file mode 100644 index c7c5c5d..0000000 --- a/LibOVR/Src/Util/Util_LongPollThread.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/************************************************************************************ - -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 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.1 - -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(Observer<PollFunc>* func) -{ - func->Observe(PollSubject); -} - -LongPollThread::LongPollThread() : - Terminated(false) -{ - Start(); - - PushDestroyCallbacks(); -} - -LongPollThread::~LongPollThread() -{ - fireTermination(); - - Join(); -} - -void LongPollThread::OnThreadDestroy() -{ - fireTermination(); -} - -void LongPollThread::Wake() -{ - WakeEvent.SetEvent(); -} - -void LongPollThread::fireTermination() -{ - Terminated = true; - Wake(); -} - -void LongPollThread::OnSystemDestroy() -{ - Release(); -} - -int LongPollThread::Run() -{ - SetThreadName("LongPoll"); - WatchDog watchdog("LongPoll"); - - // While not terminated, - do - { - watchdog.Feed(10000); - - PollSubject->Call(); - - WakeEvent.Wait(WakeupInterval); - WakeEvent.ResetEvent(); - } while (!Terminated); - - return 0; -} - - -}} // namespace OVR::Util diff --git a/LibOVR/Src/Util/Util_LongPollThread.h b/LibOVR/Src/Util/Util_LongPollThread.h deleted file mode 100644 index 5183e2f..0000000 --- a/LibOVR/Src/Util/Util_LongPollThread.h +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************************ - -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 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.1 - -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 "../Kernel/OVR_Timer.h" -#include "../Kernel/OVR_Atomic.h" -#include "../Kernel/OVR_Allocator.h" -#include "../Kernel/OVR_String.h" -#include "../Kernel/OVR_System.h" -#include "../Kernel/OVR_Threads.h" -#include "../Kernel/OVR_Observer.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 Thread, public SystemSingletonBase<LongPollThread> -{ - OVR_DECLARE_SINGLETON(LongPollThread); - virtual void OnThreadDestroy(); - -public: - typedef Delegate0<void> PollFunc; - static const int WakeupInterval = 1000; // milliseconds - - void AddPollFunc(Observer<PollFunc>* func); - - void Wake(); - -protected: - ObserverScope<PollFunc> PollSubject; - - bool Terminated; - Event WakeEvent; - void fireTermination(); - - virtual int Run(); -}; - - -}} // namespace OVR::Util - -#endif // OVR_Util_LongPollThread_h diff --git a/LibOVR/Src/Util/Util_Render_Stereo.cpp b/LibOVR/Src/Util/Util_Render_Stereo.cpp index 6937141..1389462 100644 --- a/LibOVR/Src/Util/Util_Render_Stereo.cpp +++ b/LibOVR/Src/Util/Util_Render_Stereo.cpp @@ -545,8 +545,10 @@ void StereoConfig::UpdateComputedState() eyeTypes[1] = StereoEye_Right; break; - default: - OVR_ASSERT( false ); break; + default: + numEyes = 0; + OVR_ASSERT( false ); + break; } // If either of these fire, you've probably forgotten to call SetRendertargetSize() @@ -1069,14 +1071,14 @@ void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, uint16_t **ppTri } // Populate vertex buffer info - float xOffset = 0.0f; - float uOffset = 0.0f; - - if (rightEye) - { - xOffset = 1.0f; - uOffset = 0.5f; - } + //float xOffset = 0.0f; Not currently used. + //float uOffset = 0.0f; + + //if (rightEye) + //{ + // xOffset = 1.0f; + // uOffset = 0.5f; + //} // First pass - build up raw vertex data. HeightmapMeshVertexData* pcurVert = *ppVertices; diff --git a/LibOVR/Src/Util/Util_Settings.cpp b/LibOVR/Src/Util/Util_Settings.cpp deleted file mode 100644 index d7b3f0d..0000000 --- a/LibOVR/Src/Util/Util_Settings.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/************************************************************************************ - -Filename : Util_Settings.cpp -Content : Persistent settings subsystem -Created : June 11, 2014 -Author : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.1 - -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_Settings.h" -#include "../OVR_Profile.h" - -OVR_DEFINE_SINGLETON(Util::Settings); - -namespace OVR { namespace Util { - - -//// Settings - -Settings::Settings() : - Dirty(false) -{ - // Set up long poll handler - PollObserver.SetHandler(LongPollThread::PollFunc::FromMember<Settings, &Settings::pollDirty>(this)); - LongPollThread::GetInstance()->AddPollFunc(PollObserver); - - PushDestroyCallbacks(); -} - -Settings::~Settings() -{ - PollObserver.ReleaseAll(); - - Lock::Locker locker(&DataLock); - - if (Dirty) - { - updateFile(); - Dirty = false; - } -} - -void Settings::OnSystemDestroy() -{ - delete this; -} - -void Settings::SetFileName(const String& fileName) -{ - Lock::Locker locker(&DataLock); - - OVR_ASSERT(FullFilePath.IsEmpty()); - - if (FullFilePath.IsEmpty()) - { - FullFilePath = GetBaseOVRPath(true) + "/" + fileName; - - loadFile(); - } -} - -void Settings::loadFile() -{ - Root = *JSON::Load(FullFilePath.ToCStr()); - if (!Root) - { - OVR_DEBUG_LOG(("[Settings] Settings file was empty")); - } - else - { - OVR_DEBUG_LOG(("[Settings] Successfully read settings file")); - } -} - -void Settings::updateFile() -{ - OVR_ASSERT(!FullFilePath.IsEmpty()); - - if (Root->Save(FullFilePath.ToCStr())) - { - OVR_DEBUG_LOG(("[Settings] Updated settings file: %s", FullFilePath.ToCStr())); - Dirty = false; - } - else - { - LogError("[Settings] WARNING: Unable to write settings file: %s", FullFilePath.ToCStr()); - OVR_ASSERT(false); - } -} - -void Settings::pollDirty() -{ - // If dirty, - if (Dirty) - { - Lock::Locker locker(&DataLock); - - if (!Dirty) - { - return; - } - - updateFile(); - } -} - -void Settings::SetNumber(const char* key, double value) -{ - Lock::Locker locker(&DataLock); - - Dirty = true; - - if (!Root) - { - Root = *JSON::CreateObject(); - } - - Ptr<JSON> item = Root->GetItemByName(key); - if (!item) - { - Root->AddNumberItem(key, value); - return; - } - - item->Type = JSON_Number; - item->dValue = value; -} - -void Settings::SetInt(const char* key, int value) -{ - Lock::Locker locker(&DataLock); - - if (!Root) - { - Root = *JSON::CreateObject(); - Dirty = true; - } - - Ptr<JSON> item = Root->GetItemByName(key); - if (!item) - { - Root->AddIntItem(key, value); - Dirty = true; - return; - } - - // If the value changed, - if (item->Type != JSON_Number || - (int)item->dValue != value) - { - item->Type = JSON_Number; - item->dValue = value; - Dirty = true; - } -} - -void Settings::SetBool(const char* key, bool value) -{ - Lock::Locker locker(&DataLock); - - if (!Root) - { - Root = *JSON::CreateObject(); - Dirty = true; - } - - Ptr<JSON> item = Root->GetItemByName(key); - if (!item) - { - Root->AddBoolItem(key, value); - Dirty = true; - return; - } - - // If the value changed, - if (item->Type != JSON_Bool || - ((int)item->dValue != 0) != value) - { - item->Type = JSON_Bool; - item->dValue = value ? 1. : 0.; - item->Value = value ? "true" : "false"; - Dirty = true; - } -} - -void Settings::SetString(const char* key, const char* value) -{ - Lock::Locker locker(&DataLock); - - if (!Root) - { - Root = *JSON::CreateObject(); - Dirty = true; - } - - Ptr<JSON> item = Root->GetItemByName(key); - if (!item) - { - Root->AddStringItem(key, value); - Dirty = true; - return; - } - - // If the value changed, - if (item->Type != JSON_String || - item->Value != value) - { - item->Type = JSON_String; - item->Value = value; - Dirty = true; - } -} - -double Settings::GetNumber(const char* key, double defaultValue) -{ - Lock::Locker locker(&DataLock); - - if (!Root) - { - SetNumber(key, defaultValue); - return defaultValue; - } - - Ptr<JSON> item = Root->GetItemByName(key); - if (!item) - { - SetNumber(key, defaultValue); - return defaultValue; - } - - return item->dValue; -} - -int Settings::GetInt(const char* key, int defaultValue) -{ - Lock::Locker locker(&DataLock); - - if (!Root) - { - SetInt(key, defaultValue); - return defaultValue; - } - - Ptr<JSON> item = Root->GetItemByName(key); - if (!item) - { - SetInt(key, defaultValue); - return defaultValue; - } - - return (int)item->dValue; -} - -bool Settings::GetBool(const char* key, bool defaultValue) -{ - Lock::Locker locker(&DataLock); - - if (!Root) - { - SetBool(key, defaultValue); - return defaultValue; - } - - Ptr<JSON> item = Root->GetItemByName(key); - if (!item) - { - SetBool(key, defaultValue); - return defaultValue; - } - - return (int)item->dValue != 0; -} - -String Settings::GetString(const char* key, const char* defaultValue) -{ - Lock::Locker locker(&DataLock); - - if (!Root) - { - SetString(key, defaultValue); - return defaultValue; - } - - Ptr<JSON> item = Root->GetItemByName(key); - if (!item) - { - SetString(key, defaultValue); - return defaultValue; - } - - return item->Value; -} - - -}} // namespace OVR::Util diff --git a/LibOVR/Src/Util/Util_Settings.h b/LibOVR/Src/Util/Util_Settings.h deleted file mode 100644 index 79ea172..0000000 --- a/LibOVR/Src/Util/Util_Settings.h +++ /dev/null @@ -1,83 +0,0 @@ -/************************************************************************************ - -PublicHeader: n/a -Filename : Util_Settings.h -Content : Persistent settings subsystem -Created : June 11, 2014 -Author : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.1 - -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_Settings_h -#define OVR_Settings_h - -#include "../Kernel/OVR_String.h" -#include "../Kernel/OVR_System.h" -#include "../Kernel/OVR_Observer.h" -#include "../OVR_JSON.h" -#include "Util_LongPollThread.h" - -namespace OVR { namespace Util { - - -//----------------------------------------------------------------------------- -// Settings - -class Settings : public NewOverrideBase, public SystemSingletonBase<Settings> -{ - OVR_DECLARE_SINGLETON(Settings); - - ObserverScope<LongPollThread::PollFunc> PollObserver; - void pollDirty(); - - // Helpers (call with lock held) - void loadFile(); - void updateFile(); - - // Synchronization for data access - Lock DataLock; - - // Full path to the JSON settings file - String FullFilePath; - - // Backed by JSON - Ptr<JSON> Root; - - // Dirty flag to capture multiple changes for long poll writes - bool Dirty; - -public: - void SetFileName(const String& fileName); - - void SetNumber(const char* key, double value); - void SetInt(const char* key, int value); - void SetBool(const char* key, bool value); - void SetString(const char* key, const char* value); - - double GetNumber(const char* key, double defaultValue = 0.); - int GetInt(const char* key, int defaultValue = 0); - bool GetBool(const char* key, bool defaultValue = false); - String GetString(const char* key, const char* defaultValue = ""); -}; - - -}} // namespace OVR::Util - -#endif // OVR_Settings_h |