Source code of Windows XP (NT5)
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.

194 lines
4.7 KiB

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include <assert.h>
  7. #include <windows.h>
  8. #include <gl\gl.h>
  9. #include <gl\glu.h>
  10. #include <gl\glaux.h>
  11. #include "mtk.h"
  12. #include "timer.hxx"
  13. /****** TIMER *******************************************************/
  14. TIMER::TIMER()
  15. {
  16. Reset();
  17. }
  18. void
  19. TIMER::Reset()
  20. {
  21. dwTotalMillis = 0;
  22. bRunning = FALSE;
  23. }
  24. void
  25. TIMER::Start()
  26. {
  27. dwStartMillis = GetTickCount();
  28. bRunning = TRUE;
  29. }
  30. float
  31. TIMER::Stop()
  32. {
  33. if( bRunning ) {
  34. // Need to stop the timer
  35. dwElapsedMillis = GetTickCount() - dwStartMillis;
  36. dwTotalMillis += dwElapsedMillis;
  37. bRunning = FALSE;
  38. }
  39. return MillisToSeconds( dwTotalMillis );
  40. }
  41. float
  42. TIMER::Elapsed()
  43. {
  44. if( !bRunning )
  45. return MillisToSeconds( dwTotalMillis );
  46. dwElapsedMillis = GetTickCount() - dwStartMillis;
  47. return MillisToSeconds( dwTotalMillis + dwElapsedMillis );
  48. }
  49. /****** UPDATE_TIMER *******************************************************/
  50. // mf: need to address how dwTotalMillis used here, and in AVG
  51. // Problem is that we effectively reset the timer on every update. This assumes
  52. // that the number of items is >> # drawn in interval. But wait, that's the way
  53. // it should be : We're measuring withing a time slice defined by the interval update, and don't want to include any previous slices. Of course, AVG_UPTDATE_TIMER *could* do this...
  54. UPDATE_TIMER::UPDATE_TIMER( float fUpdateInterval )
  55. : updateInterval( SecondsToMillis(fUpdateInterval) )
  56. {
  57. Reset();
  58. }
  59. void
  60. UPDATE_TIMER::Reset()
  61. {
  62. TIMER::Reset();
  63. nTotalItems = 0;
  64. fUpdateRate = 0.0f;
  65. }
  66. BOOL
  67. UPDATE_TIMER::Update( int numItems, float *fRate )
  68. {
  69. // Elapsed time will be total time plus current interval (if running)
  70. dwElapsedMillis = dwTotalMillis;
  71. if( bRunning ) {
  72. dwElapsedMillis += GetTickCount()-dwStartMillis;
  73. nTotalItems += numItems;
  74. }
  75. // If total elapsed time is greater than the update interval, send back
  76. // timing information
  77. if( bRunning && (dwElapsedMillis > updateInterval) )
  78. {
  79. int iNewResult;
  80. fUpdateRate = (float) nTotalItems*1000.0f/dwElapsedMillis;
  81. *fRate = fUpdateRate;
  82. // At the end of each update period, we effectively reset and restart
  83. // the timer, and set running totals back to 0
  84. Reset();
  85. Start();
  86. return TRUE;
  87. } else {
  88. *fRate = fUpdateRate; // return last calculated value to caller
  89. return FALSE; // no new information yet
  90. }
  91. }
  92. /****** AVG_UPDATE_TIMER *****************************************************/
  93. AVG_UPDATE_TIMER::AVG_UPDATE_TIMER( float fUpdateInterval, int numResults )
  94. : UPDATE_TIMER( fUpdateInterval), nMaxResults( numResults )
  95. {
  96. Reset();
  97. }
  98. void
  99. AVG_UPDATE_TIMER::Reset()
  100. {
  101. UPDATE_TIMER::Reset();
  102. nResults = 0;
  103. SS_CLAMP_TO_RANGE2( nMaxResults, 1, MAX_RESULTS );
  104. fSummedResults = 0.0f;
  105. iOldestResult = 0; // index of oldest result
  106. }
  107. BOOL
  108. AVG_UPDATE_TIMER::Update( int numItems, float *fRate )
  109. {
  110. dwElapsedMillis = dwTotalMillis;
  111. if( bRunning ) {
  112. dwElapsedMillis += GetTickCount()-dwStartMillis;
  113. nTotalItems += numItems;
  114. }
  115. // If total elapsed time is greater than the update interval, send back
  116. // timing information
  117. if( bRunning && (dwElapsedMillis > updateInterval) )
  118. {
  119. int iNewResult;
  120. float fItemsPerSecond;
  121. fItemsPerSecond = (float) nTotalItems*1000.0f/dwElapsedMillis;
  122. // Average last n results (they are kept in a circular buffer)
  123. if( nResults < nMaxResults ) {
  124. // Haven't filled the buffer yet
  125. iNewResult = nResults;
  126. nResults++;
  127. } else {
  128. // Full buffer : replace oldest entry with new value
  129. fSummedResults -= fResults[iOldestResult];
  130. iNewResult = iOldestResult;
  131. iOldestResult = (iOldestResult == (nMaxResults - 1)) ?
  132. 0 :
  133. (iOldestResult + 1);
  134. }
  135. // Add new result, maintain sum to simplify calculations
  136. fResults[iNewResult] = fItemsPerSecond;
  137. fSummedResults += fItemsPerSecond;
  138. // average the result
  139. fUpdateRate = fSummedResults / (float) nResults;
  140. *fRate = fUpdateRate;
  141. // At the end of each update period, we effectively reset and restart
  142. // the update timer, and set running totals back to 0
  143. UPDATE_TIMER::Reset();
  144. UPDATE_TIMER::Start();
  145. return TRUE;
  146. } else {
  147. *fRate = fUpdateRate; // return last calculated value to caller
  148. return FALSE; // no new information yet
  149. }
  150. }