Home | History | Annotate | Download | only in include
      1 /*
      2     Copyright 2010 Google Inc.
      3 
      4     Licensed under the Apache License, Version 2.0 (the "License");
      5     you may not use this file except in compliance with the License.
      6     You may obtain a copy of the License at
      7 
      8          http://www.apache.org/licenses/LICENSE-2.0
      9 
     10     Unless required by applicable law or agreed to in writing, software
     11     distributed under the License is distributed on an "AS IS" BASIS,
     12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13     See the License for the specific language governing permissions and
     14     limitations under the License.
     15  */
     16 
     17 
     18 #ifndef GrStopwatch_DEFINED
     19 #define GrStopwatch_DEFINED
     20 
     21 #include "GrTypes.h"
     22 
     23 template <typename PLATFORM_TIMER>
     24 /**
     25  * Base class for stopwatch. Relies on PLATFORM_TIMER for platform-specific
     26  * timer functions. PLATFORM_TIMER provides:
     27  *      - typename TIMESTAMP : a timestamp value that can be used with Diff()
     28  *      - static TIMESTAMP Now() : gets current timestamp
     29  *      - static double Diff(const TIMESTAMP& begin, const TIMESTAMP& end) :
     30  *           computes delta in seconds between two timestamps
     31  */
     32 class GrStopwatchBase {
     33 public:
     34     /**
     35      * Contructor - implicit reset()
     36      */
     37     GrStopwatchBase() {
     38         fRunning = false;
     39         fTotalElapsed = 0.0;
     40     }
     41 
     42     /**
     43      * begins a new lap
     44      */
     45     void start() {
     46         double lastLap = lapTime();
     47         fTotalElapsed += lastLap;
     48         fRunning = true;
     49         fLastStart = PLATFORM_TIMER::Now();
     50     }
     51 
     52     /**
     53      * ends current lap (or no effect if lap not started)
     54      */
     55     void stop() {
     56         double lastLap = lapTime();
     57         fTotalElapsed += lastLap;
     58         fRunning = false;
     59     }
     60 
     61     /**
     62      * ends current lap, resets total time
     63      */
     64     void reset() {
     65         fRunning = false;
     66         fTotalElapsed = 0.f;
     67     }
     68 
     69     /**
     70      * Computes the time of all laps since last reset() including current lap
     71      * if lap is still running.
     72      *
     73      * @return the sum time in seconds of all laps since last reset().
     74      */
     75     double totalTime() const {
     76         return fTotalElapsed + lapTime();
     77     }
     78 
     79     /**
     80      * Current lap time.
     81      *
     82      * @return time in seconds of current lap if one is running otherwise 0.
     83      */
     84     double lapTime() const {
     85         if (fRunning) {
     86             PLATFORM_TIMER::Timestamp now = PLATFORM_TIMER::Now();
     87             return PLATFORM_TIMER::Elapsed(fLastStart, now);
     88         }
     89         return 0.0;
     90     }
     91 
     92 private:
     93     double fTotalElapsed;
     94 
     95     typename PLATFORM_TIMER::Timestamp fLastStart;
     96     bool                               fRunning;
     97 };
     98 
     99 #if GR_WIN32_BUILD
    100 
    101     #include <Windows.h>
    102 
    103     class GrWin32Timer {
    104     public:
    105         typedef LARGE_INTEGER Timestamp;
    106 
    107         static Timestamp Now() {
    108             LARGE_INTEGER now;
    109             QueryPerformanceCounter(&now);
    110             return now;
    111         }
    112 
    113         static double Elapsed(const Timestamp& begin, const Timestamp& end) {
    114             double diff = (double)(end.QuadPart - begin.QuadPart);
    115             return diff * Scale();
    116         }
    117     private:
    118         static double Scale() {
    119             static double scale;
    120             if (0.0 == scale) {
    121                 LARGE_INTEGER freq;
    122                 QueryPerformanceFrequency(&freq);
    123                 GrAssert(0 != freq.QuadPart);
    124                 scale = 1 / (double) freq.QuadPart;
    125             }
    126             return scale;
    127         }
    128     };
    129     typedef GrStopwatchBase<GrWin32Timer> GrStopwatch;
    130 #else
    131     #error "Implement platform timer for stopwatch"
    132 #endif
    133 
    134 
    135 #endif
    136