1261c3ad7fde95748da92550735decc949dc73bf2joshualitt/*
2261c3ad7fde95748da92550735decc949dc73bf2joshualitt * Copyright 2015 Google Inc.
3261c3ad7fde95748da92550735decc949dc73bf2joshualitt *
4261c3ad7fde95748da92550735decc949dc73bf2joshualitt * Use of this source code is governed by a BSD-style license that can be
5261c3ad7fde95748da92550735decc949dc73bf2joshualitt * found in the LICENSE file.
6261c3ad7fde95748da92550735decc949dc73bf2joshualitt */
7261c3ad7fde95748da92550735decc949dc73bf2joshualitt
8261c3ad7fde95748da92550735decc949dc73bf2joshualitt#include "SKPAnimationBench.h"
9261c3ad7fde95748da92550735decc949dc73bf2joshualitt#include "SkCommandLineFlags.h"
10261c3ad7fde95748da92550735decc949dc73bf2joshualitt#include "SkMultiPictureDraw.h"
11261c3ad7fde95748da92550735decc949dc73bf2joshualitt#include "SkSurface.h"
12261c3ad7fde95748da92550735decc949dc73bf2joshualitt
13b4022965a280dd1ed64d6103dd29e2189abe6e00cdaltonSKPAnimationBench::SKPAnimationBench(const char* name, const SkPicture* pic, const SkIRect& clip,
1463a82855b1f0b83952b65fca330954c50ebe7a4bcdalton                                     Animation* animation, bool doLooping)
15b4022965a280dd1ed64d6103dd29e2189abe6e00cdalton    : INHERITED(name, pic, clip, 1.0, false, doLooping)
1663a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    , fAnimation(SkRef(animation)) {
1763a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    fUniqueName.printf("%s_%s", name, fAnimation->getTag());
18261c3ad7fde95748da92550735decc949dc73bf2joshualitt}
19261c3ad7fde95748da92550735decc949dc73bf2joshualitt
20261c3ad7fde95748da92550735decc949dc73bf2joshualittconst char* SKPAnimationBench::onGetUniqueName() {
21261c3ad7fde95748da92550735decc949dc73bf2joshualitt    return fUniqueName.c_str();
22261c3ad7fde95748da92550735decc949dc73bf2joshualitt}
23261c3ad7fde95748da92550735decc949dc73bf2joshualitt
24261c3ad7fde95748da92550735decc949dc73bf2joshualittvoid SKPAnimationBench::onPerCanvasPreDraw(SkCanvas* canvas) {
25261c3ad7fde95748da92550735decc949dc73bf2joshualitt    INHERITED::onPerCanvasPreDraw(canvas);
26918e144408ba218df919528f8b48c544f4767883Mike Reed    fDevBounds = canvas->getDeviceClipBounds();
27918e144408ba218df919528f8b48c544f4767883Mike Reed    SkAssertResult(!fDevBounds.isEmpty());
2863a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    fAnimationTimer.start();
29261c3ad7fde95748da92550735decc949dc73bf2joshualitt}
30261c3ad7fde95748da92550735decc949dc73bf2joshualitt
31261c3ad7fde95748da92550735decc949dc73bf2joshualittvoid SKPAnimationBench::drawPicture() {
3263a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    fAnimationTimer.end();
3363a82855b1f0b83952b65fca330954c50ebe7a4bcdalton
3463a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    for (int j = 0; j < this->tileRects().count(); ++j) {
3563a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        SkMatrix trans = SkMatrix::MakeTrans(-1.f * this->tileRects()[j].fLeft,
3663a82855b1f0b83952b65fca330954c50ebe7a4bcdalton                                             -1.f * this->tileRects()[j].fTop);
3763a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        fAnimation->preConcatFrameMatrix(fAnimationTimer.fWall, fDevBounds, &trans);
3896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        this->surfaces()[j]->getCanvas()->drawPicture(this->picture(), &trans, nullptr);
39261c3ad7fde95748da92550735decc949dc73bf2joshualitt    }
4063a82855b1f0b83952b65fca330954c50ebe7a4bcdalton
4163a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    for (int j = 0; j < this->tileRects().count(); ++j) {
4263a82855b1f0b83952b65fca330954c50ebe7a4bcdalton       this->surfaces()[j]->getCanvas()->flush();
4363a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    }
4463a82855b1f0b83952b65fca330954c50ebe7a4bcdalton}
4563a82855b1f0b83952b65fca330954c50ebe7a4bcdalton
4663a82855b1f0b83952b65fca330954c50ebe7a4bcdaltonclass ZoomAnimation : public SKPAnimationBench::Animation {
4763a82855b1f0b83952b65fca330954c50ebe7a4bcdaltonpublic:
4863a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    ZoomAnimation(SkScalar zoomMax, double zoomPeriodMs)
4963a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        : fZoomMax(zoomMax)
5063a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        , fZoomPeriodMs(zoomPeriodMs) {
5163a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    }
5263a82855b1f0b83952b65fca330954c50ebe7a4bcdalton
5363a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    virtual const char* getTag() { return "zoom"; }
5463a82855b1f0b83952b65fca330954c50ebe7a4bcdalton
5563a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    virtual void preConcatFrameMatrix(double animationTimeMs, const SkIRect& devBounds,
5663a82855b1f0b83952b65fca330954c50ebe7a4bcdalton                                      SkMatrix* drawMatrix) {
5763a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        double t = fmod(animationTimeMs / fZoomPeriodMs, 1.0); // t is in [0, 1).
5863a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        t = fabs(2 * t - 1); // Make t ping-pong between 0 and 1
5963a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        SkScalar zoom = static_cast<SkScalar>(pow(fZoomMax, t));
6063a82855b1f0b83952b65fca330954c50ebe7a4bcdalton
6163a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        SkPoint center = SkPoint::Make((devBounds.fLeft + devBounds.fRight) / 2.0f,
6263a82855b1f0b83952b65fca330954c50ebe7a4bcdalton                                       (devBounds.fTop + devBounds.fBottom) / 2.0f);
6363a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        drawMatrix->preTranslate(center.fX, center.fY);
6463a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        drawMatrix->preScale(zoom, zoom);
6563a82855b1f0b83952b65fca330954c50ebe7a4bcdalton        drawMatrix->preTranslate(-center.fX, -center.fY);
6663a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    }
6763a82855b1f0b83952b65fca330954c50ebe7a4bcdalton
6863a82855b1f0b83952b65fca330954c50ebe7a4bcdaltonprivate:
6963a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    double   fZoomMax;
7063a82855b1f0b83952b65fca330954c50ebe7a4bcdalton    double   fZoomPeriodMs;
7163a82855b1f0b83952b65fca330954c50ebe7a4bcdalton};
7263a82855b1f0b83952b65fca330954c50ebe7a4bcdalton
7363a82855b1f0b83952b65fca330954c50ebe7a4bcdaltonSKPAnimationBench::Animation* SKPAnimationBench::CreateZoomAnimation(SkScalar zoomMax,
7463a82855b1f0b83952b65fca330954c50ebe7a4bcdalton                                                                     double zoomPeriodMs) {
75385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new ZoomAnimation(zoomMax, zoomPeriodMs);
76261c3ad7fde95748da92550735decc949dc73bf2joshualitt}
77