Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
9.2 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: To accomplish X360 TCR 22, we need to call present ever 66msec
  4. // at least during loading screens. This amazing hack will do it
  5. // by overriding the allocator to tick it every so often.
  6. //
  7. // $NoKeywords: $
  8. //===========================================================================//
  9. #include "LoadScreenUpdate.h"
  10. #include "tier0/memalloc.h"
  11. #include "tier1/delegates.h"
  12. #include "tier0/threadtools.h"
  13. #include "tier2/tier2.h"
  14. #include "materialsystem/imaterialsystem.h"
  15. #include "tier0/dbg.h"
  16. // NOTE: This has to be the last file included!
  17. #include "tier0/memdbgon.h"
  18. //-----------------------------------------------------------------------------
  19. // Used to tick the loading screen every so often
  20. //-----------------------------------------------------------------------------
  21. class CLoaderMemAlloc : public IMemAlloc
  22. {
  23. // Methods of IMemAlloc
  24. public:
  25. virtual void *Alloc( size_t nSize );
  26. virtual void *Realloc( void *pMem, size_t nSize );
  27. virtual void Free( void *pMem );
  28. DELEGATE_TO_OBJECT_2( void *, Expand_NoLongerSupported, void *, size_t, m_pMemAlloc );
  29. virtual void *Alloc( size_t nSize, const char *pFileName, int nLine );
  30. virtual void *Realloc( void *pMem, size_t nSize, const char *pFileName, int nLine );
  31. virtual void Free( void *pMem, const char *pFileName, int nLine );
  32. #ifdef MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS
  33. DELEGATE_TO_OBJECT_2( void *, AllocAlign, size_t, size_t, m_pMemAlloc );
  34. DELEGATE_TO_OBJECT_4( void *, AllocAlign, size_t, size_t, const char *, int, m_pMemAlloc );
  35. DELEGATE_TO_OBJECT_3( void *, ReallocAlign, void *, size_t, size_t, m_pMemAlloc );
  36. #endif
  37. DELEGATE_TO_OBJECT_4( void*, Expand_NoLongerSupported, void *, size_t, const char *, int, m_pMemAlloc );
  38. DELEGATE_TO_OBJECT_1( size_t, GetSize, void *, m_pMemAlloc );
  39. DELEGATE_TO_OBJECT_2V( PushAllocDbgInfo, const char *, int, m_pMemAlloc );
  40. DELEGATE_TO_OBJECT_0V( PopAllocDbgInfo, m_pMemAlloc );
  41. DELEGATE_TO_OBJECT_1( int32, CrtSetBreakAlloc, int32, m_pMemAlloc );
  42. DELEGATE_TO_OBJECT_2( int, CrtSetReportMode, int, int, m_pMemAlloc );
  43. DELEGATE_TO_OBJECT_1( int, CrtIsValidHeapPointer, const void *, m_pMemAlloc );
  44. DELEGATE_TO_OBJECT_3( int, CrtIsValidPointer, const void *, unsigned int, int, m_pMemAlloc );
  45. DELEGATE_TO_OBJECT_0( int, CrtCheckMemory, m_pMemAlloc );
  46. DELEGATE_TO_OBJECT_1( int, CrtSetDbgFlag, int, m_pMemAlloc );
  47. DELEGATE_TO_OBJECT_1V( CrtMemCheckpoint, _CrtMemState *, m_pMemAlloc );
  48. DELEGATE_TO_OBJECT_0V( DumpStats, m_pMemAlloc );
  49. DELEGATE_TO_OBJECT_2V( DumpStatsFileBase, const char *, IMemAlloc::DumpStatsFormat_t, m_pMemAlloc );
  50. DELEGATE_TO_OBJECT_1( size_t, ComputeMemoryUsedBy, const char *, m_pMemAlloc );
  51. DELEGATE_TO_OBJECT_2( void*, CrtSetReportFile, int, void*, m_pMemAlloc );
  52. DELEGATE_TO_OBJECT_1( void*, CrtSetReportHook, void*, m_pMemAlloc );
  53. DELEGATE_TO_OBJECT_5( int, CrtDbgReport, int, const char *, int, const char *, const char *, m_pMemAlloc );
  54. DELEGATE_TO_OBJECT_0( int, heapchk, m_pMemAlloc );
  55. DELEGATE_TO_OBJECT_0( bool, IsDebugHeap, m_pMemAlloc );
  56. DELEGATE_TO_OBJECT_2V( GetActualDbgInfo, const char *&, int &, m_pMemAlloc );
  57. DELEGATE_TO_OBJECT_5V( RegisterAllocation, const char *, int, size_t, size_t, unsigned, m_pMemAlloc );
  58. DELEGATE_TO_OBJECT_5V( RegisterDeallocation, const char *, int, size_t, size_t, unsigned, m_pMemAlloc );
  59. DELEGATE_TO_OBJECT_0( int, GetVersion, m_pMemAlloc );
  60. DELEGATE_TO_OBJECT_0V( CompactHeap, m_pMemAlloc );
  61. DELEGATE_TO_OBJECT_1( MemAllocFailHandler_t, SetAllocFailHandler, MemAllocFailHandler_t, m_pMemAlloc );
  62. DELEGATE_TO_OBJECT_1V( DumpBlockStats, void *, m_pMemAlloc );
  63. DELEGATE_TO_OBJECT_2V( SetStatsExtraInfo, const char *, const char *, m_pMemAlloc );
  64. DELEGATE_TO_OBJECT_0( size_t, MemoryAllocFailed, m_pMemAlloc );
  65. DELEGATE_TO_OBJECT_0V( CompactIncremental, m_pMemAlloc );
  66. DELEGATE_TO_OBJECT_1V( OutOfMemory, size_t, m_pMemAlloc );
  67. DELEGATE_TO_OBJECT_2V( GlobalMemoryStatus, size_t *, size_t *, m_pMemAlloc );
  68. DELEGATE_TO_OBJECT_1( IVirtualMemorySection *, AllocateVirtualMemorySection, size_t, m_pMemAlloc );
  69. DELEGATE_TO_OBJECT_1( int, GetGenericMemoryStats, GenericMemoryStat_t **, m_pMemAlloc );
  70. virtual uint32 GetDebugInfoSize() { return 0; }
  71. virtual void SaveDebugInfo( void *pvDebugInfo ) { }
  72. virtual void RestoreDebugInfo( const void *pvDebugInfo ) {}
  73. virtual void InitDebugInfo( void *pvDebugInfo, const char *pchRootFileName, int nLine ) {}
  74. virtual void *RegionAlloc( int region, size_t nSize );
  75. virtual void *RegionAlloc( int region, size_t nSize, const char *pFileName, int nLine );
  76. // Other public methods
  77. public:
  78. CLoaderMemAlloc();
  79. void Start( MaterialNonInteractiveMode_t mode );
  80. void Stop();
  81. void AbortDueToShutdown();
  82. void Pause( bool bPause );
  83. // Check if we need to call swap. Do so if necessary.
  84. void CheckSwap( );
  85. private:
  86. IMemAlloc *m_pMemAlloc;
  87. bool m_bPaused;
  88. };
  89. //-----------------------------------------------------------------------------
  90. // Activate, deactivate loadermemalloc
  91. //-----------------------------------------------------------------------------
  92. static bool s_bLoadingUpdatesEnabled = true;
  93. static CLoaderMemAlloc s_LoaderMemAlloc;
  94. void AbortLoadingUpdatesDueToShutdown()
  95. {
  96. if ( IsGameConsole() && s_bLoadingUpdatesEnabled )
  97. {
  98. s_LoaderMemAlloc.AbortDueToShutdown();
  99. }
  100. s_bLoadingUpdatesEnabled = false;
  101. }
  102. void BeginLoadingUpdates( MaterialNonInteractiveMode_t mode )
  103. {
  104. if ( IsGameConsole() && s_bLoadingUpdatesEnabled )
  105. {
  106. s_LoaderMemAlloc.Start( mode );
  107. }
  108. }
  109. void RefreshScreenIfNecessary()
  110. {
  111. if ( IsGameConsole() && s_bLoadingUpdatesEnabled )
  112. {
  113. s_LoaderMemAlloc.CheckSwap();
  114. }
  115. }
  116. void PauseLoadingUpdates( bool bPause )
  117. {
  118. if ( IsGameConsole() && s_bLoadingUpdatesEnabled )
  119. {
  120. s_LoaderMemAlloc.Pause( bPause );
  121. }
  122. }
  123. void EndLoadingUpdates()
  124. {
  125. if ( IsGameConsole() && s_bLoadingUpdatesEnabled )
  126. {
  127. s_LoaderMemAlloc.Stop();
  128. }
  129. }
  130. static int LoadLibraryThreadFunc()
  131. {
  132. RefreshScreenIfNecessary();
  133. return 15;
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Used to tick the loading screen every so often
  137. //-----------------------------------------------------------------------------
  138. CLoaderMemAlloc::CLoaderMemAlloc()
  139. {
  140. m_pMemAlloc = 0;
  141. m_bPaused = false;
  142. }
  143. void CLoaderMemAlloc::Start( MaterialNonInteractiveMode_t mode )
  144. {
  145. AssertFatal( ThreadInMainThread() );
  146. if ( g_pMemAlloc == this || ( mode == MATERIAL_NON_INTERACTIVE_MODE_NONE ) )
  147. return;
  148. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  149. pRenderContext->EnableNonInteractiveMode( mode );
  150. if ( mode == MATERIAL_NON_INTERACTIVE_MODE_STARTUP )
  151. {
  152. SetThreadedLoadLibraryFunc( LoadLibraryThreadFunc );
  153. }
  154. // NOTE: This is necessary to avoid a one-frame black flash
  155. // since Present is what copies the back buffer into the temp buffer
  156. if ( mode == MATERIAL_NON_INTERACTIVE_MODE_LEVEL_LOAD )
  157. {
  158. extern void V_RenderVGuiOnly( void );
  159. V_RenderVGuiOnly();
  160. }
  161. m_pMemAlloc = g_pMemAlloc;
  162. g_pMemAlloc = this;
  163. m_bPaused = false;
  164. }
  165. void CLoaderMemAlloc::Stop()
  166. {
  167. AssertFatal( ThreadInMainThread() );
  168. if ( g_pMemAlloc != this )
  169. return;
  170. g_pMemAlloc = m_pMemAlloc;
  171. m_bPaused = false;
  172. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  173. pRenderContext->EnableNonInteractiveMode( MATERIAL_NON_INTERACTIVE_MODE_NONE );
  174. SetThreadedLoadLibraryFunc( NULL );
  175. }
  176. void CLoaderMemAlloc::AbortDueToShutdown()
  177. {
  178. AssertFatal( ThreadInMainThread() );
  179. if ( g_pMemAlloc != this )
  180. return;
  181. g_pMemAlloc = m_pMemAlloc;
  182. m_bPaused = false;
  183. }
  184. void CLoaderMemAlloc::Pause( bool bPause )
  185. {
  186. if ( g_pMemAlloc != this )
  187. return;
  188. m_bPaused = bPause;
  189. }
  190. //-----------------------------------------------------------------------------
  191. // Check if we need to call swap. Do so if necessary.
  192. //-----------------------------------------------------------------------------
  193. void CLoaderMemAlloc::CheckSwap( )
  194. {
  195. if ( g_pMemAlloc != this || m_bPaused )
  196. return;
  197. g_pMaterialSystem->RefreshFrontBufferNonInteractive();
  198. }
  199. //-----------------------------------------------------------------------------
  200. // Hook allocations, render when appropriate
  201. //-----------------------------------------------------------------------------
  202. void *CLoaderMemAlloc::Alloc( size_t nSize )
  203. {
  204. CheckSwap();
  205. return m_pMemAlloc->IndirectAlloc( nSize );
  206. }
  207. void *CLoaderMemAlloc::Realloc( void *pMem, size_t nSize )
  208. {
  209. CheckSwap();
  210. return m_pMemAlloc->Realloc( pMem, nSize );
  211. }
  212. void CLoaderMemAlloc::Free( void *pMem )
  213. {
  214. CheckSwap();
  215. m_pMemAlloc->Free( pMem );
  216. }
  217. void *CLoaderMemAlloc::Alloc( size_t nSize, const char *pFileName, int nLine )
  218. {
  219. CheckSwap();
  220. return m_pMemAlloc->IndirectAlloc( nSize, pFileName, nLine );
  221. }
  222. void *CLoaderMemAlloc::Realloc( void *pMem, size_t nSize, const char *pFileName, int nLine )
  223. {
  224. CheckSwap();
  225. return m_pMemAlloc->Realloc( pMem, nSize, pFileName, nLine );
  226. }
  227. void CLoaderMemAlloc::Free( void *pMem, const char *pFileName, int nLine )
  228. {
  229. CheckSwap();
  230. m_pMemAlloc->Free( pMem, pFileName, nLine );
  231. }
  232. void *CLoaderMemAlloc::RegionAlloc( int region, size_t nSize )
  233. {
  234. CheckSwap();
  235. return m_pMemAlloc->RegionAlloc( region, nSize );
  236. }
  237. void *CLoaderMemAlloc::RegionAlloc( int region, size_t nSize, const char *pFileName, int nLine )
  238. {
  239. CheckSwap();
  240. return m_pMemAlloc->RegionAlloc( region, nSize, pFileName, nLine );
  241. }