1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_canvas.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "osl/time.h" 32*cdf0e10cSrcweir #include "osl/diagnose.h" 33*cdf0e10cSrcweir #include "canvas/elapsedtime.hxx" 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #if defined(WNT) 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir #if defined _MSC_VER 38*cdf0e10cSrcweir #pragma warning(push,1) 39*cdf0e10cSrcweir #endif 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir // TEMP!!! 42*cdf0e10cSrcweir // Awaiting corresponding functionality in OSL 43*cdf0e10cSrcweir // 44*cdf0e10cSrcweir #define WIN32_LEAN_AND_MEAN 45*cdf0e10cSrcweir #include <windows.h> 46*cdf0e10cSrcweir #include <winbase.h> 47*cdf0e10cSrcweir #include <mmsystem.h> 48*cdf0e10cSrcweir #endif 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir #if defined _MSC_VER 51*cdf0e10cSrcweir #pragma warning(pop) 52*cdf0e10cSrcweir #endif 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir #include <algorithm> 55*cdf0e10cSrcweir #include <limits> 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir namespace canvas { 58*cdf0e10cSrcweir namespace tools { 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir #if defined(WNT) 62*cdf0e10cSrcweir // TODO(Q2): is 0 okay for the failure case here? 63*cdf0e10cSrcweir double ElapsedTime::getSystemTime() 64*cdf0e10cSrcweir { 65*cdf0e10cSrcweir // TEMP!!! 66*cdf0e10cSrcweir // Awaiting corresponding functionality in OSL 67*cdf0e10cSrcweir // 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir // is there a performance counter available? 70*cdf0e10cSrcweir static bool bTimeSetupDone( false ); 71*cdf0e10cSrcweir static bool bPerfTimerAvailable( false ); 72*cdf0e10cSrcweir static LONGLONG nPerfCountFreq; 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir // TODO(F1): This _might_ cause problems, as it prevents correct 75*cdf0e10cSrcweir // time handling for very long lifetimes of this class's 76*cdf0e10cSrcweir // surrounding component in memory. When the difference between 77*cdf0e10cSrcweir // current sys time and nInitialCount exceeds IEEE double's 78*cdf0e10cSrcweir // mantissa, time will start to run jerky. 79*cdf0e10cSrcweir static LONGLONG nInitialCount; 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir if( !bTimeSetupDone ) 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir if( QueryPerformanceFrequency( 84*cdf0e10cSrcweir reinterpret_cast<LARGE_INTEGER *>(&nPerfCountFreq) ) ) 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir // read initial time: 87*cdf0e10cSrcweir QueryPerformanceCounter( 88*cdf0e10cSrcweir reinterpret_cast<LARGE_INTEGER *>(&nInitialCount) ); 89*cdf0e10cSrcweir bPerfTimerAvailable = true; 90*cdf0e10cSrcweir } 91*cdf0e10cSrcweir bTimeSetupDone = true; 92*cdf0e10cSrcweir } 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir if( bPerfTimerAvailable ) 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir LONGLONG nCurrCount; 97*cdf0e10cSrcweir QueryPerformanceCounter( 98*cdf0e10cSrcweir reinterpret_cast<LARGE_INTEGER *>(&nCurrCount) ); 99*cdf0e10cSrcweir nCurrCount -= nInitialCount; 100*cdf0e10cSrcweir return double(nCurrCount) / nPerfCountFreq; 101*cdf0e10cSrcweir } 102*cdf0e10cSrcweir else 103*cdf0e10cSrcweir { 104*cdf0e10cSrcweir LONGLONG nCurrTime = timeGetTime(); 105*cdf0e10cSrcweir return double(nCurrTime) / 1000.0; 106*cdf0e10cSrcweir } 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir #else // ! WNT 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir // TODO(Q2): is 0 okay for the failure case here? 112*cdf0e10cSrcweir double ElapsedTime::getSystemTime() 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir TimeValue aTimeVal; 115*cdf0e10cSrcweir if( osl_getSystemTime( &aTimeVal ) ) 116*cdf0e10cSrcweir return ((aTimeVal.Nanosec * 10e-10) + aTimeVal.Seconds); 117*cdf0e10cSrcweir else 118*cdf0e10cSrcweir return 0.0; 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir #endif 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir ElapsedTime::ElapsedTime() 124*cdf0e10cSrcweir : m_pTimeBase(), 125*cdf0e10cSrcweir m_fLastQueriedTime( 0.0 ), 126*cdf0e10cSrcweir m_fStartTime( getSystemTime() ), 127*cdf0e10cSrcweir m_fFrozenTime( 0.0 ), 128*cdf0e10cSrcweir m_bInPauseMode( false ), 129*cdf0e10cSrcweir m_bInHoldMode( false ) 130*cdf0e10cSrcweir { 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir ElapsedTime::ElapsedTime( 134*cdf0e10cSrcweir boost::shared_ptr<ElapsedTime> const & pTimeBase ) 135*cdf0e10cSrcweir : m_pTimeBase( pTimeBase ), 136*cdf0e10cSrcweir m_fLastQueriedTime( 0.0 ), 137*cdf0e10cSrcweir m_fStartTime( getCurrentTime() ), 138*cdf0e10cSrcweir m_fFrozenTime( 0.0 ), 139*cdf0e10cSrcweir m_bInPauseMode( false ), 140*cdf0e10cSrcweir m_bInHoldMode( false ) 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir boost::shared_ptr<ElapsedTime> const & ElapsedTime::getTimeBase() const 145*cdf0e10cSrcweir { 146*cdf0e10cSrcweir return m_pTimeBase; 147*cdf0e10cSrcweir } 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir void ElapsedTime::reset() 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir m_fLastQueriedTime = 0.0; 152*cdf0e10cSrcweir m_fStartTime = getCurrentTime(); 153*cdf0e10cSrcweir m_fFrozenTime = 0.0; 154*cdf0e10cSrcweir m_bInPauseMode = false; 155*cdf0e10cSrcweir m_bInHoldMode = false; 156*cdf0e10cSrcweir } 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir void ElapsedTime::adjustTimer( double fOffset, bool /*bLimitToLastQueriedTime*/ ) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir // to make getElapsedTime() become _larger_, have to reduce 161*cdf0e10cSrcweir // m_fStartTime. 162*cdf0e10cSrcweir m_fStartTime -= fOffset; 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir // also adjust frozen time, this method must _always_ affect the 165*cdf0e10cSrcweir // value returned by getElapsedTime()! 166*cdf0e10cSrcweir if (m_bInHoldMode || m_bInPauseMode) 167*cdf0e10cSrcweir m_fFrozenTime += fOffset; 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir double ElapsedTime::getCurrentTime() const 171*cdf0e10cSrcweir { 172*cdf0e10cSrcweir return m_pTimeBase.get() == 0 173*cdf0e10cSrcweir ? getSystemTime() : m_pTimeBase->getElapsedTimeImpl(); 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir double ElapsedTime::getElapsedTime() const 177*cdf0e10cSrcweir { 178*cdf0e10cSrcweir m_fLastQueriedTime = getElapsedTimeImpl(); 179*cdf0e10cSrcweir return m_fLastQueriedTime; 180*cdf0e10cSrcweir } 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir double ElapsedTime::getElapsedTimeImpl() const 183*cdf0e10cSrcweir { 184*cdf0e10cSrcweir if (m_bInHoldMode || m_bInPauseMode) 185*cdf0e10cSrcweir return m_fFrozenTime; 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir return getCurrentTime() - m_fStartTime; 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir void ElapsedTime::pauseTimer() 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir m_fFrozenTime = getElapsedTimeImpl(); 193*cdf0e10cSrcweir m_bInPauseMode = true; 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir void ElapsedTime::continueTimer() 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir m_bInPauseMode = false; 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir // stop pausing, time runs again. Note that 201*cdf0e10cSrcweir // getElapsedTimeImpl() honors hold mode, i.e. a 202*cdf0e10cSrcweir // continueTimer() in hold mode will preserve the latter 203*cdf0e10cSrcweir const double fPauseDuration( getElapsedTimeImpl() - m_fFrozenTime ); 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir // adjust start time, such that subsequent getElapsedTime() calls 206*cdf0e10cSrcweir // will virtually start from m_fFrozenTime. 207*cdf0e10cSrcweir m_fStartTime += fPauseDuration; 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir void ElapsedTime::holdTimer() 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir // when called during hold mode (e.g. more than once per time 213*cdf0e10cSrcweir // object), the original hold time will be maintained. 214*cdf0e10cSrcweir m_fFrozenTime = getElapsedTimeImpl(); 215*cdf0e10cSrcweir m_bInHoldMode = true; 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir void ElapsedTime::releaseTimer() 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir m_bInHoldMode = false; 221*cdf0e10cSrcweir } 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir } // namespace tools 224*cdf0e10cSrcweir } // namespace canvas 225