/* * Copyright 2010 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrStopwatch_DEFINED #define GrStopwatch_DEFINED #include "GrTypes.h" template /** * Base class for stopwatch. Relies on PLATFORM_TIMER for platform-specific * timer functions. PLATFORM_TIMER provides: * - typename TIMESTAMP : a timestamp value that can be used with Diff() * - static TIMESTAMP Now() : gets current timestamp * - static double Diff(const TIMESTAMP& begin, const TIMESTAMP& end) : * computes delta in seconds between two timestamps */ class GrStopwatchBase { public: /** * Contructor - implicit reset() */ GrStopwatchBase() { fRunning = false; fTotalElapsed = 0.0; } /** * begins a new lap */ void start() { double lastLap = lapTime(); fTotalElapsed += lastLap; fRunning = true; fLastStart = PLATFORM_TIMER::Now(); } /** * ends current lap (or no effect if lap not started) */ void stop() { double lastLap = lapTime(); fTotalElapsed += lastLap; fRunning = false; } /** * ends current lap, resets total time */ void reset() { fRunning = false; fTotalElapsed = 0.f; } /** * Computes the time of all laps since last reset() including current lap * if lap is still running. * * @return the sum time in seconds of all laps since last reset(). */ double totalTime() const { return fTotalElapsed + lapTime(); } /** * Current lap time. * * @return time in seconds of current lap if one is running otherwise 0. */ double lapTime() const { if (fRunning) { PLATFORM_TIMER::Timestamp now = PLATFORM_TIMER::Now(); return PLATFORM_TIMER::Elapsed(fLastStart, now); } return 0.0; } private: double fTotalElapsed; typename PLATFORM_TIMER::Timestamp fLastStart; bool fRunning; }; #if GR_WIN32_BUILD #include class GrWin32Timer { public: typedef LARGE_INTEGER Timestamp; static Timestamp Now() { LARGE_INTEGER now; QueryPerformanceCounter(&now); return now; } static double Elapsed(const Timestamp& begin, const Timestamp& end) { double diff = (double)(end.QuadPart - begin.QuadPart); return diff * Scale(); } private: static double Scale() { static double scale; if (0.0 == scale) { LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); GrAssert(0 != freq.QuadPart); scale = 1 / (double) freq.QuadPart; } return scale; } }; typedef GrStopwatchBase GrStopwatch; #else #error "Implement platform timer for stopwatch" #endif #endif