Add nanosecond timer.
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
diff --git a/include/core/SkTime.h b/include/core/SkTime.h
index 51616d4..c4a7d06 100644
--- a/include/core/SkTime.h
+++ b/include/core/SkTime.h
@@ -28,7 +28,9 @@
};
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)
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
index 13450cd..3a512ab 100644
--- a/include/core/SkTypes.h
+++ b/include/core/SkTypes.h
@@ -315,6 +315,10 @@
*/
#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
diff --git a/src/ports/SkTime_Unix.cpp b/src/ports/SkTime_Unix.cpp
index f519a69..cdf7f3d 100644
--- a/src/ports/SkTime_Unix.cpp
+++ b/src/ports/SkTime_Unix.cpp
@@ -12,10 +12,8 @@
#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 @@
}
}
-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
diff --git a/src/ports/SkTime_win.cpp b/src/ports/SkTime_win.cpp
index 37af9f2..a48a69e 100644
--- a/src/ports/SkTime_win.cpp
+++ b/src/ports/SkTime_win.cpp
@@ -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 @@
}
}
-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);
}
diff --git a/tools/bench_playback.cpp b/tools/bench_playback.cpp
index a5dfe50..534ad96 100644
--- a/tools/bench_playback.cpp
+++ b/tools/bench_playback.cpp
@@ -40,7 +40,7 @@
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 @@
}
}
- 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);
diff --git a/tools/bench_record.cpp b/tools/bench_record.cpp
index 63139d6..712f63a 100644
--- a/tools/bench_record.cpp
+++ b/tools/bench_record.cpp
@@ -56,7 +56,7 @@
}
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 @@
}
}
- 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);