]> git.cworth.org Git - vogl/blob - src/voglcore/vogl_timer.cpp
Initial vogl checkin
[vogl] / src / voglcore / vogl_timer.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 // File: vogl_timer.cpp
28 #include "vogl_core.h"
29 #include "vogl_timer.h"
30 #include <time.h>
31
32 #include "vogl_timer.h"
33
34 #ifdef VOGL_USE_WIN32_API
35 #include "vogl_winhdr.h"
36 #endif
37
38 namespace vogl
39 {
40     uint64_t timer::g_init_ticks;
41     uint64_t timer::g_freq;
42     double timer::g_inv_freq;
43
44 #if defined(VOGL_USE_WIN32_API)
45     inline void query_counter(timer_ticks *pTicks)
46     {
47         QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(pTicks));
48     }
49     inline void query_counter_frequency(timer_ticks *pTicks)
50     {
51         QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER *>(pTicks));
52     }
53 #elif defined(__GNUC__)
54 #include <sys/timex.h>
55     inline void query_counter(timer_ticks *pTicks)
56     {
57         struct timeval cur_time;
58         gettimeofday(&cur_time, NULL);
59         *pTicks = static_cast<unsigned long long>(cur_time.tv_sec) * 1000000ULL + static_cast<unsigned long long>(cur_time.tv_usec);
60     }
61     inline void query_counter_frequency(timer_ticks *pTicks)
62     {
63         *pTicks = 1000000;
64     }
65 #else
66 #error Unimplemented
67 #endif
68
69     timer::timer()
70         : m_start_time(0),
71           m_stop_time(0),
72           m_started(false),
73           m_stopped(false)
74     {
75         if (!g_inv_freq)
76             init();
77     }
78
79     timer::timer(timer_ticks start_ticks)
80     {
81         if (!g_inv_freq)
82             init();
83
84         m_start_time = start_ticks;
85
86         m_started = true;
87         m_stopped = false;
88     }
89
90     void timer::start(timer_ticks start_ticks)
91     {
92         m_start_time = start_ticks;
93
94         m_started = true;
95         m_stopped = false;
96     }
97
98     void timer::start()
99     {
100         query_counter(&m_start_time);
101
102         m_started = true;
103         m_stopped = false;
104     }
105
106     void timer::stop()
107     {
108         VOGL_ASSERT(m_started);
109
110         query_counter(&m_stop_time);
111
112         m_stopped = true;
113     }
114
115     double timer::get_elapsed_secs() const
116     {
117         VOGL_ASSERT(m_started);
118         if (!m_started)
119             return 0;
120
121         timer_ticks stop_time = m_stop_time;
122         if (!m_stopped)
123             query_counter(&stop_time);
124
125         timer_ticks delta = stop_time - m_start_time;
126         return delta * g_inv_freq;
127     }
128
129     timer_ticks timer::get_elapsed_us() const
130     {
131         VOGL_ASSERT(m_started);
132         if (!m_started)
133             return 0;
134
135         timer_ticks stop_time = m_stop_time;
136         if (!m_stopped)
137             query_counter(&stop_time);
138
139         timer_ticks delta = stop_time - m_start_time;
140         return (delta * 1000000ULL + (g_freq >> 1U)) / g_freq;
141     }
142
143     timer_ticks timer::get_elapsed_ticks() const
144     {
145         VOGL_ASSERT(m_started);
146         if (!m_started)
147             return 0;
148
149         timer_ticks stop_time = m_stop_time;
150         if (!m_stopped)
151             query_counter(&stop_time);
152
153         return stop_time - m_start_time;
154     }
155
156     void timer::init()
157     {
158         if (!g_inv_freq)
159         {
160             query_counter_frequency(&g_freq);
161             g_inv_freq = 1.0f / g_freq;
162
163             query_counter(&g_init_ticks);
164         }
165     }
166
167     timer_ticks timer::get_init_ticks()
168     {
169         if (!g_inv_freq)
170             init();
171
172         return g_init_ticks;
173     }
174
175     timer_ticks timer::get_ticks()
176     {
177         if (!g_inv_freq)
178             init();
179
180         timer_ticks ticks;
181         query_counter(&ticks);
182         return ticks - g_init_ticks;
183     }
184
185     double timer::ticks_to_secs(timer_ticks ticks)
186     {
187         if (!g_inv_freq)
188             init();
189
190         return ticks * g_inv_freq;
191     }
192
193 } // namespace vogl