Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/WIN32/OgreTimer.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 5.2 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30#include "OgreTimer.h"
31
32using namespace Ogre;
33
34//-------------------------------------------------------------------------
35Timer::Timer()
36{
37        reset();
38}
39
40//-------------------------------------------------------------------------
41Timer::~Timer()
42{
43}
44
45//-------------------------------------------------------------------------
46void Timer::reset()
47{
48        zeroClock = clock();
49
50    QueryPerformanceFrequency(&mFrequency);
51    QueryPerformanceCounter(&mStartTime);
52    mStartTick = GetTickCount();
53    mLastTime = 0;
54        mQueryCount = 0;
55
56    // Save the current process
57    HANDLE mProc = GetCurrentProcess();
58
59    // Get the current Affinity
60#if _MSC_VER >= 1400 && defined (_M_X64)
61        GetProcessAffinityMask(mProc, (PDWORD_PTR)&mProcMask, (PDWORD_PTR)&mSysMask);
62#else
63        GetProcessAffinityMask(mProc, &mProcMask, &mSysMask);
64#endif
65
66    mThread = GetCurrentThread();
67}
68
69//-------------------------------------------------------------------------
70unsigned long Timer::getMilliseconds()
71{
72    LARGE_INTEGER curTime;
73
74    // Set affinity to the first core
75    SetThreadAffinityMask(mThread, 1);
76
77    // Query the timer
78    QueryPerformanceCounter(&curTime);
79
80    // Reset affinity
81    SetThreadAffinityMask(mThread, mProcMask);
82
83        // Resample the frequency
84    mQueryCount++;
85    if(mQueryCount == FREQUENCY_RESAMPLE_RATE)
86    {
87        mQueryCount = 0;
88        QueryPerformanceFrequency(&mFrequency);
89    }
90
91    LONGLONG newTime = curTime.QuadPart - mStartTime.QuadPart;
92   
93    // scale by 1000 for milliseconds
94    unsigned long newTicks = (unsigned long) (1000 * newTime / mFrequency.QuadPart);
95
96    // detect and compensate for performance counter leaps
97    // (surprisingly common, see Microsoft KB: Q274323)
98    unsigned long check = GetTickCount() - mStartTick;
99    signed long msecOff = (signed long)(newTicks - check);
100    if (msecOff < -100 || msecOff > 100)
101    {
102        // We must keep the timer running forward :)
103        LONGLONG adjust = (std::min)(msecOff * mFrequency.QuadPart / 1000, newTime - mLastTime);
104        mStartTime.QuadPart += adjust;
105        newTime -= adjust;
106
107        // Re-calculate milliseconds
108        newTicks = (unsigned long) (1000 * newTime / mFrequency.QuadPart);
109    }
110
111    // Record last time for adjust
112    mLastTime = newTime;
113
114    return newTicks;
115}
116
117//-------------------------------------------------------------------------
118unsigned long Timer::getMicroseconds()
119{
120    LARGE_INTEGER curTime;
121    QueryPerformanceCounter(&curTime);
122    LONGLONG newTime = curTime.QuadPart - mStartTime.QuadPart;
123   
124    // get milliseconds to check against GetTickCount
125    unsigned long newTicks = (unsigned long) (1000 * newTime / mFrequency.QuadPart);
126   
127    // detect and compensate for performance counter leaps
128    // (surprisingly common, see Microsoft KB: Q274323)
129    unsigned long check = GetTickCount() - mStartTick;
130    signed long msecOff = (signed long)(newTicks - check);
131    if (msecOff < -100 || msecOff > 100)
132    {
133        // We must keep the timer running forward :)
134        LONGLONG adjust = (std::min)(msecOff * mFrequency.QuadPart / 1000, newTime - mLastTime);
135        mStartTime.QuadPart += adjust;
136        newTime -= adjust;
137    }
138
139    // Record last time for adjust
140    mLastTime = newTime;
141
142    // scale by 1000000 for microseconds
143    unsigned long newMicro = (unsigned long) (1000000 * newTime / mFrequency.QuadPart);
144
145    return newMicro;
146}
147
148//-------------------------------------------------------------------------
149unsigned long Timer::getMillisecondsCPU()
150{
151        clock_t newClock = clock();
152        return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ;
153}
154
155//-------------------------------------------------------------------------
156unsigned long Timer::getMicrosecondsCPU()
157{
158        clock_t newClock = clock();
159        return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ;
160}
Note: See TracBrowser for help on using the repository browser.