diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /engine/LoadScreenUpdate.cpp | |
| download | archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip | |
Diffstat (limited to 'engine/LoadScreenUpdate.cpp')
| -rw-r--r-- | engine/LoadScreenUpdate.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/engine/LoadScreenUpdate.cpp b/engine/LoadScreenUpdate.cpp new file mode 100644 index 0000000..6bfcd1b --- /dev/null +++ b/engine/LoadScreenUpdate.cpp @@ -0,0 +1,239 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: To accomplish X360 TCR 22, we need to call present ever 66msec +// at least during loading screens. This amazing hack will do it +// by overriding the allocator to tick it every so often. +// +// $NoKeywords: $ +//===========================================================================// + +#include "LoadScreenUpdate.h" +#include "tier0/memalloc.h" +#include "tier1/delegates.h" +#include "tier0/threadtools.h" +#include "tier2/tier2.h" +#include "materialsystem/imaterialsystem.h" +#include "tier0/dbg.h" + +#ifdef _X360 + +#define LOADING_UPDATE_INTERVAL 0.015f +#define UNINITIALIZED_LAST_TIME -1000.0f + +//----------------------------------------------------------------------------- +// Used to tick the loading screen every so often +//----------------------------------------------------------------------------- +class CLoaderMemAlloc : public IMemAlloc +{ + // Methods of IMemAlloc +public: + virtual void *Alloc( size_t nSize ); + virtual void *Realloc( void *pMem, size_t nSize ); + virtual void Free( void *pMem ); + DELEGATE_TO_OBJECT_2( void *, Expand_NoLongerSupported, void *, size_t, m_pMemAlloc ); + virtual void *Alloc( size_t nSize, const char *pFileName, int nLine ); + virtual void *Realloc( void *pMem, size_t nSize, const char *pFileName, int nLine ); + virtual void Free( void *pMem, const char *pFileName, int nLine ); + DELEGATE_TO_OBJECT_4( void*, Expand_NoLongerSupported, void *, size_t, const char *, int, m_pMemAlloc ); + DELEGATE_TO_OBJECT_1( size_t, GetSize, void *, m_pMemAlloc ); + DELEGATE_TO_OBJECT_2V( PushAllocDbgInfo, const char *, int, m_pMemAlloc ); + DELEGATE_TO_OBJECT_0V( PopAllocDbgInfo, m_pMemAlloc ); + DELEGATE_TO_OBJECT_1( long, CrtSetBreakAlloc, long, m_pMemAlloc ); + DELEGATE_TO_OBJECT_2( int, CrtSetReportMode, int, int, m_pMemAlloc ); + DELEGATE_TO_OBJECT_1( int, CrtIsValidHeapPointer, const void *, m_pMemAlloc ); + DELEGATE_TO_OBJECT_3( int, CrtIsValidPointer, const void *, unsigned int, int, m_pMemAlloc ); + DELEGATE_TO_OBJECT_0( int, CrtCheckMemory, m_pMemAlloc ); + DELEGATE_TO_OBJECT_1( int, CrtSetDbgFlag, int, m_pMemAlloc ); + DELEGATE_TO_OBJECT_1V( CrtMemCheckpoint, _CrtMemState *, m_pMemAlloc ); + DELEGATE_TO_OBJECT_0V( DumpStats, m_pMemAlloc ); + DELEGATE_TO_OBJECT_1V( DumpStatsFileBase, const char *, m_pMemAlloc ); + DELEGATE_TO_OBJECT_2( void*, CrtSetReportFile, int, void*, m_pMemAlloc ); + DELEGATE_TO_OBJECT_1( void*, CrtSetReportHook, void*, m_pMemAlloc ); + DELEGATE_TO_OBJECT_5( int, CrtDbgReport, int, const char *, int, const char *, const char *, m_pMemAlloc ); + DELEGATE_TO_OBJECT_0( int, heapchk, m_pMemAlloc ); + DELEGATE_TO_OBJECT_0( bool, IsDebugHeap, m_pMemAlloc ); + DELEGATE_TO_OBJECT_2V( GetActualDbgInfo, const char *&, int &, m_pMemAlloc ); + DELEGATE_TO_OBJECT_5V( RegisterAllocation, const char *, int, int, int, unsigned, m_pMemAlloc ); + DELEGATE_TO_OBJECT_5V( RegisterDeallocation, const char *, int, int, int, unsigned, m_pMemAlloc ); + DELEGATE_TO_OBJECT_0( int, GetVersion, m_pMemAlloc ); + DELEGATE_TO_OBJECT_0V( CompactHeap, m_pMemAlloc ); + DELEGATE_TO_OBJECT_1( MemAllocFailHandler_t, SetAllocFailHandler, MemAllocFailHandler_t, m_pMemAlloc ); + DELEGATE_TO_OBJECT_1V( DumpBlockStats, void *, m_pMemAlloc ); +#if defined( _MEMTEST ) + DELEGATE_TO_OBJECT_2V( SetStatsExtraInfo, const char *, const char *, m_pMemAlloc ); +#endif + DELEGATE_TO_OBJECT_0(size_t, MemoryAllocFailed, m_pMemAlloc ); + virtual uint32 GetDebugInfoSize() { return 0; } + virtual void SaveDebugInfo( void *pvDebugInfo ) { } + virtual void RestoreDebugInfo( const void *pvDebugInfo ) {} + virtual void InitDebugInfo( void *pvDebugInfo, const char *pchRootFileName, int nLine ) {} + + // Other public methods +public: + CLoaderMemAlloc(); + void Start( MaterialNonInteractiveMode_t mode ); + void Stop(); + + // Check if we need to call swap. Do so if necessary. + void CheckSwap( ); + +private: + IMemAlloc *m_pMemAlloc; + float m_flLastUpdateTime; + bool m_bInSwap; +}; + + +//----------------------------------------------------------------------------- +// Activate, deactivate loadermemalloc +//----------------------------------------------------------------------------- +static CLoaderMemAlloc s_LoaderMemAlloc; + +void BeginLoadingUpdates( MaterialNonInteractiveMode_t mode ) +{ + if ( IsX360() ) + { + s_LoaderMemAlloc.Start( mode ); + } +} + +void RefreshScreenIfNecessary() +{ + if ( IsX360() ) + { + s_LoaderMemAlloc.CheckSwap(); + } +} + +void EndLoadingUpdates() +{ + if ( IsX360() ) + { + s_LoaderMemAlloc.Stop(); + } +} + +static int LoadLibraryThreadFunc() +{ + RefreshScreenIfNecessary(); + return 15; +} + + +//----------------------------------------------------------------------------- +// Used to tick the loading screen every so often +//----------------------------------------------------------------------------- +CLoaderMemAlloc::CLoaderMemAlloc() +{ + m_pMemAlloc = 0; +} + +void CLoaderMemAlloc::Start( MaterialNonInteractiveMode_t mode ) +{ + if ( m_pMemAlloc || ( mode == MATERIAL_NON_INTERACTIVE_MODE_NONE ) ) + return; + + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + pRenderContext->EnableNonInteractiveMode( mode ); + + if ( mode == MATERIAL_NON_INTERACTIVE_MODE_STARTUP ) + { + SetThreadedLoadLibraryFunc( LoadLibraryThreadFunc ); + } + + // NOTE: This is necessary to avoid a one-frame black flash + // since Present is what copies the back buffer into the temp buffer + if ( mode == MATERIAL_NON_INTERACTIVE_MODE_LEVEL_LOAD ) + { + extern void V_RenderVGuiOnly( void ); + V_RenderVGuiOnly(); + } + + m_flLastUpdateTime = UNINITIALIZED_LAST_TIME; + m_bInSwap = false; + m_pMemAlloc = g_pMemAlloc; + g_pMemAlloc = this; +} + +void CLoaderMemAlloc::Stop() +{ + if ( !m_pMemAlloc ) + return; + + g_pMemAlloc = m_pMemAlloc; + m_pMemAlloc = 0; + + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + pRenderContext->EnableNonInteractiveMode( MATERIAL_NON_INTERACTIVE_MODE_NONE ); + SetThreadedLoadLibraryFunc( NULL ); +} + + +//----------------------------------------------------------------------------- +// Check if we need to call swap. Do so if necessary. +//----------------------------------------------------------------------------- +void CLoaderMemAlloc::CheckSwap( ) +{ + if ( !m_pMemAlloc ) + return; + + float t = Plat_FloatTime(); + float dt = t - m_flLastUpdateTime; + if ( dt >= LOADING_UPDATE_INTERVAL ) + { + if ( ThreadInMainThread() && !m_bInSwap && !g_pMaterialSystem->IsInFrame() ) + { + m_bInSwap = true; + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + pRenderContext->RefreshFrontBufferNonInteractive(); + m_bInSwap = false; + + // NOTE: It is necessary to re-read time, since Refresh + // may block, and if it does, it'll force a refresh every allocation + // if we don't resample time after the block + m_flLastUpdateTime = Plat_FloatTime(); + } + } +} + + +//----------------------------------------------------------------------------- +// Hook allocations, render when appropriate +//----------------------------------------------------------------------------- +void *CLoaderMemAlloc::Alloc( size_t nSize ) +{ + CheckSwap(); + return m_pMemAlloc->Alloc( nSize ); +} + +void *CLoaderMemAlloc::Realloc( void *pMem, size_t nSize ) +{ + CheckSwap(); + return m_pMemAlloc->Realloc( pMem, nSize ); +} + +void CLoaderMemAlloc::Free( void *pMem ) +{ + CheckSwap(); + m_pMemAlloc->Free( pMem ); +} + +void *CLoaderMemAlloc::Alloc( size_t nSize, const char *pFileName, int nLine ) +{ + CheckSwap(); + return m_pMemAlloc->Alloc( nSize, pFileName, nLine ); +} + +void *CLoaderMemAlloc::Realloc( void *pMem, size_t nSize, const char *pFileName, int nLine ) +{ + CheckSwap(); + return m_pMemAlloc->Realloc( pMem, nSize, pFileName, nLine ); +} + +void CLoaderMemAlloc::Free( void *pMem, const char *pFileName, int nLine ) +{ + CheckSwap(); + m_pMemAlloc->Free( pMem, pFileName, nLine ); +} + +#endif // _X360 |