oculus1

view libovr/Src/Kernel/OVR_Timer.cpp @ 29:9a973ef0e2a3

fixed the performance issue under MacOSX by replacing glutSolidTeapot (which uses glEvalMesh) with my own teapot generator.
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 27 Oct 2013 06:31:18 +0200
parents e2f9e4603129
children
line source
1 /************************************************************************************
3 Filename : OVR_Timer.cpp
4 Content : Provides static functions for precise timing
5 Created : September 19, 2012
6 Notes :
8 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
10 Use of this software is subject to the terms of the Oculus license
11 agreement provided at the time of installation or download, or which
12 otherwise accompanies this software in either electronic or hard copy form.
14 ************************************************************************************/
16 #include "OVR_Timer.h"
18 #if defined (OVR_OS_WIN32)
19 #include <windows.h>
21 #else
22 #include <sys/time.h>
23 #endif
25 namespace OVR {
27 //-----------------------------------------------------------------------------------
28 // ***** Timer Class
30 UInt64 Timer::GetProfileTicks()
31 {
32 return (GetRawTicks() * MksPerSecond) / GetRawFrequency();
33 }
34 double Timer::GetProfileSeconds()
35 {
36 static UInt64 StartTime = GetProfileTicks();
37 return TicksToSeconds(GetProfileTicks()-StartTime);
38 }
41 //------------------------------------------------------------------------
42 // *** Win32 Specific Timer
44 #if (defined (OVR_OS_WIN32))
46 CRITICAL_SECTION WinAPI_GetTimeCS;
47 volatile UInt32 WinAPI_OldTime = 0;
48 volatile UInt32 WinAPI_WrapCounter = 0;
51 UInt32 Timer::GetTicksMs()
52 {
53 return timeGetTime();
54 }
56 UInt64 Timer::GetTicks()
57 {
58 DWORD ticks = timeGetTime();
59 UInt64 result;
61 // On Win32 QueryPerformanceFrequency is unreliable due to SMP and
62 // performance levels, so use this logic to detect wrapping and track
63 // high bits.
64 ::EnterCriticalSection(&WinAPI_GetTimeCS);
66 if (WinAPI_OldTime > ticks)
67 WinAPI_WrapCounter++;
68 WinAPI_OldTime = ticks;
70 result = (UInt64(WinAPI_WrapCounter) << 32) | ticks;
71 ::LeaveCriticalSection(&WinAPI_GetTimeCS);
73 return result * MksPerMs;
74 }
76 UInt64 Timer::GetRawTicks()
77 {
78 LARGE_INTEGER li;
79 QueryPerformanceCounter(&li);
80 return li.QuadPart;
81 }
83 UInt64 Timer::GetRawFrequency()
84 {
85 static UInt64 perfFreq = 0;
86 if (perfFreq == 0)
87 {
88 LARGE_INTEGER freq;
89 QueryPerformanceFrequency(&freq);
90 perfFreq = freq.QuadPart;
91 }
92 return perfFreq;
93 }
95 void Timer::initializeTimerSystem()
96 {
97 timeBeginPeriod(1);
98 InitializeCriticalSection(&WinAPI_GetTimeCS);
100 }
101 void Timer::shutdownTimerSystem()
102 {
103 DeleteCriticalSection(&WinAPI_GetTimeCS);
104 timeEndPeriod(1);
105 }
107 #else // !OVR_OS_WIN32
110 //------------------------------------------------------------------------
111 // *** Standard OS Timer
113 UInt32 Timer::GetTicksMs()
114 {
115 return (UInt32)(GetProfileTicks() / 1000);
116 }
117 // The profile ticks implementation is just fine for a normal timer.
118 UInt64 Timer::GetTicks()
119 {
120 return GetProfileTicks();
121 }
123 void Timer::initializeTimerSystem()
124 {
125 }
126 void Timer::shutdownTimerSystem()
127 {
128 }
130 UInt64 Timer::GetRawTicks()
131 {
132 // TODO: prefer rdtsc when available?
134 // Return microseconds.
135 struct timeval tv;
136 UInt64 result;
138 gettimeofday(&tv, 0);
140 result = (UInt64)tv.tv_sec * 1000000;
141 result += tv.tv_usec;
143 return result;
144 }
146 UInt64 Timer::GetRawFrequency()
147 {
148 return MksPerSecond;
149 }
151 #endif // !OVR_OS_WIN32
155 } // OVR