Add nanosecond timer.
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 24 Apr 2014 20:04:20 +0000 (20:04 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 24 Apr 2014 20:04:20 +0000 (20:04 +0000)
I've been finding it hard to get enough resolution out of our existing timers when measuring really tiny pictures.

BUG=skia:2378
R=bsalomon@google.com, mtklein@google.com, bungeman@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/250243002

git-svn-id: http://skia.googlecode.com/svn/trunk@14362 2bbb7eff-a529-9590-31e7-b0007b416f81

include/core/SkTime.h
include/core/SkTypes.h
src/ports/SkTime_Unix.cpp
src/ports/SkTime_win.cpp
tools/bench_playback.cpp
tools/bench_record.cpp

index 51616d41c741f724ec365243a5aeab6d0ad26faa..c4a7d06fe33b2eda7d51c75a7ec6dfe0d03d0e36 100644 (file)
@@ -28,7 +28,9 @@ public:
     };
     static void GetDateTime(DateTime*);
 
-    static SkMSec GetMSecs();
+    static SkMSec GetMSecs() { return GetNSecs() / 1000000; }
+
+    static SkNSec GetNSecs();
 };
 
 #if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN32)
index 13450cd0117585084f6a8ca7cc7affe4a9261abf..3a512abee2d67566f96306883b872563e5bd784b 100644 (file)
@@ -315,6 +315,10 @@ typedef uint32_t SkMSec;
 */
 #define SkMSec_LE(a, b)     ((int32_t)(a) - (int32_t)(b) <= 0)
 
+/** 64 bit value to hold nanosecond count
+*/
+typedef uint64_t SkNSec;
+
 /** The generation IDs in Skia reserve 0 has an invalid marker.
  */
 #define SK_InvalidGenID     0
index f519a69d07c2843a60427ea385a5d79b11dd765c..cdf7f3d947c94c8d042a1b553ed8857eaf5acb58 100644 (file)
 #include <sys/time.h>
 #include <time.h>
 
-void SkTime::GetDateTime(DateTime* dt)
-{
-    if (dt)
-    {
+void SkTime::GetDateTime(DateTime* dt) {
+    if (dt) {
         time_t m_time;
         time(&m_time);
         struct tm* tstruct;
@@ -31,9 +29,33 @@ void SkTime::GetDateTime(DateTime* dt)
     }
 }
 
-SkMSec SkTime::GetMSecs()
-{
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    return (SkMSec) (tv.tv_sec * 1000 + tv.tv_usec / 1000 ); // microseconds to milliseconds
+#ifdef __MACH__
+#  include <mach/mach_time.h>
+
+namespace {
+
+struct ConversionFactor {
+    ConversionFactor() {
+        mach_timebase_info_data_t timebase;
+        mach_timebase_info(&timebase);
+        toNanos = (double) timebase.numer / timebase.denom;
+    }
+    double toNanos;
+};
+
+}  // namespace
+
+SkNSec SkTime::GetNSecs() {
+    static ConversionFactor convert;  // Since already know we're on Mac, this is threadsafe.
+    return mach_absolute_time() * convert.toNanos;
 }
+
+#else  // Linux, presumably all others too
+
+SkNSec SkTime::GetNSecs() {
+    struct timespec time;
+    clock_gettime(CLOCK_MONOTONIC, &time);
+    return (SkNSec)(time.tv_sec * 1000000000 + time.tv_nsec);
+}
+
+#endif
index 37af9f29f5bb2102c3ef5e44dc28c5872d4403c8..a48a69e88e81ae86330e5236feb2cdac820ea3a8 100644 (file)
@@ -9,8 +9,7 @@
 
 #include "SkTime.h"
 
-void SkTime::GetDateTime(DateTime* dt)
-{
+void SkTime::GetDateTime(DateTime* dt) {
     if (dt)
     {
         SYSTEMTIME      st;
@@ -26,13 +25,12 @@ void SkTime::GetDateTime(DateTime* dt)
     }
 }
 
-SkMSec SkTime::GetMSecs()
-{
+SkNSec SkTime::GetNSecs() {
     FILETIME        ft;
     LARGE_INTEGER   li;
     GetSystemTimeAsFileTime(&ft);
     li.LowPart  = ft.dwLowDateTime;
     li.HighPart = ft.dwHighDateTime;
     __int64 t  = li.QuadPart;       /* In 100-nanosecond intervals */
-    return (SkMSec)(t / 10000);               /* In milliseconds */
+    return (SkMSec)(t * 100);
 }
index a5dfe50973a211abf29e39640be93e245bc9cb3f..534ad9682214cb38f91a76a01a6f785d1dfc9be7 100644 (file)
@@ -40,7 +40,7 @@ static void bench(SkPMColor* scratch, SkPicture& src, const char* name) {
                                                                 src.width() * sizeof(SkPMColor)));
     canvas->clipRect(SkRect::MakeWH(SkIntToScalar(FLAGS_tile), SkIntToScalar(FLAGS_tile)));
 
-    const SkMSec start = SkTime::GetMSecs();
+    const SkNSec start = SkTime::GetNSecs();
     for (int i = 0; i < FLAGS_loops; i++) {
         if (FLAGS_skr) {
             SkRecordDraw(record, canvas.get());
@@ -49,9 +49,9 @@ static void bench(SkPMColor* scratch, SkPicture& src, const char* name) {
         }
     }
 
-    const SkMSec elapsed = SkTime::GetMSecs() - start;
-    const double msPerLoop = elapsed / (double)FLAGS_loops;
-    printf("%6.2f\t%s\n", msPerLoop, name);
+    const SkNSec elapsed = SkTime::GetNSecs() - start;
+    const double nsPerLoop = elapsed / (double)FLAGS_loops;
+    printf("%u\t%s\n", SkToUInt(nsPerLoop), name);
 }
 
 int tool_main(int argc, char** argv);
index 63139d69fd3379d2c27f53107731ae1d859696ea..712f63a6a30d5b698baef63dd02163a99cdc6cb2 100644 (file)
@@ -56,7 +56,7 @@ static SkBBHFactory* parse_FLAGS_bbh() {
 }
 
 static void bench_record(SkPicture* src, const char* name, SkBBHFactory* bbhFactory) {
-    const SkMSec start = SkTime::GetMSecs();
+    const SkNSec start = SkTime::GetNSecs();
     const int width  = src ? src->width()  : FLAGS_nullSize;
     const int height = src ? src->height() : FLAGS_nullSize;
 
@@ -80,9 +80,9 @@ static void bench_record(SkPicture* src, const char* name, SkBBHFactory* bbhFact
         }
     }
 
-    const SkMSec elapsed = SkTime::GetMSecs() - start;
-    const double msPerLoop = elapsed / (double)FLAGS_loops;
-    printf("%.2g\t%s\n", msPerLoop, name);
+    const SkNSec elapsed = SkTime::GetNSecs() - start;
+    const double nsPerLoop = elapsed / (double)FLAGS_loops;
+    printf("%u\t%s\n", SkToUInt(nsPerLoop), name);
 }
 
 int tool_main(int argc, char** argv);