From 763222b571de1d48ebae50d96ff57d14e954e984 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Tue, 14 Nov 2017 15:52:54 -0500 Subject: [PATCH] - fixed: high uptime was causing overloads in uint32_t and float structures (float losing loss of precision) - this caused any computer online for more than a few days to experience jankiness with internal animations such as rotations and shader timers. Unfortunately, this sounds the death knell for 32-bit platforms, since uint64_t is now required in time-critical structures, which will hurt performance tremendeously, but 64-bit systems will be unaffected. --- src/gl/models/gl_models.cpp | 10 +++++----- src/gl/renderer/gl_renderstate.cpp | 6 +++++- src/gl/scene/gl_scene.cpp | 4 ++-- src/i_time.cpp | 6 +++--- src/i_time.h | 2 +- src/v_video.h | 2 +- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 541a4c36c1..963518a991 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -53,9 +53,9 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/shaders/gl_shader.h" -static inline float GetTimeFloat() +static inline double GetTimeFloat() { - return (float)screen->FrameTime * (float)TICRATE / 1000.0f; + return (double)screen->FrameTime * (double)TICRATE / 1000.; } CVAR(Bool, gl_interpolate_model_frames, true, CVAR_ARCHIVE) @@ -890,7 +890,7 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf, // [BB] In case the tic counter is frozen we have to leave ticFraction at zero. if ( ConsoleState == c_up && menuactive != MENU_On && !(level.flags2 & LEVEL2_FROZEN) ) { - float time = GetTimeFloat(); + double time = GetTimeFloat(); ticFraction = (time - static_cast(time)); } inter = static_cast(curState->Tics - curTics - ticFraction)/static_cast(curState->Tics); @@ -999,8 +999,8 @@ void gl_RenderModel(GLSprite * spr) if( smf->flags & MDL_ROTATING ) { - const float time = smf->rotationSpeed*GetTimeFloat()/200.f; - rotateOffset = float((time - xs_FloorToInt(time)) *360.f ); + const double time = smf->rotationSpeed*GetTimeFloat()/200.; + rotateOffset = double((time - xs_FloorToInt(time)) *360. ); } // Added MDL_USEACTORPITCH and MDL_USEACTORROLL flags processing. diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 1427e23501..5385e4ae37 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -118,6 +118,10 @@ void FRenderState::Reset() bool FRenderState::ApplyShader() { + static int firstFrame = 0; + if (firstFrame == 0) + firstFrame = screen->FrameTime; + static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f }; if (mSpecialEffect > EFF_NONE) { @@ -161,7 +165,7 @@ bool FRenderState::ApplyShader() activeShader->muInterpolationFactor.Set(mInterpolationFactor); activeShader->muClipHeight.Set(mClipHeight); activeShader->muClipHeightDirection.Set(mClipHeightDirection); - activeShader->muTimer.Set(screen->FrameTime * mShaderTimer / 1000.f); + activeShader->muTimer.Set((double)(screen->FrameTime - firstFrame) * mShaderTimer / 1000.f); activeShader->muAlphaThreshold.Set(mAlphaThreshold); activeShader->muLightIndex.Set(mLightIndex); // will always be -1 for now activeShader->muClipSplit.Set(mClipSplit); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 92d3785213..329ac64840 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -800,8 +800,8 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f GLRenderer->mAngles.Roll.Degrees = r_viewpoint.Angles.Roll.Degrees; // Scroll the sky - GLRenderer->mSky1Pos = (float)fmod(screen->FrameTime * level.skyspeed1, 1024.f) * 90.f/256.f; - GLRenderer->mSky2Pos = (float)fmod(screen->FrameTime * level.skyspeed2, 1024.f) * 90.f/256.f; + GLRenderer->mSky1Pos = (double)fmod(screen->FrameTime * level.skyspeed1, 1024.f) * 90./256.; + GLRenderer->mSky2Pos = (double)fmod(screen->FrameTime * level.skyspeed2, 1024.f) * 90./256.; diff --git a/src/i_time.cpp b/src/i_time.cpp index 050bb1ebc9..4be0a8b826 100644 --- a/src/i_time.cpp +++ b/src/i_time.cpp @@ -60,9 +60,9 @@ static uint64_t MSToNS(unsigned int ms) return static_cast(ms) * 1'000'000; } -static uint32_t NSToMS(uint64_t ns) +static uint64_t NSToMS(uint64_t ns) { - return static_cast(ns / 1'000'000); + return static_cast(ns / 1'000'000); } static int NSToTic(uint64_t ns) @@ -125,7 +125,7 @@ uint64_t I_nsTime() return GetClockTimeNS(); } -unsigned int I_msTime() +uint64_t I_msTime() { return NSToMS(I_nsTime()); } diff --git a/src/i_time.h b/src/i_time.h index 1605969698..33907ded2a 100644 --- a/src/i_time.h +++ b/src/i_time.h @@ -20,7 +20,7 @@ int I_WaitForTic(int); void I_FreezeTime(bool frozen); // [RH] Returns millisecond-accurate time -unsigned int I_msTime(); +uint64_t I_msTime(); // Nanosecond-accurate time uint64_t I_nsTime(); diff --git a/src/v_video.h b/src/v_video.h index 5934a3706a..4fae94198e 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -453,7 +453,7 @@ public: // The original size of the framebuffer as selected in the video menu. int VideoWidth = 0; int VideoHeight = 0; - uint32_t FrameTime = 0; + uint64_t FrameTime = 0; protected: void DrawRateStuff ();