// @(#)root/gl:$Id$
// Author:  Richard Maunder  25/05/2005

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TGLStopwatch.h"
#include "TGLIncludes.h"

#ifdef R__WIN32
#include <Windows.h>  // For GetSystemTimeAsFileTime()
#else
#include <sys/time.h> // For gettimeofday()
#endif

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGLStopwatch                                                         //
//                                                                      //
// Stopwatch object for timing GL work. We do not use the TStopwatch as //
// we need to perform GL flushing to get accurate times + we record     //
// timing overheads here.                                               //
//////////////////////////////////////////////////////////////////////////

ClassImp(TGLStopwatch);

//______________________________________________________________________________
TGLStopwatch::TGLStopwatch() : fStart(0), fEnd(0), fLastRun(0)
{
   // Construct stopwatch object.
}

//______________________________________________________________________________
TGLStopwatch::~TGLStopwatch()
{
   // Destroy stopwatch object.
}

//______________________________________________________________________________
void TGLStopwatch::Start()
{
   // Start timing.

   fStart   = GetClock();
   fEnd     = 0;
}

// In milliseconds
//______________________________________________________________________________
Double_t TGLStopwatch::Lap() const
{
   // Return lap time since Start(), in milliseconds.

   if (fStart == 0)
      return 0;
   else
      return GetClock() - fStart;
}

// In milliseconds
//______________________________________________________________________________
Double_t TGLStopwatch::End()
{
   // End timing, return total time since Start(), in milliseconds.

   if (fStart == 0)
      return 0;
   if (fEnd == 0) {
      fEnd = GetClock();
      fLastRun = fEnd - fStart;
   }
   return fLastRun;
}

//______________________________________________________________________________
Double_t TGLStopwatch::GetClock(void) const
{
   // Get internal clock time, in milliseconds.

#ifdef R__WIN32
   // Use performance counter (system dependent support) if possible
   static LARGE_INTEGER perfFreq;
   static Bool_t usePerformanceCounter = QueryPerformanceFrequency(&perfFreq);

   if (usePerformanceCounter) {
      LARGE_INTEGER counter;
      QueryPerformanceCounter(&counter);
      Double_t time = static_cast<Double_t>(counter.QuadPart)*1000.0 /
                      static_cast<Double_t>(perfFreq.QuadPart);
      return time;
   }

   // TODO: Portability - check with Rene
   FILETIME        ft;
   ULARGE_INTEGER  uli;
   __int64         t;

   GetSystemTimeAsFileTime(&ft);
   uli.LowPart  = ft.dwLowDateTime;
   uli.HighPart = ft.dwHighDateTime;
   t  = uli.QuadPart;                        // 100-nanosecond resolution
   return static_cast<Double_t>(t /= 1E4);   // Milliseconds
#else
   struct timeval tv;
   gettimeofday(&tv, 0);
   return static_cast<Double_t>(tv.tv_sec*1E3) + static_cast<Double_t>(tv.tv_usec) / 1E3;
#endif
}
 TGLStopwatch.cxx:1
 TGLStopwatch.cxx:2
 TGLStopwatch.cxx:3
 TGLStopwatch.cxx:4
 TGLStopwatch.cxx:5
 TGLStopwatch.cxx:6
 TGLStopwatch.cxx:7
 TGLStopwatch.cxx:8
 TGLStopwatch.cxx:9
 TGLStopwatch.cxx:10
 TGLStopwatch.cxx:11
 TGLStopwatch.cxx:12
 TGLStopwatch.cxx:13
 TGLStopwatch.cxx:14
 TGLStopwatch.cxx:15
 TGLStopwatch.cxx:16
 TGLStopwatch.cxx:17
 TGLStopwatch.cxx:18
 TGLStopwatch.cxx:19
 TGLStopwatch.cxx:20
 TGLStopwatch.cxx:21
 TGLStopwatch.cxx:22
 TGLStopwatch.cxx:23
 TGLStopwatch.cxx:24
 TGLStopwatch.cxx:25
 TGLStopwatch.cxx:26
 TGLStopwatch.cxx:27
 TGLStopwatch.cxx:28
 TGLStopwatch.cxx:29
 TGLStopwatch.cxx:30
 TGLStopwatch.cxx:31
 TGLStopwatch.cxx:32
 TGLStopwatch.cxx:33
 TGLStopwatch.cxx:34
 TGLStopwatch.cxx:35
 TGLStopwatch.cxx:36
 TGLStopwatch.cxx:37
 TGLStopwatch.cxx:38
 TGLStopwatch.cxx:39
 TGLStopwatch.cxx:40
 TGLStopwatch.cxx:41
 TGLStopwatch.cxx:42
 TGLStopwatch.cxx:43
 TGLStopwatch.cxx:44
 TGLStopwatch.cxx:45
 TGLStopwatch.cxx:46
 TGLStopwatch.cxx:47
 TGLStopwatch.cxx:48
 TGLStopwatch.cxx:49
 TGLStopwatch.cxx:50
 TGLStopwatch.cxx:51
 TGLStopwatch.cxx:52
 TGLStopwatch.cxx:53
 TGLStopwatch.cxx:54
 TGLStopwatch.cxx:55
 TGLStopwatch.cxx:56
 TGLStopwatch.cxx:57
 TGLStopwatch.cxx:58
 TGLStopwatch.cxx:59
 TGLStopwatch.cxx:60
 TGLStopwatch.cxx:61
 TGLStopwatch.cxx:62
 TGLStopwatch.cxx:63
 TGLStopwatch.cxx:64
 TGLStopwatch.cxx:65
 TGLStopwatch.cxx:66
 TGLStopwatch.cxx:67
 TGLStopwatch.cxx:68
 TGLStopwatch.cxx:69
 TGLStopwatch.cxx:70
 TGLStopwatch.cxx:71
 TGLStopwatch.cxx:72
 TGLStopwatch.cxx:73
 TGLStopwatch.cxx:74
 TGLStopwatch.cxx:75
 TGLStopwatch.cxx:76
 TGLStopwatch.cxx:77
 TGLStopwatch.cxx:78
 TGLStopwatch.cxx:79
 TGLStopwatch.cxx:80
 TGLStopwatch.cxx:81
 TGLStopwatch.cxx:82
 TGLStopwatch.cxx:83
 TGLStopwatch.cxx:84
 TGLStopwatch.cxx:85
 TGLStopwatch.cxx:86
 TGLStopwatch.cxx:87
 TGLStopwatch.cxx:88
 TGLStopwatch.cxx:89
 TGLStopwatch.cxx:90
 TGLStopwatch.cxx:91
 TGLStopwatch.cxx:92
 TGLStopwatch.cxx:93
 TGLStopwatch.cxx:94
 TGLStopwatch.cxx:95
 TGLStopwatch.cxx:96
 TGLStopwatch.cxx:97
 TGLStopwatch.cxx:98
 TGLStopwatch.cxx:99
 TGLStopwatch.cxx:100
 TGLStopwatch.cxx:101
 TGLStopwatch.cxx:102
 TGLStopwatch.cxx:103
 TGLStopwatch.cxx:104
 TGLStopwatch.cxx:105
 TGLStopwatch.cxx:106
 TGLStopwatch.cxx:107
 TGLStopwatch.cxx:108
 TGLStopwatch.cxx:109
 TGLStopwatch.cxx:110
 TGLStopwatch.cxx:111
 TGLStopwatch.cxx:112
 TGLStopwatch.cxx:113