From ec4d4d784dbb250e572f8e04d18d0fd2ebeee851 Mon Sep 17 00:00:00 2001 From: benjaminwagner Date: Fri, 25 Mar 2016 12:59:53 -0700 Subject: Change SkTime::GetMSecs to double; ensure values stored in SkMSec do not overflow. The following are currently unused in Android, Google3, Chromium, and Mozilla: - SkEvent - SkTime::GetMSecs - SK_TIME_FACTOR (also unused in Skia) - SkAutoTime I left uses of SkMSec more-or-less intact for SkEvent, SkAnimator, and SkInterpolator. SkInterpolator is used in Chromium, so I did not want to change the API. The views/ and animator/ code is crufty, so it didn't seem worthwhile to refactor it. Instead, I added SkEvent::GetMSecsSinceStartup, which is likely to be adequate for use in SampleApp. I also left SkMSec where it is used to measure a duration rather than a timestamp. With the exception of SkMovie, which is used in Android, all of the uses appear to measure the execution time of a piece of code, which I would hope does not exceed 2^31 milliseconds. Added skiatest::Timer to support a common idiom in tests where we want to measure the wallclock time in integer milliseconds. (Not used in tests/PathOpsSkpClipTest.cpp because it redefines things in Test.h.) Removed tabs in tests/StrokerTest.cpp. BUG=skia:4632 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1811613004 Review URL: https://codereview.chromium.org/1811613004 --- dm/DM.cpp | 2 +- gm/SkAnimTimer.h | 31 +++++---- include/animator/SkAnimator.h | 3 +- include/core/SkTime.h | 25 +++---- include/core/SkTypes.h | 8 ++- include/views/SkEvent.h | 9 ++- include/views/SkTouchGesture.h | 4 +- samplecode/SampleClipDrawMatch.cpp | 17 +++-- src/animator/SkAnimateMaker.cpp | 2 +- src/pdf/SkPDFMetadata.cpp | 2 +- src/views/SkEvent.cpp | 11 ++- src/views/SkTouchGesture.cpp | 15 ++-- tests/PathOpsSkpClipTest.cpp | 16 ++--- tests/SkpSkGrTest.cpp | 12 ++-- tests/StrokerTest.cpp | 137 +++++++++++++++++++------------------ tests/Test.cpp | 14 ++++ tests/Test.h | 21 ++++++ tests/skia_test.cpp | 4 +- 18 files changed, 196 insertions(+), 137 deletions(-) diff --git a/dm/DM.cpp b/dm/DM.cpp index ce3a1aa77e..34f8a961e3 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -73,7 +73,7 @@ using namespace DM; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ -static const SkMSec kStartMs = SkTime::GetMSecs(); +static const double kStartMs = SkTime::GetMSecs(); static FILE* gVLog; diff --git a/gm/SkAnimTimer.h b/gm/SkAnimTimer.h index 725171a8fe..2c8a723e5b 100644 --- a/gm/SkAnimTimer.h +++ b/gm/SkAnimTimer.h @@ -29,7 +29,7 @@ public: /** * Class begins in the "stopped" state. */ - SkAnimTimer() : fBaseTime(0), fCurrTime(0), fState(kStopped_State) {} + SkAnimTimer() : fBaseTimeNanos(0), fCurrTimeNanos(0), fState(kStopped_State) {} bool isStopped() const { return kStopped_State == fState; } bool isRunning() const { return kRunning_State == fState; } @@ -70,23 +70,26 @@ public: */ void updateTime() { if (kRunning_State == fState) { - fCurrTime = SkTime::GetMSecs(); + fCurrTimeNanos = SkTime::GetNSecs(); } } /** * Return the time in milliseconds the timer has been in the running state. - * Returns 0 if the timer is stopped. + * Returns 0 if the timer is stopped. Behavior is undefined if the timer + * has been running longer than SK_MSecMax. */ - SkMSec msec() const { return fCurrTime - fBaseTime; } + SkMSec msec() const { + const double msec = (fCurrTimeNanos - fBaseTimeNanos) * 1e-6; + SkASSERT(SK_MSecMax >= msec); + return static_cast(msec); + } /** * Return the time in seconds the timer has been in the running state. * Returns 0 if the timer is stopped. */ - double secs() const { - return this->msec() * 0.001; - } + double secs() const { return (fCurrTimeNanos - fBaseTimeNanos) * 1e-9; } /** * Return the time in seconds the timer has been in the running state, @@ -102,14 +105,14 @@ public: } private: - SkMSec fBaseTime; - SkMSec fCurrTime; + double fBaseTimeNanos; + double fCurrTimeNanos; State fState; void setState(State newState) { switch (newState) { case kStopped_State: - fBaseTime = fCurrTime = 0; + fBaseTimeNanos = fCurrTimeNanos = 0; fState = kStopped_State; break; case kPaused_State: @@ -120,12 +123,12 @@ private: case kRunning_State: switch (fState) { case kStopped_State: - fBaseTime = fCurrTime = SkTime::GetMSecs(); + fBaseTimeNanos = fCurrTimeNanos = SkTime::GetNSecs(); break; case kPaused_State: {// they want "resume" - SkMSec now = SkTime::GetMSecs(); - fBaseTime += now - fCurrTime; - fCurrTime = now; + double now = SkTime::GetNSecs(); + fBaseTimeNanos += now - fCurrTimeNanos; + fCurrTimeNanos = now; } break; case kRunning_State: break; diff --git a/include/animator/SkAnimator.h b/include/animator/SkAnimator.h index 9bb3642ca0..0fe787c526 100644 --- a/include/animator/SkAnimator.h +++ b/include/animator/SkAnimator.h @@ -443,7 +443,8 @@ public: }; /** Sets a user class to return the current time to the animator. - Optional; if not called, the system clock will be used by calling SkTime::GetMSecs instead. + Optional; if not called, the system clock will be used by calling + SkEvent::GetMSecsSinceStartup instead. @param callBack the time function */ void setTimeline(const Timeline& ); diff --git a/include/core/SkTime.h b/include/core/SkTime.h index 3ff29aa25e..8a8224a82a 100644 --- a/include/core/SkTime.h +++ b/include/core/SkTime.h @@ -34,34 +34,27 @@ public: }; static void GetDateTime(DateTime*); - static SkMSec GetMSecs() { return (SkMSec)(GetNSecs() * 1e-6); } + static double GetSecs() { return GetNSecs() * 1e-9; } + static double GetMSecs() { return GetNSecs() * 1e-6; } static double GetNSecs(); }; -#define SK_TIME_FACTOR 1 - /////////////////////////////////////////////////////////////////////////////// class SkAutoTime { public: // The label is not deep-copied, so its address must remain valid for the // lifetime of this object - SkAutoTime(const char* label = NULL, SkMSec minToDump = 0) : fLabel(label) - { - fNow = SkTime::GetMSecs(); - fMinToDump = minToDump; - } - ~SkAutoTime() - { - SkMSec dur = SkTime::GetMSecs() - fNow; - if (dur >= fMinToDump) { - SkDebugf("%s %d\n", fLabel ? fLabel : "", dur); - } + SkAutoTime(const char* label = nullptr) + : fLabel(label) + , fNow(SkTime::GetMSecs()) {} + ~SkAutoTime() { + uint64_t dur = static_cast(SkTime::GetMSecs() - fNow); + SkDebugf("%s %ld\n", fLabel ? fLabel : "", dur); } private: const char* fLabel; - SkMSec fNow; - SkMSec fMinToDump; + double fNow; }; #define SkAutoTime(...) SK_REQUIRE_LOCAL_VAR(SkAutoTime) diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h index d7a791163b..a94a59233f 100644 --- a/include/core/SkTypes.h +++ b/include/core/SkTypes.h @@ -342,13 +342,15 @@ typedef uint32_t SkFourByteTag; /** 32 bit integer to hold a unicode value */ typedef int32_t SkUnichar; -/** 32 bit value to hold a millisecond count -*/ + +/** 32 bit value to hold a millisecond duration + * Note that SK_MSecMax is about 25 days. + */ typedef uint32_t SkMSec; /** 1 second measured in milliseconds */ #define SK_MSec1 1000 -/** maximum representable milliseconds +/** maximum representable milliseconds; 24d 20h 31m 23.647s. */ #define SK_MSecMax 0x7FFFFFFF /** Returns a < b for milliseconds, correctly handling wrap-around from 0xFFFFFFFF to 0 diff --git a/include/views/SkEvent.h b/include/views/SkEvent.h index 0af76fe686..b8fc00ef51 100644 --- a/include/views/SkEvent.h +++ b/include/views/SkEvent.h @@ -206,13 +206,20 @@ public: /** * Post to the event queue using the event's targetID or target-proc. * The event will be delivered no sooner than the specified millisecond - * time, as measured by SkTime::GetMSecs(). + * time, as measured by GetMSecsSinceStartup(). * * The event must be dynamically allocated, as ownership is transferred to * the event queue. It cannot be allocated on the stack or in a global. */ void postTime(SkMSec time); + /** + * Returns ~zero the first time it's called, then returns the number of + * milliseconds since the first call. Behavior is undefined if the program + * runs more than ~25 days. + */ + static SkMSec GetMSecsSinceStartup(); + /////////////////////////////////////////////// /** Porting layer must call these functions **/ /////////////////////////////////////////////// diff --git a/include/views/SkTouchGesture.h b/include/views/SkTouchGesture.h index 4a03065e25..60487c7a2f 100644 --- a/include/views/SkTouchGesture.h +++ b/include/views/SkTouchGesture.h @@ -55,14 +55,14 @@ private: float fStartX, fStartY; float fPrevX, fPrevY; float fLastX, fLastY; - SkMSec fPrevT, fLastT; + float fPrevT, fLastT; }; SkTDArray fTouches; State fState; SkMatrix fLocalM, fGlobalM; SkFlingState fFlinger; - SkMSec fLastUpT; + double fLastUpMillis; SkPoint fLastUpP; diff --git a/samplecode/SampleClipDrawMatch.cpp b/samplecode/SampleClipDrawMatch.cpp index 502f34946b..45663b5018 100644 --- a/samplecode/SampleClipDrawMatch.cpp +++ b/samplecode/SampleClipDrawMatch.cpp @@ -121,15 +121,15 @@ public: fTrans.setRepeatCount(999); values[0] = values[1] = 0; - fTrans.setKeyFrame(0, SkTime::GetMSecs() + 1000, values); + fTrans.setKeyFrame(0, GetMSecs() + 1000, values); values[1] = 1; - fTrans.setKeyFrame(1, SkTime::GetMSecs() + 2000, values); + fTrans.setKeyFrame(1, GetMSecs() + 2000, values); values[0] = values[1] = 1; - fTrans.setKeyFrame(2, SkTime::GetMSecs() + 3000, values); + fTrans.setKeyFrame(2, GetMSecs() + 3000, values); values[1] = 0; - fTrans.setKeyFrame(3, SkTime::GetMSecs() + 4000, values); + fTrans.setKeyFrame(3, GetMSecs() + 4000, values); values[0] = 0; - fTrans.setKeyFrame(4, SkTime::GetMSecs() + 5000, values); + fTrans.setKeyFrame(4, GetMSecs() + 5000, values); } protected: @@ -231,7 +231,7 @@ protected: void onDrawContent(SkCanvas* canvas) override { SkScalar trans[2]; - fTrans.timeToValues(SkTime::GetMSecs(), trans); + fTrans.timeToValues(GetMSecs(), trans); SkPoint offset; offset.set(trans[0], trans[1]); @@ -243,11 +243,16 @@ protected: this->inval(nullptr); } + SkMSec GetMSecs() const { + return static_cast(SkTime::GetMSecs() - fStart); + } + private: SkInterpolator fTrans; Geometry fGeom; bool fClipFirst; int fSign; + const double fStart = SkTime::GetMSecs(); typedef SampleView INHERITED; }; diff --git a/src/animator/SkAnimateMaker.cpp b/src/animator/SkAnimateMaker.cpp index 0c28c7bd57..5186da04d8 100644 --- a/src/animator/SkAnimateMaker.cpp +++ b/src/animator/SkAnimateMaker.cpp @@ -23,7 +23,7 @@ class DefaultTimeline : public SkAnimator::Timeline { virtual SkMSec getMSecs() const { - return SkTime::GetMSecs(); + return SkEvent::GetMSecsSinceStartup(); } } gDefaultTimeline; diff --git a/src/pdf/SkPDFMetadata.cpp b/src/pdf/SkPDFMetadata.cpp index 5e8c124d7b..118cda39fe 100644 --- a/src/pdf/SkPDFMetadata.cpp +++ b/src/pdf/SkPDFMetadata.cpp @@ -55,7 +55,7 @@ SkPDFMetadata::UUID SkPDFMetadata::uuid() const { SkMD5 md5; const char uuidNamespace[] = "org.skia.pdf\n"; md5.write(uuidNamespace, strlen(uuidNamespace)); - SkMSec msec = SkTime::GetMSecs(); + double msec = SkTime::GetMSecs(); md5.write(&msec, sizeof(msec)); SkTime::DateTime dateTime; SkTime::GetDateTime(&dateTime); diff --git a/src/views/SkEvent.cpp b/src/views/SkEvent.cpp index 5316b49a1d..b90d03f3d0 100644 --- a/src/views/SkEvent.cpp +++ b/src/views/SkEvent.cpp @@ -298,7 +298,7 @@ void SkEvent::postDelay(SkMSec delay) { } if (delay) { - this->postTime(SkTime::GetMSecs() + delay); + this->postTime(GetMSecsSinceStartup() + delay); return; } @@ -404,7 +404,7 @@ SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time) { prev->fNextEvent = evt; } - SkMSec delay = globals.fDelayQHead->fTime - SkTime::GetMSecs(); + SkMSec delay = globals.fDelayQHead->fTime - GetMSecsSinceStartup(); if ((int32_t)delay <= 0) { delay = 1; } @@ -436,7 +436,7 @@ void SkEvent::ServiceQueueTimer() globals.fEventMutex.acquire(); bool wasEmpty = false; - SkMSec now = SkTime::GetMSecs(); + SkMSec now = GetMSecsSinceStartup(); SkEvent* evt = globals.fDelayQHead; while (evt) @@ -485,6 +485,11 @@ int SkEvent::CountEventsOnQueue() { return count; } +SkMSec SkEvent::GetMSecsSinceStartup() { + static const double kEpoch = SkTime::GetMSecs(); + return static_cast(SkTime::GetMSecs() - kEpoch); +} + /////////////////////////////////////////////////////////////////////////////// void SkEvent::Init() {} diff --git a/src/views/SkTouchGesture.cpp b/src/views/SkTouchGesture.cpp index 22c9434216..676f8e9a64 100644 --- a/src/views/SkTouchGesture.cpp +++ b/src/views/SkTouchGesture.cpp @@ -115,7 +115,7 @@ void SkTouchGesture::reset() { fLocalM.reset(); fGlobalM.reset(); - fLastUpT = SkTime::GetMSecs() - 2*MAX_DBL_TAP_INTERVAL; + fLastUpMillis = SkTime::GetMSecs() - 2*MAX_DBL_TAP_INTERVAL; fLastUpP.set(0, 0); } @@ -138,7 +138,7 @@ void SkTouchGesture::appendNewRec(void* owner, float x, float y) { rec->fOwner = owner; rec->fStartX = rec->fPrevX = rec->fLastX = x; rec->fStartY = rec->fPrevY = rec->fLastY = y; - rec->fLastT = rec->fPrevT = SkTime::GetMSecs(); + rec->fLastT = rec->fPrevT = static_cast(SkTime::GetSecs()); } void SkTouchGesture::touchBegin(void* owner, float x, float y) { @@ -227,7 +227,8 @@ void SkTouchGesture::touchMoved(void* owner, float x, float y) { rec.fPrevX = rec.fLastX; rec.fLastX = x; rec.fPrevY = rec.fLastY; rec.fLastY = y; - rec.fPrevT = rec.fLastT; rec.fLastT = SkTime::GetMSecs(); + rec.fPrevT = rec.fLastT; + rec.fLastT = static_cast(SkTime::GetSecs()); switch (fTouches.count()) { case 1: { @@ -276,7 +277,7 @@ void SkTouchGesture::touchEnd(void* owner) { this->flushLocalM(); float dx = rec.fLastX - rec.fPrevX; float dy = rec.fLastY - rec.fPrevY; - float dur = (rec.fLastT - rec.fPrevT) * 0.001f; + float dur = rec.fLastT - rec.fPrevT; if (dur > 0) { fFlinger.reset(dx / dur, dy / dur); } @@ -310,8 +311,8 @@ float SkTouchGesture::computePinch(const Rec& rec0, const Rec& rec1) { bool SkTouchGesture::handleDblTap(float x, float y) { bool found = false; - SkMSec now = SkTime::GetMSecs(); - if (now - fLastUpT <= MAX_DBL_TAP_INTERVAL) { + double now = SkTime::GetMSecs(); + if (now - fLastUpMillis <= MAX_DBL_TAP_INTERVAL) { if (SkPoint::Length(fLastUpP.fX - x, fLastUpP.fY - y) <= MAX_DBL_TAP_DISTANCE) { fFlinger.stop(); @@ -323,7 +324,7 @@ bool SkTouchGesture::handleDblTap(float x, float y) { } } - fLastUpT = now; + fLastUpMillis = now; fLastUpP.set(x, y); return found; } diff --git a/tests/PathOpsSkpClipTest.cpp b/tests/PathOpsSkpClipTest.cpp index d11f8e0634..b5fd58d3d5 100644 --- a/tests/PathOpsSkpClipTest.cpp +++ b/tests/PathOpsSkpClipTest.cpp @@ -215,7 +215,7 @@ struct TestResult { TestStep fTestStep; int fDirNo; int fPixelError; - int fTime; + SkMSec fTime; int fScale; }; @@ -372,7 +372,7 @@ static bool addError(TestState* data, const TestResult& testResult) { } } int slowCount = data->fSlowest.count(); - int time = testResult.fTime; + SkMSec time = testResult.fTime; if (time > 0) { for (int index = 0; index < slowCount; ++index) { if (time > data->fSlowest[index].fTime) { @@ -402,7 +402,7 @@ static SkMSec timePict(SkPicture* pic, SkCanvas* canvas) { SkScalar yInterval = SkTMax(pHeight - maxDimension, 0.0f) / (slices - 1); SkRect rect = {0, 0, SkTMin(maxDimension, pWidth), SkTMin(maxDimension, pHeight) }; canvas->clipRect(rect); - SkMSec start = SkTime::GetMSecs(); + double start = SkTime::GetMSecs(); for (int x = 0; x < slices; ++x) { for (int y = 0; y < slices; ++y) { pic->playback(canvas); @@ -410,9 +410,9 @@ static SkMSec timePict(SkPicture* pic, SkCanvas* canvas) { } canvas->translate(xInterval, -yInterval * slices); } - SkMSec end = SkTime::GetMSecs(); + double end = SkTime::GetMSecs(); canvas->restore(); - return end - start; + return static_cast(end - start); } static void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) { @@ -502,9 +502,9 @@ void TestResult::testOne() { drawPict(pic.get(), &opCanvas, fScale); if (fTestStep == kCompareBits) { fPixelError = similarBits(oldBitmap, opBitmap); - int oldTime = timePict(pic.get(), &oldCanvas); - int opTime = timePict(pic.get(), &opCanvas); - fTime = SkTMax(0, oldTime - opTime); + SkMSec oldTime = timePict(pic.get(), &oldCanvas); + SkMSec opTime = timePict(pic.get(), &opCanvas); + fTime = SkTMax(static_cast(0), oldTime - opTime); } else if (fTestStep == kEncodeFiles) { SkString pngStr = make_png_name(fFilename); const char* pngName = pngStr.c_str(); diff --git a/tests/SkpSkGrTest.cpp b/tests/SkpSkGrTest.cpp index 23bec84b8f..4469d4fb57 100644 --- a/tests/SkpSkGrTest.cpp +++ b/tests/SkpSkGrTest.cpp @@ -106,7 +106,7 @@ struct TestResult { TestStep fTestStep; int fDirNo; int fPixelError; - int fTime; + SkMSec fTime; bool fScaleOversized; }; @@ -343,7 +343,7 @@ static SkMSec timePict(SkPicture* pic, SkCanvas* canvas) { SkRect rect = {0, 0, SkIntToScalar(SkTMin(maxDimension, pWidth)), SkIntToScalar(SkTMin(maxDimension, pHeight))}; canvas->clipRect(rect); - SkMSec start = SkTime::GetMSecs(); + skiatest::Timer timer; for (int x = 0; x < slices; ++x) { for (int y = 0; y < slices; ++y) { pic->draw(canvas); @@ -351,9 +351,9 @@ static SkMSec timePict(SkPicture* pic, SkCanvas* canvas) { } canvas->translate(SkIntToScalar(xInterval), SkIntToScalar(-yInterval * slices)); } - SkMSec end = SkTime::GetMSecs(); + SkMSec elapsed = timer.elapsedMsInt(); canvas->restore(); - return end - start; + return elapsed; } static void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) { @@ -462,8 +462,8 @@ void TestResult::testOne() { if (fTestStep == kCompareBits) { fPixelError = similarBits(grBitmap, bitmap); - int skTime = timePict(pic, &skCanvas); - int grTime = timePict(pic, &grCanvas); + SkMSec skTime = timePict(pic, &skCanvas); + SkMSec grTime = timePict(pic, &grCanvas); fTime = skTime - grTime; } else if (fTestStep == kEncodeFiles) { SkString pngStr = make_png_name(fFilename); diff --git a/tests/StrokerTest.cpp b/tests/StrokerTest.cpp index b588cc6d10..68792d9d47 100755 --- a/tests/StrokerTest.cpp +++ b/tests/StrokerTest.cpp @@ -1,3 +1,10 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + #include "PathOpsCubicIntersectionTestData.h" #include "PathOpsQuadIntersectionTestData.h" #include "SkCommonFlags.h" @@ -20,7 +27,7 @@ size_t widths_count = SK_ARRAY_COUNT(widths); static void pathTest(const SkPath& path) { SkPaint p; - SkPath fill; + SkPath fill; p.setStyle(SkPaint::kStroke_Style); for (size_t index = 0; index < widths_count; ++index) { p.setStrokeWidth(widths[index]); @@ -29,91 +36,91 @@ static void pathTest(const SkPath& path) { } static void cubicTest(const SkPoint c[4]) { - SkPath path; - path.moveTo(c[0].fX, c[0].fY); - path.cubicTo(c[1].fX, c[1].fY, c[2].fX, c[2].fY, c[3].fX, c[3].fY); - pathTest(path); + SkPath path; + path.moveTo(c[0].fX, c[0].fY); + path.cubicTo(c[1].fX, c[1].fY, c[2].fX, c[2].fY, c[3].fX, c[3].fY); + pathTest(path); } static void quadTest(const SkPoint c[3]) { - SkPath path; - path.moveTo(c[0].fX, c[0].fY); - path.quadTo(c[1].fX, c[1].fY, c[2].fX, c[2].fY); - pathTest(path); + SkPath path; + path.moveTo(c[0].fX, c[0].fY); + path.quadTo(c[1].fX, c[1].fY, c[2].fX, c[2].fY); + pathTest(path); } static void cubicSetTest(const SkDCubic* dCubic, size_t count) { - SkMSec limit = SkTime::GetMSecs() + MS_TEST_DURATION; - for (size_t index = 0; index < count; ++index) { - const SkDCubic& d = dCubic[index]; - SkPoint c[4] = { {(float) d[0].fX, (float) d[0].fY}, {(float) d[1].fX, (float) d[1].fY}, + skiatest::Timer timer; + for (size_t index = 0; index < count; ++index) { + const SkDCubic& d = dCubic[index]; + SkPoint c[4] = { {(float) d[0].fX, (float) d[0].fY}, {(float) d[1].fX, (float) d[1].fY}, {(float) d[2].fX, (float) d[2].fY}, {(float) d[3].fX, (float) d[3].fY} }; - cubicTest(c); - if (FLAGS_timeout && SkTime::GetMSecs() > limit) { + cubicTest(c); + if (FLAGS_timeout && timer.elapsedMs() > MS_TEST_DURATION) { return; } - } + } } static void cubicPairSetTest(const SkDCubic dCubic[][2], size_t count) { - SkMSec limit = SkTime::GetMSecs() + MS_TEST_DURATION; - for (size_t index = 0; index < count; ++index) { - for (int pair = 0; pair < 2; ++pair) { - const SkDCubic& d = dCubic[index][pair]; - SkPoint c[4] = { {(float) d[0].fX, (float) d[0].fY}, {(float) d[1].fX, (float) d[1].fY}, + skiatest::Timer timer; + for (size_t index = 0; index < count; ++index) { + for (int pair = 0; pair < 2; ++pair) { + const SkDCubic& d = dCubic[index][pair]; + SkPoint c[4] = { {(float) d[0].fX, (float) d[0].fY}, {(float) d[1].fX, (float) d[1].fY}, {(float) d[2].fX, (float) d[2].fY}, {(float) d[3].fX, (float) d[3].fY} }; - cubicTest(c); - if (FLAGS_timeout && SkTime::GetMSecs() > limit) { + cubicTest(c); + if (FLAGS_timeout && timer.elapsedMs() > MS_TEST_DURATION) { return; } - } - } + } + } } static void quadSetTest(const SkDQuad* dQuad, size_t count) { - SkMSec limit = SkTime::GetMSecs() + MS_TEST_DURATION; - for (size_t index = 0; index < count; ++index) { - const SkDQuad& d = dQuad[index]; - SkPoint c[3] = { {(float) d[0].fX, (float) d[0].fY}, {(float) d[1].fX, (float) d[1].fY}, + skiatest::Timer timer; + for (size_t index = 0; index < count; ++index) { + const SkDQuad& d = dQuad[index]; + SkPoint c[3] = { {(float) d[0].fX, (float) d[0].fY}, {(float) d[1].fX, (float) d[1].fY}, {(float) d[2].fX, (float) d[2].fY} }; - quadTest(c); - if (FLAGS_timeout && SkTime::GetMSecs() > limit) { + quadTest(c); + if (FLAGS_timeout && timer.elapsedMs() > MS_TEST_DURATION) { return; } - } + } } static void quadPairSetTest(const SkDQuad dQuad[][2], size_t count) { - SkMSec limit = SkTime::GetMSecs() + MS_TEST_DURATION; - for (size_t index = 0; index < count; ++index) { - for (int pair = 0; pair < 2; ++pair) { - const SkDQuad& d = dQuad[index][pair]; - SkPoint c[3] = { {(float) d[0].fX, (float) d[0].fY}, {(float) d[1].fX, (float) d[1].fY}, + skiatest::Timer timer; + for (size_t index = 0; index < count; ++index) { + for (int pair = 0; pair < 2; ++pair) { + const SkDQuad& d = dQuad[index][pair]; + SkPoint c[3] = { {(float) d[0].fX, (float) d[0].fY}, {(float) d[1].fX, (float) d[1].fY}, {(float) d[2].fX, (float) d[2].fY} }; - quadTest(c); - if (FLAGS_timeout && SkTime::GetMSecs() > limit) { + quadTest(c); + if (FLAGS_timeout && timer.elapsedMs() > MS_TEST_DURATION) { return; } - } - } + } + } } DEF_TEST(QuadStrokerSet, reporter) { - quadSetTest(quadraticLines, quadraticLines_count); - quadSetTest(quadraticPoints, quadraticPoints_count); - quadSetTest(quadraticModEpsilonLines, quadraticModEpsilonLines_count); - quadPairSetTest(quadraticTests, quadraticTests_count); + quadSetTest(quadraticLines, quadraticLines_count); + quadSetTest(quadraticPoints, quadraticPoints_count); + quadSetTest(quadraticModEpsilonLines, quadraticModEpsilonLines_count); + quadPairSetTest(quadraticTests, quadraticTests_count); } DEF_TEST(CubicStrokerSet, reporter) { - cubicSetTest(pointDegenerates, pointDegenerates_count); - cubicSetTest(notPointDegenerates, notPointDegenerates_count); - cubicSetTest(lines, lines_count); - cubicSetTest(notLines, notLines_count); - cubicSetTest(modEpsilonLines, modEpsilonLines_count); - cubicSetTest(lessEpsilonLines, lessEpsilonLines_count); - cubicSetTest(negEpsilonLines, negEpsilonLines_count); - cubicPairSetTest(tests, tests_count); + cubicSetTest(pointDegenerates, pointDegenerates_count); + cubicSetTest(notPointDegenerates, notPointDegenerates_count); + cubicSetTest(lines, lines_count); + cubicSetTest(notLines, notLines_count); + cubicSetTest(modEpsilonLines, modEpsilonLines_count); + cubicSetTest(lessEpsilonLines, lessEpsilonLines_count); + cubicSetTest(negEpsilonLines, negEpsilonLines_count); + cubicPairSetTest(tests, tests_count); } static SkScalar unbounded(SkRandom& r) { @@ -134,7 +141,7 @@ DEF_TEST(QuadStrokerUnbounded, reporter) { int best = 0; sk_bzero(gMaxRecursion, sizeof(gMaxRecursion[0]) * 3); #endif - SkMSec limit = SkTime::GetMSecs() + MS_TEST_DURATION; + skiatest::Timer timer; for (int i = 0; i < 1000000; ++i) { SkPath path, fill; path.moveTo(unbounded(r), unbounded(r)); @@ -153,7 +160,7 @@ DEF_TEST(QuadStrokerUnbounded, reporter) { best = gMaxRecursion[2]; } #endif - if (FLAGS_timeout && SkTime::GetMSecs() > limit) { + if (FLAGS_timeout && timer.elapsedMs() > MS_TEST_DURATION) { return; } } @@ -173,7 +180,7 @@ DEF_TEST(CubicStrokerUnbounded, reporter) { int bestCubic = 0; sk_bzero(gMaxRecursion, sizeof(gMaxRecursion[0]) * 3); #endif - SkMSec limit = SkTime::GetMSecs() + MS_TEST_DURATION; + skiatest::Timer timer; for (int i = 0; i < 1000000; ++i) { SkPath path, fill; path.moveTo(unbounded(r), unbounded(r)); @@ -194,7 +201,7 @@ DEF_TEST(CubicStrokerUnbounded, reporter) { bestCubic = SkTMax(bestCubic, gMaxRecursion[1]); } #endif - if (FLAGS_timeout && SkTime::GetMSecs() > limit) { + if (FLAGS_timeout && timer.elapsedMs() > MS_TEST_DURATION) { return; } } @@ -213,7 +220,7 @@ DEF_TEST(QuadStrokerConstrained, reporter) { int best = 0; sk_bzero(gMaxRecursion, sizeof(gMaxRecursion[0]) * 3); #endif - SkMSec limit = SkTime::GetMSecs() + MS_TEST_DURATION; + skiatest::Timer timer; for (int i = 0; i < 1000000; ++i) { SkPath path, fill; SkPoint quad[3]; @@ -245,7 +252,7 @@ DEF_TEST(QuadStrokerConstrained, reporter) { best = gMaxRecursion[2]; } #endif - if (FLAGS_timeout && SkTime::GetMSecs() > limit) { + if (FLAGS_timeout && timer.elapsedMs() > MS_TEST_DURATION) { return; } } @@ -265,7 +272,7 @@ DEF_TEST(CubicStrokerConstrained, reporter) { int bestCubic = 0; sk_bzero(gMaxRecursion, sizeof(gMaxRecursion[0]) * 3); #endif - SkMSec limit = SkTime::GetMSecs() + MS_TEST_DURATION; + skiatest::Timer timer; for (int i = 0; i < 1000000; ++i) { SkPath path, fill; SkPoint cubic[4]; @@ -304,7 +311,7 @@ DEF_TEST(CubicStrokerConstrained, reporter) { bestCubic = SkTMax(bestCubic, gMaxRecursion[1]); } #endif - if (FLAGS_timeout && SkTime::GetMSecs() > limit) { + if (FLAGS_timeout && timer.elapsedMs() > MS_TEST_DURATION) { return; } } @@ -323,7 +330,7 @@ DEF_TEST(QuadStrokerRange, reporter) { int best = 0; sk_bzero(gMaxRecursion, sizeof(gMaxRecursion[0]) * 3); #endif - SkMSec limit = SkTime::GetMSecs() + MS_TEST_DURATION; + skiatest::Timer timer; for (int i = 0; i < 1000000; ++i) { SkPath path, fill; SkPoint quad[3]; @@ -349,7 +356,7 @@ DEF_TEST(QuadStrokerRange, reporter) { best = gMaxRecursion[2]; } #endif - if (FLAGS_timeout && SkTime::GetMSecs() > limit) { + if (FLAGS_timeout && timer.elapsedMs() > MS_TEST_DURATION) { return; } } @@ -368,7 +375,7 @@ DEF_TEST(CubicStrokerRange, reporter) { int best[2] = { 0 }; sk_bzero(gMaxRecursion, sizeof(gMaxRecursion[0]) * 3); #endif - SkMSec limit = SkTime::GetMSecs() + MS_TEST_DURATION; + skiatest::Timer timer; for (int i = 0; i < 1000000; ++i) { SkPath path, fill; path.moveTo(r.nextRangeF(0, 500), r.nextRangeF(0, 500)); @@ -389,7 +396,7 @@ DEF_TEST(CubicStrokerRange, reporter) { best[1] = SkTMax(best[1], gMaxRecursion[1]); } #endif - if (FLAGS_timeout && SkTime::GetMSecs() > limit) { + if (FLAGS_timeout && timer.elapsedMs() > MS_TEST_DURATION) { return; } } diff --git a/tests/Test.cpp b/tests/Test.cpp index f6f2bdab3d..dcb08e6bad 100644 --- a/tests/Test.cpp +++ b/tests/Test.cpp @@ -36,3 +36,17 @@ SkString skiatest::GetTmpDir() { const char* tmpDir = FLAGS_tmpDir.isEmpty() ? nullptr : FLAGS_tmpDir[0]; return SkString(tmpDir); } + +skiatest::Timer::Timer() : fStartNanos(SkTime::GetNSecs()) {} + +double skiatest::Timer::elapsedNs() const { + return SkTime::GetNSecs() - fStartNanos; +} + +double skiatest::Timer::elapsedMs() const { return this->elapsedNs() * 1e-6; } + +SkMSec skiatest::Timer::elapsedMsInt() const { + const double elapsedMs = this->elapsedMs(); + SkASSERT(SK_MSecMax >= elapsedMs); + return static_cast(elapsedMs); +} diff --git a/tests/Test.h b/tests/Test.h index d643c8382a..411ce11c20 100644 --- a/tests/Test.h +++ b/tests/Test.h @@ -85,6 +85,27 @@ enum GPUTestContexts { template void RunWithGPUTestContexts(T testFunction, GPUTestContexts contexts, Reporter* reporter, GrContextFactory* factory); + +/** Timer provides wall-clock duration since its creation. */ +class Timer { +public: + /** Starts the timer. */ + Timer(); + + /** Nanoseconds since creation. */ + double elapsedNs() const; + + /** Milliseconds since creation. */ + double elapsedMs() const; + + /** Milliseconds since creation as an integer. + Behavior is undefined for durations longer than SK_MSecMax. + */ + SkMSec elapsedMsInt() const; +private: + double fStartNanos; +}; + } // namespace skiatest #define REPORTER_ASSERT(r, cond) \ diff --git a/tests/skia_test.cpp b/tests/skia_test.cpp index 65fbc32842..5d21d1ec15 100644 --- a/tests/skia_test.cpp +++ b/tests/skia_test.cpp @@ -95,9 +95,9 @@ public: int fTestCount; } reporter; - const SkMSec start = SkTime::GetMSecs(); + const Timer timer; fTest.proc(&reporter, fGrContextFactory); - SkMSec elapsed = SkTime::GetMSecs() - start; + SkMSec elapsed = timer.elapsedMsInt(); if (reporter.fError) { fStatus->reportFailure(); } -- cgit v1.2.3