tools: separate TimeUtils from AnimTimer

gm, slides, and samples no longer need to know about the implementation
details of AnimTimer.

This
    virtual bool onAnimate(const AnimTimer&);
becomes this:
    virtual bool onAnimate(double /*nanoseconds*/);
which is much easier to reason about.

AnimTimer itself is now part of viewer.

Change-Id: Ib70bf7a0798b1991f25204ae84f70463cdbeb358
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/226838
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
This commit is contained in:
Hal Canary 2019-07-11 16:32:53 -04:00 committed by Skia Commit-Bot
parent 5043f1f2cd
commit 41248071ac
67 changed files with 347 additions and 466 deletions

View File

@ -1650,7 +1650,7 @@ if (skia_enable_tools) {
"tools/fonts/TestTypeface.h",
"tools/fonts/ToolUtilsFont.cpp",
"tools/random_parse_path.cpp",
"tools/timer/AnimTimer.h",
"tools/timer/TimeUtils.h",
"tools/timer/Timer.cpp",
]
libs = []
@ -2423,6 +2423,7 @@ if (skia_enable_tools) {
test_app("viewer") {
is_shared_library = is_android
sources = [
"tools/viewer/AnimTimer.h",
"tools/viewer/BisectSlide.cpp",
"tools/viewer/GMSlide.cpp",
"tools/viewer/ImGuiLayer.cpp",

View File

@ -20,7 +20,7 @@
#include "include/private/SkFloatingPoint.h"
#include "include/utils/SkRandom.h"
#include "tools/ToolUtils.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
class AddArcGM : public skiagm::GM {
public:
@ -62,8 +62,8 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
fRotate = timer.scaled(1, 360);
bool onAnimate(double nanos) override {
fRotate = TimeUtils::Scaled(1e-9 * nanos, 1, 360);
return true;
}
@ -148,8 +148,8 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
fRotate = timer.scaled(60, 360);
bool onAnimate(double nanos) override {
fRotate = TimeUtils::Scaled(1e-9 * nanos, 60, 360);
return true;
}
@ -201,8 +201,8 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
fRotate = timer.scaled(60, 360);
bool onAnimate(double nanos) override {
fRotate = TimeUtils::Scaled(1e-9 * nanos, 60, 360);
return true;
}

View File

@ -22,7 +22,7 @@
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include "tools/flags/CommandLineFlags.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
#include <memory>
#include <utility>
@ -140,12 +140,12 @@ private:
return DrawResult::kOk;
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
if (!fCodec || fTotalFrames == 1) {
return false;
}
double secs = timer.msec() * .1;
double secs = TimeUtils::NanosToMSec(nanos) * .1;
if (fNextUpdate < double(0)) {
// This is a sentinel that we have not done any updates yet.
// I'm assuming this gets called *after* onOnceBeforeDraw, so our first frame should
@ -219,12 +219,12 @@ private:
}
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
if (fBaseMSec == 0) {
fBaseMSec = timer.msec();
fBaseMSec = TimeUtils::NanosToMSec(nanos);
}
for (auto& p : fPlayers) {
(void)p->seek(timer.msec() - fBaseMSec);
(void)p->seek(TimeUtils::NanosToMSec(nanos) - fBaseMSec);
}
return true;
}

View File

@ -18,7 +18,7 @@
#include "include/core/SkTypes.h"
#include "include/effects/SkBlurImageFilter.h"
#include "include/utils/SkRandom.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
static const SkScalar kBlurMax = 7.0f;
static const int kNumNodes = 30;
@ -68,14 +68,14 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
if (0.0f != fLastTime) {
for (int i = 0; i < kNumNodes; ++i) {
fNodes[i].update(timer, fLastTime);
fNodes[i].update(nanos, fLastTime);
}
}
fLastTime = timer.secs();
fLastTime = 1e-9 * nanos;
return true;
}
@ -105,8 +105,8 @@ private:
fSpeed = rand->nextRangeF(20.0f, 60.0f);
}
void update(const AnimTimer& timer, SkScalar lastTime) {
SkScalar deltaTime = timer.secs() - lastTime;
void update(double nanos, SkScalar lastTime) {
SkScalar deltaTime = 1e-9 * nanos - lastTime;
fPos.fX += deltaTime * fSpeed * fDir.fX;
fPos.fY += deltaTime * fSpeed * fDir.fY;
@ -119,7 +119,7 @@ private:
fDir.fY = -fDir.fY;
}
fBlur = timer.pingPong(kBlurAnimationDuration, fBlurOffset, 0.0f, kBlurMax);
fBlur = TimeUtils::PingPong(1e-9 * nanos, kBlurAnimationDuration, fBlurOffset, 0.0f, kBlurMax);
}
SkScalar sigma() const { return fBlur; }

View File

@ -19,7 +19,7 @@
#include "include/core/SkString.h"
#include "include/utils/SkRandom.h"
#include "src/core/SkBlurMask.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
/**
* In GM mode this draws an array of circles with different radii and different blur radii. Below
@ -34,9 +34,9 @@
class BlurCircles2GM : public skiagm::GM {
public:
BlurCircles2GM() {
fAnimRadius = AnimTimer::PingPong(
fAnimRadius = TimeUtils::PingPong(
0, kRadiusPingPoingPeriod, kRadiusPingPoingShift, kMinRadius, kMaxRadius);
fAnimBlurRadius = AnimTimer::PingPong(0,
fAnimBlurRadius = TimeUtils::PingPong(0,
kBlurRadiusPingPoingPeriod,
kBlurRadiusPingPoingShift,
kMinBlurRadius,
@ -141,10 +141,10 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
fAnimRadius = timer.pingPong(kRadiusPingPoingPeriod, kRadiusPingPoingShift, kMinRadius,
bool onAnimate(double nanos) override {
fAnimRadius = TimeUtils::PingPong(1e-9 * nanos, kRadiusPingPoingPeriod, kRadiusPingPoingShift, kMinRadius,
kMaxRadius);
fAnimBlurRadius = timer.pingPong(kBlurRadiusPingPoingPeriod, kBlurRadiusPingPoingShift,
fAnimBlurRadius = TimeUtils::PingPong(1e-9 * nanos, kBlurRadiusPingPoingPeriod, kBlurRadiusPingPoingShift,
kMinBlurRadius, kMaxBlurRadius);
return true;
}

View File

@ -19,7 +19,7 @@
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkDashPathEffect.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
int dash1[] = { 1, 1 };
int dash2[] = { 1, 3 };
@ -105,10 +105,10 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
constexpr SkScalar kDesiredDurationSecs = 100.0f;
fRotation = timer.scaled(360.0f/kDesiredDurationSecs, 360.0f);
fRotation = TimeUtils::Scaled(1e-9 * nanos, 360.0f/kDesiredDurationSecs, 360.0f);
return true;
}
@ -226,8 +226,8 @@ protected:
}
protected:
bool onAnimate(const AnimTimer& timer) override {
fPhaseDegrees = timer.secs();
bool onAnimate(double nanos) override {
fPhaseDegrees = 1e-9 * nanos;
return true;
}

View File

@ -19,7 +19,7 @@
#include "include/effects/SkTrimPathEffect.h"
#include "include/private/SkTArray.h"
#include "include/utils/SkParsePath.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
#include <math.h>
#include <utility>
@ -161,8 +161,8 @@ protected:
}
}
bool onAnimate(const AnimTimer& t) override {
fOffset = t.msec() / 2000.0f;
bool onAnimate(double nanos) override {
fOffset = TimeUtils::NanosToMSec(nanos) / 2000.0f;
fOffset -= floorf(fOffset);
return true;
}

View File

@ -139,14 +139,14 @@ void GM::setBGColor(SkColor color) {
fBGColor = color;
}
bool GM::animate(const AnimTimer& timer) { return this->onAnimate(timer); }
bool GM::animate(double nanos) { return this->onAnimate(nanos); }
bool GM::runAsBench() const { return false; }
void GM::modifyGrContextOptions(GrContextOptions* options) {}
void GM::onOnceBeforeDraw() {}
bool GM::onAnimate(const AnimTimer&) { return false; }
bool GM::onAnimate(double /*nanos*/) { return false; }
bool GM::onChar(SkUnichar uni) { return false; }

View File

@ -16,7 +16,6 @@
#include "include/private/SkMacros.h"
#include "tools/Registry.h"
class AnimTimer;
class GrContext;
class GrRenderTargetContext;
class SkCanvas;
@ -144,7 +143,7 @@ namespace skiagm {
fCanvasIsDeferred = isDeferred;
}
bool animate(const AnimTimer&);
bool animate(double /*nanos*/);
virtual bool onChar(SkUnichar);
bool getControls(SkMetaData* controls) { return this->onGetControls(controls); }
@ -160,7 +159,7 @@ namespace skiagm {
virtual SkISize onISize() = 0;
virtual SkString onShortName() = 0;
virtual bool onAnimate(const AnimTimer&);
virtual bool onAnimate(double /*nanos*/);
virtual bool onGetControls(SkMetaData*);
virtual void onSetControls(const SkMetaData&);

View File

@ -20,7 +20,7 @@
#include "include/effects/SkLightingImageFilter.h"
#include "include/effects/SkOffsetImageFilter.h"
#include "tools/ToolUtils.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
#define WIDTH 330
#define HEIGHT 660
@ -166,10 +166,10 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
constexpr SkScalar kDesiredDurationSecs = 15.0f;
fAzimuth = kStartAzimuth + timer.scaled(360.0f/kDesiredDurationSecs, 360.0f);
fAzimuth = kStartAzimuth + TimeUtils::Scaled(1e-9 * nanos, 360.0f/kDesiredDurationSecs, 360.0f);
return true;
}

View File

@ -24,7 +24,6 @@
#include "include/effects/SkGradientShader.h"
#include "include/effects/SkLumaColorFilter.h"
#include "tools/Resources.h"
#include "tools/timer/AnimTimer.h"
#include <math.h>
@ -196,8 +195,8 @@ protected:
canvas->drawRect(r, paint);
}
bool onAnimate(const AnimTimer& timer) override {
fPos = (sin(timer.secs()) + 1) * 0.5f;
bool onAnimate(double nanos) override {
fPos = (sin(1e-9 * nanos) + 1) * 0.5f;
return true;
}

View File

@ -22,7 +22,7 @@
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
// Mimics https://output.jsbin.com/falefice/1/quiet?CC_POSTER_CIRCLE, which can't be captured as
// an SKP due to many 3D layers being composited post-SKP capture.
@ -41,15 +41,8 @@ protected:
return SkISize::Make(kStageWidth, kStageHeight + 50);
}
bool onAnimate(const AnimTimer& timer) override {
#if 0
if (timer.isRunning()) {
// Use a fixed timestep
fTime += 5e-4f;
}
#else
fTime = timer.scaled(0.5f);
#endif
bool onAnimate(double nanos) override {
fTime = TimeUtils::Scaled(1e-9 * nanos, 0.5f);
return true;
}

View File

@ -15,8 +15,6 @@
#include "include/utils/SkRandom.h"
#include "tools/ToolUtils.h"
class AnimTimer;
class SimpleRectGM : public skiagm::GM {
public:
SimpleRectGM() {}
@ -51,7 +49,7 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override { return true; }
bool onAnimate(double nanos) override { return true; }
private:

View File

@ -15,7 +15,7 @@
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "tools/ToolUtils.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
// Reproduces https://code.google.com/p/chromium/issues/detail?id=279014
@ -67,11 +67,11 @@ protected:
canvas->drawPath(path, paint);
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
constexpr SkScalar kDesiredDurationSecs = 3.0f;
// Make the animation ping-pong back and forth but start in the fully drawn state
SkScalar fraction = 1.0f - timer.scaled(2.0f/kDesiredDurationSecs, 2.0f);
SkScalar fraction = 1.0f - TimeUtils::Scaled(1e-9 * nanos, 2.0f/kDesiredDurationSecs, 2.0f);
if (fraction <= 0.0f) {
fraction = -fraction;
}
@ -147,8 +147,8 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
SkScalar time = (float)(fmod(timer.secs(), fDur) / fDur);
bool onAnimate(double nanos) override {
SkScalar time = (float)(fmod(1e-9 * nanos, fDur) / fDur);
for (auto anim : fAnims) {
anim->seek(time);
}

View File

@ -55,7 +55,7 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
return true;
}

View File

@ -14,7 +14,7 @@
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
class XformGM : public skiagm::GM {
sk_sp<MatrixXF> fRoot, fRA, fRB, fA, fB;
@ -91,11 +91,11 @@ protected:
fShape->draw(ctx.get());
}
bool onAnimate(const AnimTimer& timer) override {
float scale = 3 + sinf(timer.scaled(1, 0)) * 2;
bool onAnimate(double nanos) override {
float scale = 3 + sinf(TimeUtils::Scaled(1e-9 * nanos, 1, 0)) * 2;
fRoot->setScale(scale, scale);
fRA->setRotate(timer.scaled(40, 0));
fB->setRotate(timer.scaled(40*sqrtf(2), 0));
fRA->setRotate(TimeUtils::Scaled(1e-9 * nanos, 40, 0));
fB->setRotate(TimeUtils::Scaled(1e-9 * nanos, 40*sqrtf(2), 0));
return true;
}

View File

@ -25,7 +25,6 @@
#include "include/utils/Sk3D.h"
#include "modules/skottie/include/Skottie.h"
#include "tools/Resources.h"
#include "tools/timer/AnimTimer.h"
#include <math.h>
#include <algorithm>
@ -196,12 +195,12 @@ protected:
SkString onShortName() override { return SkString("3dgm"); }
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
if (!fAnim) {
return false;
}
SkScalar dur = fAnim->duration();
fAnimT = fmod(timer.secs(), dur) / dur;
fAnimT = fmod(1e-9 * nanos, dur) / dur;
return true;
}
bool onChar(SkUnichar uni) override {

View File

@ -13,7 +13,6 @@
#include "modules/skottie/utils/SkottieUtils.h"
#include "src/core/SkMakeUnique.h"
#include "tools/Resources.h"
#include "tools/timer/AnimTimer.h"
#include <cmath>
#include <vector>
@ -72,13 +71,13 @@ protected:
return DrawResult::kOk;
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
if (!fAnimation) {
return false;
}
const auto duration = fAnimation->duration();
fAnimation->seek(std::fmod(timer.secs(), duration) / duration);
fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
return true;
}
@ -125,13 +124,13 @@ protected:
return DrawResult::kOk;
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
if (!fAnimation) {
return false;
}
const auto duration = fAnimation->duration();
fAnimation->seek(std::fmod(timer.secs(), duration) / duration);
fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
return true;
}
@ -198,13 +197,13 @@ protected:
return DrawResult::kOk;
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
if (!fAnimation) {
return false;
}
const auto duration = fAnimation->duration();
fAnimation->seek(std::fmod(timer.secs(), duration) / duration);
fAnimation->seek(std::fmod(1e-9 * nanos, duration) / duration);
return true;
}

View File

@ -8,7 +8,7 @@
#include "include/core/SkRRect.h"
#include "include/utils/SkRandom.h"
#include "samplecode/Sample.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
#include "modules/sksg/include/SkSGDraw.h"
#include "modules/sksg/include/SkSGGroup.h"
@ -185,11 +185,11 @@ protected:
fScene->render(canvas);
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
// onAnimate may fire before the first draw.
if (fScene) {
SkScalar dt = (timer.msec() - fLastTick) * fTimeScale;
fLastTick = timer.msec();
SkScalar dt = (TimeUtils::NanosToMSec(nanos) - fLastTick) * fTimeScale;
fLastTick = TimeUtils::NanosToMSec(nanos);
fPaddle0.posTick(dt);
fPaddle1.posTick(dt);

View File

@ -39,7 +39,6 @@
#include "platform_tools/android/apps/arcore/src/main/cpp/plane_renderer.h"
#include "platform_tools/android/apps/arcore/src/main/cpp/util.h"
#include "tools/Resources.h"
#include "tools/timer/AnimTimer.h"
namespace hello_ar {
namespace {

View File

@ -11,7 +11,6 @@
#include "samplecode/Sample.h"
#include "src/utils/SkPatchUtils.h"
#include "tools/ModifierKey.h"
#include "tools/timer/AnimTimer.h"
static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
//draw control points
@ -121,7 +120,7 @@ protected:
return false;
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
fSeed += 0.005f;
return true;
}

View File

@ -17,7 +17,6 @@
#include "tools/ModifierKey.h"
#include "tools/Registry.h"
class AnimTimer;
class SkCanvas;
class Sample;
@ -78,7 +77,7 @@ public:
static void DoClickUp(Click*, int x, int y, ModifierKey modi);
void setBGColor(SkColor color) { fBGColor = color; }
bool animate(const AnimTimer& timer) { return this->onAnimate(timer); }
bool animate(double nanos) { return this->onAnimate(nanos); }
virtual SkString name() = 0;
@ -94,7 +93,7 @@ protected:
virtual void onDrawBackground(SkCanvas*);
virtual void onDrawContent(SkCanvas*) = 0;
virtual bool onAnimate(const AnimTimer&) { return false; }
virtual bool onAnimate(double /*nanos*/) { return false; }
virtual void onOnceBeforeDraw() {}
private:

View File

@ -17,7 +17,7 @@
#include "src/core/SkBlurMask.h"
#include "src/utils/SkUTF.h"
#include "tools/ToolUtils.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
////////////////////////////////////////////////////////////////////////////
@ -335,11 +335,11 @@ protected:
lightPos, kLightWidth, .5f);
}
bool onAnimate(const AnimTimer& timer) override {
fAnimTranslate = timer.pingPong(30, 0, 125, -125);
fAnimAngle = timer.pingPong(15, 0, 0, 20);
bool onAnimate(double nanos) override {
fAnimTranslate = TimeUtils::PingPong(1e-9 * nanos, 30, 0, 125, -125);
fAnimAngle = TimeUtils::PingPong(1e-9 * nanos, 15, 0, 0, 20);
if (fDoAlphaAnimation) {
fAnimAlpha = timer.pingPong(5, 0, 1, 0);
fAnimAlpha = TimeUtils::PingPong(1e-9 * nanos, 5, 0, 1, 0);
}
return true;
}

View File

@ -10,7 +10,6 @@
#include "include/core/SkMaskFilter.h"
#include "include/utils/SkRandom.h"
#include "samplecode/Sample.h"
#include "tools/timer/AnimTimer.h"
SkScalar get_anim_sin(double secs, SkScalar amplitude, SkScalar periodInSec, SkScalar phaseInSec) {
if (!periodInSec) {
@ -49,9 +48,9 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
fBlurSigma = get_anim_sin(timer.secs(), 100, 4, 5);
fCircleRadius = 3 + get_anim_sin(timer.secs(), 150, 25, 3);
bool onAnimate(double nanos) override {
fBlurSigma = get_anim_sin(1e-9 * nanos, 100, 4, 5);
fCircleRadius = 3 + get_anim_sin(1e-9 * nanos, 150, 25, 3);
return true;
}

View File

@ -14,7 +14,7 @@
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
#include "samplecode/Sample.h"
#include "tools/Resources.h"
@ -56,13 +56,13 @@ protected:
canvas->drawDrawable(fDrawable.get(), fImage->getBounds().width(), 0);
}
bool onAnimate(const AnimTimer& animTimer) override {
bool onAnimate(double nanos) override {
if (!fImage) {
return false;
}
const double lastWallTime = fLastWallTime;
fLastWallTime = animTimer.msec();
fLastWallTime = TimeUtils::NanosToMSec(nanos);
if (fRunning) {
fCurrentTime += fLastWallTime - lastWallTime;

View File

@ -123,7 +123,7 @@ protected:
canvas->drawString(modeString, 768.f, 540.f, font, paint);
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
// We add noise to the scale and rotation animations to
// keep the font atlas from falling into a steady state
fRotation += (1.0f + gRand.nextRangeF(-0.1f, 0.1f));

View File

@ -22,7 +22,6 @@
#include "include/utils/SkTextUtils.h"
#include "samplecode/Sample.h"
#include "src/utils/SkUTF.h"
#include "tools/timer/AnimTimer.h"
#include "include/utils/SkParsePath.h"
static void testparse() {
@ -181,8 +180,8 @@ protected:
canvas->drawDrawable(fRootDrawable.get());
}
bool onAnimate(const AnimTimer& timer) override {
SkScalar angle = SkDoubleToScalar(fmod(timer.secs() * 360 / 24, 360));
bool onAnimate(double nanos) override {
SkScalar angle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 24, 360));
if (fAnimatingDrawable) {
fAnimatingDrawable->setSweep(angle);
}

View File

@ -13,7 +13,6 @@
#include "include/utils/SkRandom.h"
#include "include/utils/SkTextUtils.h"
#include "samplecode/Sample.h"
#include "tools/timer/AnimTimer.h"
typedef void (*DrawAtlasProc)(SkCanvas*, SkImage*, const SkRSXform[], const SkRect[],
const SkColor[], int, const SkRect*, const SkPaint*);
@ -229,11 +228,11 @@ protected:
canvas->drawDrawable(fDrawable.get());
}
bool onAnimate(const AnimTimer&) override { return true; }
bool onAnimate(double /*nanos*/) override { return true; }
#if 0
// TODO: switch over to use this for our animation
bool onAnimate(const AnimTimer& timer) override {
SkScalar angle = SkDoubleToScalar(fmod(timer.secs() * 360 / 24, 360));
bool onAnimate(double nanos) override {
SkScalar angle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 24, 360));
fAnimatingDrawable->setSweep(angle);
return true;
}

View File

@ -19,13 +19,12 @@
#include "include/effects/SkGradientShader.h"
#include "samplecode/Sample.h"
#include "src/utils/SkUTF.h"
#include "tools/timer/AnimTimer.h"
#include "include/core/SkStream.h"
#include "src/core/SkOSFile.h"
#define INT_SIZE 64
#define SCALAR_SIZE SkIntToScalar(INT_SIZE)
static constexpr int INT_SIZE = 64;
static constexpr float SCALAR_SIZE = (float)INT_SIZE;
static void make_bitmap(SkBitmap* bitmap) {
bitmap->allocN32Pixels(INT_SIZE, INT_SIZE);
@ -40,11 +39,6 @@ static void make_bitmap(SkBitmap* bitmap) {
canvas.drawCircle(SCALAR_SIZE/2, SCALAR_SIZE/2, SCALAR_SIZE/2, paint);
}
static SkPoint unit_vec(int degrees) {
SkScalar rad = SkDegreesToRadians(SkIntToScalar(degrees));
return SkPoint::Make(SkScalarCos(rad), SkScalarSin(rad));
}
static void bounce(SkScalar* value, SkScalar* delta, SkScalar min, SkScalar max) {
*value += *delta;
if (*value < min) {
@ -62,77 +56,43 @@ static void bounce_pt(SkPoint* pt, SkVector* vec, const SkRect& limit) {
}
class BitmapRectView : public Sample {
SkPoint fSrcPts[2];
SkPoint fSrcVec[2];
SkRect fSrcLimit;
SkRect fDstR[2];
SkPoint fSrcPt = {0, 0};
SkPoint fSrcVec = {0.866025f, 0.5f};
void bounce() {
bounce_pt(&fSrcPts[0], &fSrcVec[0], fSrcLimit);
bounce_pt(&fSrcPts[1], &fSrcVec[1], fSrcLimit);
}
SkRect fSrcLimit = {-SCALAR_SIZE/4, -SCALAR_SIZE/4,
SCALAR_SIZE*5/4, SCALAR_SIZE*5/4};
SkRect fDstR[2] = {{10, 100, 260, 400}, {322.5, 100, 572.5, 400}};
SkBitmap fBitmap;
void resetBounce() {
fSrcPts[0].set(0, 0);
fSrcPts[1].set(SCALAR_SIZE, SCALAR_SIZE);
fSrcVec[0] = unit_vec(30);
fSrcVec[1] = unit_vec(107);
}
public:
BitmapRectView() {
this->setBGColor(SK_ColorGRAY);
this->resetBounce();
fSrcLimit.set(-SCALAR_SIZE/4, -SCALAR_SIZE/4,
SCALAR_SIZE*5/4, SCALAR_SIZE*5/4);
fDstR[0] = SkRect::MakeXYWH(SkIntToScalar(10), SkIntToScalar(100),
SkIntToScalar(250), SkIntToScalar(300));
fDstR[1] = fDstR[0];
fDstR[1].offset(fDstR[0].width() * 5/4, 0);
fSrcPts[0].set(32, 32);
fSrcPts[1].set(90, 90);
}
protected:
SkString name() override { return SkString("BitmapRect"); }
void onOnceBeforeDraw() override {
this->setBGColor(SK_ColorGRAY);
make_bitmap(&fBitmap);
}
void onDrawContent(SkCanvas* canvas) override {
SkRect srcR;
srcR.set(fSrcPts[0], fSrcPts[1]);
srcR = SkRect::MakeXYWH(fSrcPts[0].fX, fSrcPts[0].fY, 32, 32);
srcR.offset(-srcR.width()/2, -srcR.height()/2);
SkRect srcR = {fSrcPt.fX - 16, fSrcPt.fY - 16,
fSrcPt.fX + 16, fSrcPt.fY + 16};
SkPaint paint;
SkPaint paint(SkColors::kYellow);
paint.setStyle(SkPaint::kStroke_Style);
paint.setColor(SK_ColorYELLOW);
SkBitmap bitmap;
make_bitmap(&bitmap);
canvas->translate(20, 20);
canvas->drawBitmap(bitmap, 0, 0, &paint);
canvas->drawBitmap(fBitmap, 0, 0, &paint);
canvas->drawRect(srcR, paint);
for (int i = 0; i < 2; ++i) {
paint.setFilterQuality(1 == i ? kLow_SkFilterQuality : kNone_SkFilterQuality);
canvas->drawBitmapRect(bitmap, srcR, fDstR[i], &paint,
canvas->drawBitmapRect(fBitmap, srcR, fDstR[i], &paint,
SkCanvas::kStrict_SrcRectConstraint);
canvas->drawRect(fDstR[i], paint);
}
}
bool onAnimate(const AnimTimer& timer) override {
if (timer.isStopped()) {
this->resetBounce();
} else if (timer.isRunning()) {
this->bounce();
}
bool onAnimate(double nanos) override {
bounce_pt(&fSrcPt, &fSrcVec, fSrcLimit);
return true;
}
@ -142,6 +102,8 @@ private:
//////////////////////////////////////////////////////////////////////////////
static constexpr int BIG_H = 120;
static void make_big_bitmap(SkBitmap* bm) {
static const char gText[] =
"We the people, in order to form a more perfect union, establish justice,"
@ -150,8 +112,6 @@ static void make_big_bitmap(SkBitmap* bm) {
" posterity, do ordain and establish this constitution for the United"
" States of America.";
const int BIG_H = 120;
SkFont font;
font.setSize(SkIntToScalar(BIG_H));
@ -167,41 +127,17 @@ static void make_big_bitmap(SkBitmap* bm) {
class BitmapRectView2 : public Sample {
SkBitmap fBitmap;
SkRect fSrcR = {0, 0, 3 * BIG_H, BIG_H};
SkRect fLimitR;
SkScalar fDX = 1;
SkRect fDstR[2] = {{20, 20, 620, 220}, {20, 270, 620, 470}};
SkRect fSrcR;
SkRect fLimitR;
SkScalar fDX;
SkRect fDstR[2];
void bounceMe() {
SkScalar width = fSrcR.width();
bounce(&fSrcR.fLeft, &fDX, fLimitR.fLeft, fLimitR.fRight - width);
fSrcR.fRight = fSrcR.fLeft + width;
}
void resetBounce() {
fSrcR.iset(0, 0, fBitmap.height() * 3, fBitmap.height());
fDX = SK_Scalar1;
}
public:
BitmapRectView2() { }
protected:
SkString name() override { return SkString("BigBitmapRect"); }
void onOnceBeforeDraw() override {
make_big_bitmap(&fBitmap);
this->setBGColor(SK_ColorGRAY);
this->resetBounce();
fLimitR.iset(0, 0, fBitmap.width(), fBitmap.height());
fDstR[0] = SkRect::MakeXYWH(20, 20, 600, 200);
fDstR[1] = fDstR[0];
fDstR[1].offset(0, fDstR[0].height() * 5/4);
make_big_bitmap(&fBitmap);
fLimitR = SkRect::Make(fBitmap.dimensions());
}
void onDrawContent(SkCanvas* canvas) override {
@ -217,17 +153,12 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
if (timer.isStopped()) {
this->resetBounce();
} else if (timer.isRunning()) {
this->bounceMe();
}
bool onAnimate(double nanos) override {
SkScalar width = fSrcR.width();
bounce(&fSrcR.fLeft, &fDX, fLimitR.fLeft, fLimitR.fRight - width);
fSrcR.fRight = fSrcR.fLeft + width;
return true;
}
private:
typedef Sample INHERITED;
};
//////////////////////////////////////////////////////////////////////////////

View File

@ -13,7 +13,7 @@
#include "samplecode/Sample.h"
#include "src/effects/SkEmbossMaskFilter.h"
#include "tools/Resources.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
namespace {
class CameraView : public Sample {
@ -67,12 +67,8 @@ class CameraView : public Sample {
}
}
bool onAnimate(const AnimTimer& timer) override {
if (timer.isStopped()) {
fRY = 0;
} else {
fRY = timer.scaled(90, 360);
}
bool onAnimate(double nanos) override {
fRY = nanos ? TimeUtils::Scaled(1e-9 * nanos, 90, 360) : 0;
return true;
}
};

View File

@ -210,7 +210,7 @@ protected:
canvas->restore();
}
bool onAnimate(const AnimTimer&) override { return true; }
bool onAnimate(double /*nanos*/) override { return true; }
private:

View File

@ -98,7 +98,7 @@ protected:
SkString name() override { return fLabel; }
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
if (!fDom) {
return false;
}

View File

@ -11,7 +11,7 @@
#include "include/core/SkPath.h"
#include "samplecode/Sample.h"
#include "src/core/SkGeometry.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
// This draws an animation where every cubic has a cusp, to test drawing a circle
// at the cusp point. Create a unit square. A cubic with its control points
@ -165,8 +165,8 @@ protected:
SkDebugf("");
}
bool onAnimate(const AnimTimer& timer) override {
curTime = timer.msec();
bool onAnimate(double nanos) override {
curTime = TimeUtils::NanosToMSec(nanos);
if (!start) {
start = curTime;
}

View File

@ -10,7 +10,6 @@
#include "include/core/SkString.h"
#include "include/effects/SkGradientShader.h"
#include "samplecode/Sample.h"
#include "tools/timer/AnimTimer.h"
static void draw_gradient2(SkCanvas* canvas, const SkRect& rect, SkScalar delta) {
SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorMAGENTA };
@ -67,8 +66,8 @@ protected:
SkFont(), SkPaint());
}
bool onAnimate(const AnimTimer& timer) override {
fTime = SkDoubleToScalar(timer.secs() / 15);
bool onAnimate(double nanos) override {
fTime = SkDoubleToScalar(1e-9 * nanos / 15);
return true;
}

View File

@ -16,7 +16,7 @@
#include "include/utils/SkRandom.h"
#include "samplecode/Sample.h"
#include "tools/Resources.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
static sk_sp<SkSurface> make_surface(SkCanvas* canvas, const SkImageInfo& info) {
auto surface = canvas->makeSurface(info);
@ -278,8 +278,8 @@ protected:
canvas->drawString(SkStringPrintf("%.8g", trans[1] ), textX, 250, font, paint);
}
bool onAnimate(const AnimTimer& timer) override {
fCurrTime = timer.msec();
bool onAnimate(double nanos) override {
fCurrTime = TimeUtils::NanosToMSec(nanos);
return true;
}

View File

@ -14,7 +14,6 @@
#include "include/core/SkTypeface.h"
#include "include/utils/SkRandom.h"
#include "samplecode/Sample.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/Timer.h"
#if SK_SUPPORT_GPU
@ -57,11 +56,11 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
fCurrTime = timer.secs() - fResetTime;
bool onAnimate(double nanos) override {
fCurrTime = 1e-9 * nanos - fResetTime;
if (fCurrTime > kDuration) {
this->initChars();
fResetTime = timer.secs();
fResetTime = 1e-9 * nanos;
fCurrTime = 0;
}

View File

@ -12,7 +12,7 @@
#include "include/core/SkRRect.h"
#include "include/core/SkTypeface.h"
#include "include/utils/SkRandom.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
#include <cmath>
@ -54,9 +54,9 @@ protected:
font, paint);
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
constexpr SkScalar maxt = 100000;
double t = timer.pingPong(20, 0, 0, maxt); // d3 t is in milliseconds
double t = TimeUtils::PingPong(1e-9 * nanos, 20, 0, 0, maxt); // d3 t is in milliseconds
fTranslate.set(sin(t / 3000) - t * this->width() * 0.7 / maxt, sin(t / 999) / t);
fScale = 4.5 - std::sqrt(t) / 99;

View File

@ -12,7 +12,7 @@
#include "include/utils/SkRandom.h"
#include "samplecode/Sample.h"
#include "src/core/SkPointPriv.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
const SkRect gUnitSquare = { -1, -1, 1, 1 };
@ -148,8 +148,8 @@ protected:
canvas->drawDrawable(fRoot.get());
}
bool onAnimate(const AnimTimer& timer) override {
fTime = timer.msec();
bool onAnimate(double nanos) override {
fTime = TimeUtils::NanosToMSec(nanos);
for (int i = 0; i < N; ++i) {
fArray[i].fDrawable->setTime(fTime);
}

View File

@ -22,7 +22,6 @@
#include "include/utils/SkRandom.h"
#include "samplecode/Sample.h"
#include "src/utils/SkUTF.h"
#include "tools/timer/AnimTimer.h"
static SkRandom gRand;
@ -208,7 +207,7 @@ protected:
canvas->drawBitmap(bm2, SkIntToScalar(10), SkIntToScalar(10), nullptr);
}
bool onAnimate(const AnimTimer&) override {
bool onAnimate(double /*nanos*/) override {
if (fDoAA) {
fProcIndex = cycle_hairproc_index(fProcIndex);
// todo: signal that we want to rebuild our TITLE

View File

@ -179,7 +179,6 @@ DEF_SAMPLE( return new LayersView; )
#include "include/effects/SkMorphologyImageFilter.h"
#include "tools/Resources.h"
#include "tools/timer/AnimTimer.h"
class BackdropView : public Sample {
SkPoint fCenter;
@ -219,8 +218,8 @@ protected:
canvas->restore();
}
bool onAnimate(const AnimTimer& timer) override {
fAngle = SkDoubleToScalar(fmod(timer.secs() * 360 / 5, 360));
bool onAnimate(double nanos) override {
fAngle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 5, 360));
return true;
}

View File

@ -69,7 +69,7 @@ protected:
return this->INHERITED::onFindClickHandler(x, y, modi);
}
bool onAnimate(const AnimTimer& timer) override {
bool onAnimate(double nanos) override {
fLightAngle += 0.015f;
fColorFactor += 0.01f;
if (fColorFactor > 1.0f) {

View File

@ -14,7 +14,6 @@
#include "src/shaders/SkBitmapProcShader.h"
#include "src/shaders/SkLightingShader.h"
#include "src/shaders/SkLights.h"
#include "tools/timer/AnimTimer.h"
#include "tools/ToolUtils.h"
@ -476,7 +475,7 @@ protected:
canvas->drawDrawable(fDrawable.get());
}
bool onAnimate(const AnimTimer& timer) override { return true; }
bool onAnimate(double nanos) override { return true; }
private:
sk_sp<DrawLitAtlasDrawable> fDrawable;

View File

@ -69,7 +69,7 @@ protected:
fClip.set(0, 0, 950, 600);
}
bool onAnimate(const AnimTimer&) override { return true; }
bool onAnimate(double /*nanos*/) override { return true; }
private:
SkPath fMegaPath;

View File

@ -27,7 +27,7 @@
#include "src/core/SkOSFile.h"
#include "src/utils/SkUTF.h"
#include "tools/Resources.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
namespace {
static sk_sp<SkShader> make_shader0(SkIPoint* size) {
@ -282,8 +282,8 @@ struct PatchView : public Sample {
drawpatches(canvas, paint, nu, nv, &patch);
}
bool onAnimate(const AnimTimer& timer) override {
fAngle = timer.scaled(60, 360);
bool onAnimate(double nanos) override {
fAngle = TimeUtils::Scaled(1e-9 * nanos, 60, 360);
return true;
}
@ -379,7 +379,7 @@ public:
protected:
SkString name() override { return SkString("PseudoInk"); }
bool onAnimate(const AnimTimer& timer) override { return true; }
bool onAnimate(double nanos) override { return true; }
void onDrawContent(SkCanvas* canvas) override {
if (fDirty) {
@ -445,7 +445,7 @@ public:
protected:
SkString name() override { return SkString("ManyStrokes"); }
bool onAnimate(const AnimTimer& timer) override { return true; }
bool onAnimate(double nanos) override { return true; }
void dodraw(SkCanvas* canvas, sk_sp<SkPathEffect> pe, SkScalar x, SkScalar y,
const SkPaint* ptr = nullptr) {

View File

@ -20,7 +20,7 @@
#include "include/utils/SkParsePath.h"
#include "samplecode/Sample.h"
#include "src/utils/SkUTF.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
#include "src/core/SkGeometry.h"
@ -177,8 +177,8 @@ protected:
}
}
bool onAnimate(const AnimTimer& timer) override {
SkScalar currSecs = timer.scaled(100);
bool onAnimate(double nanos) override {
SkScalar currSecs = TimeUtils::Scaled(1e-9 * nanos, 100);
SkScalar delta = currSecs - fPrevSecs;
fPrevSecs = currSecs;

View File

@ -17,7 +17,7 @@
#include "include/utils/SkRandom.h"
#include "samplecode/Sample.h"
#include "src/utils/SkUTF.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
#define CORNER_RADIUS 12
@ -132,8 +132,8 @@ protected:
canvas->drawPath(fPath, paint);
}
bool onAnimate(const AnimTimer& timer) override {
fPhase = timer.scaled(40);
bool onAnimate(double nanos) override {
fPhase = TimeUtils::Scaled(1e-9 * nanos, 40);
return true;
}

View File

@ -15,7 +15,6 @@
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTaskGroup.h"
#include "tools/ToolUtils.h"
#include "tools/timer/AnimTimer.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// Static text from paths.
@ -164,15 +163,15 @@ public:
fLastTick = 0;
}
bool onAnimate(const AnimTimer& timer) final {
bool onAnimate(double nanos) final {
fBackgroundAnimationTask.wait();
this->swapAnimationBuffers();
const double tsec = timer.secs();
const double dt = fLastTick ? (timer.secs() - fLastTick) : 0;
const double tsec = 1e-9 * nanos;
const double dt = fLastTick ? (1e-9 * nanos - fLastTick) : 0;
fBackgroundAnimationTask.add(std::bind(&MovingPathText::runAnimationTask, this, tsec,
dt, this->width(), this->height()));
fLastTick = timer.secs();
fLastTick = 1e-9 * nanos;
return true;
}

View File

@ -17,7 +17,6 @@
#include "src/core/SkBlurMask.h"
#include "src/utils/SkUTF.h"
#include "tools/ToolUtils.h"
#include "tools/timer/AnimTimer.h"
////////////////////////////////////////////////////////////////////////////

View File

@ -11,7 +11,6 @@
#include "include/core/SkSurface.h"
#include "samplecode/Sample.h"
#include "tools/Resources.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/Timer.h"
#include <stdio.h>
@ -150,8 +149,8 @@ protected:
#if 0
// TODO: switch over to use this for our animation
bool onAnimate(const AnimTimer& timer) override {
SkScalar angle = SkDoubleToScalar(fmod(timer.secs() * 360 / 24, 360));
bool onAnimate(double nanos) override {
SkScalar angle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 24, 360));
fAnimatingDrawable->setSweep(angle);
return true;
}

View File

@ -13,7 +13,6 @@
#include "include/core/SkImage.h"
#include "include/core/SkPath.h"
#include "include/core/SkSurface.h"
#include "tools/timer/AnimTimer.h"
namespace skiagm {
@ -316,8 +315,8 @@ protected:
this->drawShapes(canvas, "SSx64", 4, fSS16);
}
bool onAnimate(const AnimTimer& timer) override {
SkScalar t = timer.secs();
bool onAnimate(double nanos) override {
SkScalar t = 1e-9 * nanos;
SkScalar dt = fLastFrameTime < 0.f ? 0.f : t - fLastFrameTime;
fLastFrameTime = t;

View File

@ -15,7 +15,6 @@
#include "include/utils/SkRandom.h"
#include "include/utils/SkTextUtils.h"
#include "samplecode/Sample.h"
#include "tools/timer/AnimTimer.h"
const SkBlendMode gModes[] = {
SkBlendMode::kSrcOver,

View File

@ -1,166 +0,0 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkScalar.h"
#include "include/core/SkTime.h"
#ifndef AnimTimer_DEFINED
#define AnimTimer_DEFINED
/**
* Class to track a "timer". It supports 3 states: stopped, paused, and running.
* Playback speed is variable.
*
* The caller must call updateTime() to resync with the clock (typically just before
* using the timer). Forcing the caller to do this ensures that the timer's return values
* are consistent if called repeatedly, as they only reflect the time since the last
* calle to updateTimer().
*/
class AnimTimer {
public:
enum State { kStopped_State, kPaused_State, kRunning_State };
/**
* Class begins in the "stopped" state.
*/
AnimTimer() : fPreviousNanos(0), fElapsedNanos(0), fSpeed(1), fState(kStopped_State) {}
AnimTimer(double elapsed)
: fPreviousNanos(0), fElapsedNanos(elapsed), fSpeed(1), fState(kRunning_State) {}
bool isStopped() const { return kStopped_State == fState; }
bool isRunning() const { return kRunning_State == fState; }
bool isPaused() const { return kPaused_State == fState; }
/**
* Stops the timer, and resets it, such that the next call to run or togglePauseResume
* will begin at time 0.
*/
void stop() { this->setState(kStopped_State); }
/**
* If the timer is paused or stopped, it will resume (or start if it was stopped).
*/
void run() { this->setState(kRunning_State); }
/**
* Control the rate at which time advances.
*/
float getSpeed() const { return fSpeed; }
void setSpeed(float speed) { fSpeed = speed; }
/**
* If the timer is stopped, start running, else it toggles between paused and running.
*/
void togglePauseResume() {
if (kRunning_State == fState) {
this->setState(kPaused_State);
} else {
this->setState(kRunning_State);
}
}
/**
* Call this each time you want to sample the clock for the timer. This is NOT done
* automatically, so that repeated calls to msec() or secs() will always return the
* same value.
*
* This may safely be called with the timer in any state.
*/
void updateTime() {
if (kRunning_State == fState) {
double now = SkTime::GetNSecs();
fElapsedNanos += (now - fPreviousNanos) * fSpeed;
fPreviousNanos = now;
}
}
/**
* Return the time in milliseconds the timer has been in the running state.
* Returns 0 if the timer is stopped. Behavior is undefined if the timer
* has been running longer than SK_MSecMax.
*/
SkMSec msec() const {
const double msec = fElapsedNanos * 1e-6;
SkASSERT(SK_MSecMax >= msec);
return static_cast<SkMSec>(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 fElapsedNanos * 1e-9; }
/**
* Return the time in seconds the timer has been in the running state,
* scaled by "speed" and (if not zero) mod by period.
* Returns 0 if the timer is stopped.
*/
SkScalar scaled(SkScalar speed, SkScalar period = 0) const {
double value = this->secs() * speed;
if (period) {
value = ::fmod(value, SkScalarToDouble(period));
}
return SkDoubleToScalar(value);
}
/**
* Transitions from ends->mid->ends linearly over period seconds. The phase specifies a phase
* shift in seconds.
*/
SkScalar pingPong(SkScalar period, SkScalar phase, SkScalar ends, SkScalar mid) const {
return PingPong(this->secs(), period, phase, ends, mid);
}
/** Helper for computing a ping-pong value without a AnimTimer object. */
static SkScalar PingPong(double t,
SkScalar period,
SkScalar phase,
SkScalar ends,
SkScalar mid) {
double value = ::fmod(t + phase, period);
double half = period / 2.0;
double diff = ::fabs(value - half);
return SkDoubleToScalar(ends + (1.0 - diff / half) * (mid - ends));
}
private:
double fPreviousNanos;
double fElapsedNanos;
float fSpeed;
State fState;
void setState(State newState) {
switch (newState) {
case kStopped_State:
fPreviousNanos = fElapsedNanos = 0;
fState = kStopped_State;
break;
case kPaused_State:
if (kRunning_State == fState) {
fState = kPaused_State;
} // else stay stopped or paused
break;
case kRunning_State:
switch (fState) {
case kStopped_State:
fPreviousNanos = SkTime::GetNSecs();
fElapsedNanos = 0;
break;
case kPaused_State: // they want "resume"
fPreviousNanos = SkTime::GetNSecs();
break;
case kRunning_State: break;
}
fState = kRunning_State;
break;
}
}
};
#endif

47
tools/timer/TimeUtils.h Normal file
View File

@ -0,0 +1,47 @@
// Copyright 2019 Google LLC
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TimeUtils_DEFINED
#define TimeUtils_DEFINED
#include "include/core/SkTypes.h"
#include <cmath>
namespace TimeUtils {
// Returns 0 if the timer is stopped. Behavior is undefined if the timer
// has been running longer than SK_MSecMax.
static inline SkMSec NanosToMSec(double nanos) {
const double msec = nanos * 1e-6;
SkASSERT(SK_MSecMax >= msec);
return static_cast<SkMSec>(msec);
}
static inline double NanosToSeconds(double nanos) {
return nanos * 1e-9;
}
// Return the time scaled by "speed" and (if not zero) mod by period.
static inline float Scaled(float time, float speed, float period = 0) {
double value = time * speed;
if (period) {
value = ::fmod(value, (double)(period));
}
return (float)value;
}
// Transitions from ends->mid->ends linearly over period time. The phase
// specifies a phase shift in time units.
static inline float PingPong(double time,
float period,
float phase,
float ends,
float mid) {
double value = ::fmod(time + phase, period);
double half = period / 2.0;
double diff = ::fabs(value - half);
return (float)(ends + (1.0 - diff / half) * (mid - ends));
}
} // namespace TimeUtils
#endif

98
tools/viewer/AnimTimer.h Normal file
View File

@ -0,0 +1,98 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkScalar.h"
#include "include/core/SkTime.h"
#ifndef AnimTimer_DEFINED
#define AnimTimer_DEFINED
/**
* Class to track a "timer". It supports 3 states: stopped, paused, and running.
* Playback speed is variable.
*
* The caller must call updateTime() to resync with the clock (typically just before
* using the timer). Forcing the caller to do this ensures that the timer's return values
* are consistent if called repeatedly, as they only reflect the time since the last
* calle to updateTimer().
*/
class AnimTimer {
public:
/**
* Class begins in the "stopped" state.
*/
AnimTimer() {}
enum State { kStopped_State, kPaused_State, kRunning_State };
State state() const { return fState; }
double nanos() const { return fElapsedNanos; }
/**
* Control the rate at which time advances.
*/
float getSpeed() const { return fSpeed; }
void setSpeed(float speed) { fSpeed = speed; }
/**
* If the timer is paused or stopped, it will resume (or start if it was stopped).
*/
void run() {
switch (this->state()) {
case kStopped_State:
fPreviousNanos = SkTime::GetNSecs();
fElapsedNanos = 0;
break;
case kPaused_State: // they want "resume"
fPreviousNanos = SkTime::GetNSecs();
break;
case kRunning_State: break;
}
fState = kRunning_State;
}
void pause() {
if (kRunning_State == this->state()) {
fState = kPaused_State;
} // else stay stopped or paused
}
/**
* If the timer is stopped, start running, else it toggles between paused and running.
*/
void togglePauseResume() {
if (kRunning_State == this->state()) {
this->pause();
} else {
this->run();
}
}
/**
* Call this each time you want to sample the clock for the timer. This is NOT done
* automatically, so that repeated calls to msec() or secs() will always return the
* same value.
*
* This may safely be called with the timer in any state.
*/
void updateTime() {
if (kRunning_State == this->state()) {
double now = SkTime::GetNSecs();
fElapsedNanos += (now - fPreviousNanos) * fSpeed;
fPreviousNanos = now;
}
}
private:
double fPreviousNanos = 0;
double fElapsedNanos = 0;
float fSpeed = 1;
State fState = kStopped_State;
};
#endif

View File

@ -27,7 +27,7 @@ void GMSlide::draw(SkCanvas* canvas) {
fGM->drawContent(canvas);
}
bool GMSlide::animate(const AnimTimer& timer) { return fGM->animate(timer); }
bool GMSlide::animate(double nanos) { return fGM->animate(nanos); }
bool GMSlide::onChar(SkUnichar c) { return fGM->onChar(c); }

View File

@ -19,7 +19,7 @@ public:
SkISize getDimensions() const override { return fGM->getISize(); }
void draw(SkCanvas* canvas) override;
bool animate(const AnimTimer&) override;
bool animate(double nanos) override;
bool onChar(SkUnichar c) override;

View File

@ -15,7 +15,6 @@
#include "src/core/SkOSFile.h"
#include "src/utils/SkOSPath.h"
#include "tools/Resources.h"
#include "tools/timer/AnimTimer.h"
#include "tools/viewer/ImGuiLayer.h"
#include "imgui.h"
@ -282,9 +281,9 @@ void ParticlesSlide::draw(SkCanvas* canvas) {
SkGuiVisitor gui;
for (int i = 0; i < fLoaded.count(); ++i) {
ImGui::PushID(i);
if (fTimer && ImGui::Button("Play")) {
if (fAnimated && ImGui::Button("Play")) {
sk_sp<SkParticleEffect> effect(new SkParticleEffect(fLoaded[i].fParams, fRandom));
effect->start(fTimer->secs(), looped);
effect->start(fAnimationTime, looped);
fRunning.push_back({ fPlayPosition, fLoaded[i].fName, effect });
}
ImGui::SameLine();
@ -339,10 +338,11 @@ void ParticlesSlide::draw(SkCanvas* canvas) {
}
}
bool ParticlesSlide::animate(const AnimTimer& timer) {
fTimer = &timer;
bool ParticlesSlide::animate(double nanos) {
fAnimated = true;
fAnimationTime = 1e-9 * nanos;
for (const auto& effect : fRunning) {
effect.fEffect->update(timer.secs());
effect.fEffect->update(fAnimationTime);
}
return true;
}

View File

@ -14,7 +14,6 @@
#include "include/private/SkTArray.h"
#include "include/utils/SkRandom.h"
class AnimTimer;
class SkParticleEffect;
class SkParticleEffectParams;
@ -27,7 +26,7 @@ public:
void load(SkScalar winWidth, SkScalar winHeight) override;
void draw(SkCanvas* canvas) override;
bool animate(const AnimTimer& timer) override;
bool animate(double) override;
bool onMouse(SkScalar x, SkScalar y, sk_app::Window::InputState state,
ModifierKey modifiers) override;
@ -36,7 +35,8 @@ private:
void loadEffects(const char* dirname);
SkRandom fRandom;
const AnimTimer* fTimer;
bool fAnimated = false;
double fAnimationTime = 0;
SkPoint fPlayPosition;
struct LoadedEffect {

View File

@ -27,6 +27,8 @@ SkISize SampleSlide::getDimensions() const {
return SkISize::Make(SkScalarCeilToInt(fSample->width()), SkScalarCeilToInt(fSample->height()));
}
bool SampleSlide::animate(double nanos) { return fSample->animate(nanos); }
void SampleSlide::draw(SkCanvas* canvas) {
SkASSERT(fSample);
fSample->draw(canvas);

View File

@ -24,7 +24,7 @@ public:
fSample->setSize(winWidth, winHeight);
}
void unload() override;
bool animate(const AnimTimer& timer) override { return fSample->animate(timer); }
bool animate(double) override;
bool onChar(SkUnichar c) override;
bool onMouse(SkScalar x, SkScalar y, sk_app::Window::InputState state,

View File

@ -14,7 +14,7 @@
#include "modules/skottie/include/Skottie.h"
#include "modules/skottie/utils/SkottieUtils.h"
#include "src/utils/SkOSPath.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
#include <cmath>
@ -136,14 +136,15 @@ void SkottieSlide::draw(SkCanvas* canvas) {
}
}
bool SkottieSlide::animate(const AnimTimer& timer) {
bool SkottieSlide::animate(double nanos) {
SkMSec msec = TimeUtils::NanosToMSec(nanos);
if (fTimeBase == 0) {
// Reset the animation time.
fTimeBase = timer.msec();
fTimeBase = msec;
}
if (fAnimation) {
const auto t = timer.msec() - fTimeBase;
const auto t = msec - fTimeBase;
const auto d = fAnimation->duration() * 1000;
fAnimation->seek(std::fmod(t, d) / d);
}

View File

@ -26,7 +26,7 @@ public:
SkISize getDimensions() const override;
void draw(SkCanvas*) override;
bool animate(const AnimTimer&) override;
bool animate(double) override;
bool onChar(SkUnichar) override;
bool onMouse(SkScalar x, SkScalar y, sk_app::Window::InputState, ModifierKey modifiers) override;

View File

@ -14,7 +14,6 @@
#include "tools/sk_app/Window.h"
class SkCanvas;
class AnimTimer;
class SkMetaData;
class Slide : public SkRefCnt {
@ -24,7 +23,7 @@ public:
virtual SkISize getDimensions() const = 0;
virtual void draw(SkCanvas* canvas) = 0;
virtual bool animate(const AnimTimer&) { return false; }
virtual bool animate(double nanos) { return false; }
virtual void load(SkScalar winWidth, SkScalar winHeight) {}
virtual void resize(SkScalar winWidth, SkScalar winHeight) {}
virtual void unload() {}

View File

@ -20,7 +20,7 @@
#include "modules/sksg/include/SkSGText.h"
#include "modules/sksg/include/SkSGTransform.h"
#include "src/core/SkMakeUnique.h"
#include "tools/timer/AnimTimer.h"
#include "tools/timer/TimeUtils.h"
#include <cmath>
#include <utility>
@ -84,7 +84,7 @@ protected:
private:
void tick(SkMSec t) {
fSlide->animate(AnimTimer(t * 1e6));
fSlide->animate(t * 1e6);
this->invalidate();
}
@ -353,13 +353,14 @@ void SlideDir::draw(SkCanvas* canvas) {
fScene->render(canvas);
}
bool SlideDir::animate(const AnimTimer& timer) {
bool SlideDir::animate(double nanos) {
SkMSec msec = TimeUtils::NanosToMSec(nanos);
if (fTimeBase == 0) {
// Reset the animation time.
fTimeBase = timer.msec();
fTimeBase = msec;
}
const auto t = timer.msec() - fTimeBase;
const auto t = msec - fTimeBase;
fScene->animate(t);
fFocusController->tick(t);

View File

@ -33,7 +33,7 @@ protected:
SkISize getDimensions() const override;
void draw(SkCanvas*) override;
bool animate(const AnimTimer&) override;
bool animate(double) override;
bool onChar(SkUnichar) override;
bool onMouse(SkScalar x, SkScalar y, sk_app::Window::InputState, ModifierKey modifiers) override;

View File

@ -1952,7 +1952,7 @@ void Viewer::drawImGui() {
}
if (ImGui::CollapsingHeader("Animation")) {
bool isPaused = fAnimTimer.isPaused();
bool isPaused = AnimTimer::kPaused_State == fAnimTimer.state();
if (ImGui::Checkbox("Pause", &isPaused)) {
fAnimTimer.togglePauseResume();
}
@ -2154,7 +2154,7 @@ void Viewer::onIdle() {
fStatsLayer.beginTiming(fAnimateTimer);
fAnimTimer.updateTime();
bool animateWantsInval = fSlides[fCurrentSlide]->animate(fAnimTimer);
bool animateWantsInval = fSlides[fCurrentSlide]->animate(fAnimTimer.nanos());
fStatsLayer.endTiming(fAnimateTimer);
ImGuiIO& io = ImGui::GetIO();

View File

@ -18,7 +18,7 @@
#include "tools/sk_app/Application.h"
#include "tools/sk_app/CommandSet.h"
#include "tools/sk_app/Window.h"
#include "tools/timer/AnimTimer.h"
#include "tools/viewer/AnimTimer.h"
#include "tools/viewer/ImGuiLayer.h"
#include "tools/viewer/Slide.h"
#include "tools/viewer/StatsLayer.h"