180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkAnimateActive.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkAnimateBase.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkAnimateMaker.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkAnimateSet.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkDrawGroup.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTime.h"
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// SkActive holds array of interpolators
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkActive::SkActive(SkApply& apply, SkAnimateMaker& maker) : fApply(apply),
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMaxTime(0), fMaker(maker), fDrawIndex(0), fDrawMax(0) {
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::init()
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fAnimators = fApply.fAnimators;
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int animators = fAnimators.count();
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fInterpolators.setCount(animators);
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memset(fInterpolators.begin(), 0, animators * sizeof(SkOperandInterpolator*));
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fState.setCount(animators);
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int index;
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < animators; index++)
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fInterpolators[index] = SkNEW(SkOperandInterpolator);
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    initState(&fApply, 0);
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  for (index = 0; index < animators; index++)
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      fState[index].bumpSave();
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fInterpolators.count() == fAnimators.count());
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkActive::~SkActive() {
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int index;
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fSaveRestore.count(); index++)
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        delete[] fSaveRestore[index];
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fSaveInterpolators.count(); index++)
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        delete[] fSaveInterpolators[index];
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < fInterpolators.count(); index++)
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        delete fInterpolators[index];
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::advance() {
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fDrawMax < fDrawIndex)
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fDrawMax = fDrawIndex;
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fDrawIndex += fAnimators.count();
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::append(SkApply* apply) {
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int oldCount = fAnimators.count();
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTDAnimateArray& animates = apply->fAnimators;
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int newCount = animates.count();
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int index;
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int total = oldCount + newCount;
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (total == 0)
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fInterpolators.setCount(total);
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memset(&fInterpolators.begin()[oldCount], 0, newCount * sizeof(SkOperandInterpolator*));
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = oldCount; index < total; index++)
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fInterpolators[index] = SkNEW(SkOperandInterpolator);
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fAnimators.setCount(total);
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memcpy(&fAnimators[oldCount], animates.begin(), sizeof(fAnimators[0]) *
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        newCount);
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fState.setCount(total);
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    initState(apply, oldCount);
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fApply.scope == apply->scope);
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < newCount; index++) {
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* test = animates[index];
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      SkASSERT(fApply.scope == test->fTarget || fApply.scope->contains(test->fTarget));
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkActive::SkState& testState = fState[oldCount + index];
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int inner = 0; inner < oldCount; inner++) {
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkAnimateBase* oldGuard = fAnimators[inner];
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkActive::SkState& oldState = fState[inner];
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (oldGuard->fTarget == test->fTarget && oldGuard->fFieldInfo == test->fFieldInfo &&
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    testState.fBegin == oldState.fBegin) {
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                delete fInterpolators[inner];
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fInterpolators.remove(inner);
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fAnimators.remove(inner);
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                testState.fSave = oldState.fSave;
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (oldState.fUnpostedEndEvent) {
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//                  SkDEBUGF(("%8x %8x active append: post on end\n", this, oldGuard));
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    fMaker.postOnEnd(oldGuard, oldState.fBegin + oldState.fDuration);
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fState.remove(inner);
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (fApply.restore) {
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    int saveIndex = fSaveRestore.count();
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    SkASSERT(fSaveInterpolators.count() == saveIndex);
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    saveIndex += inner;
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    do {
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        saveIndex -= oldCount;
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        delete[] fSaveRestore[saveIndex];
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        fSaveRestore.remove(saveIndex);
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        delete[] fSaveInterpolators[saveIndex];
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        fSaveInterpolators.remove(saveIndex);
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    } while (saveIndex > 0);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                oldCount--;
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  total = oldCount + newCount;
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  for (index = oldCount; index < total; index++)
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      fState[index].bumpSave();
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fInterpolators.count() == fAnimators.count());
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::appendSave(int oldCount) {
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fDrawMax == 0);    // if true, we can optimize below quite a bit
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int newCount = fAnimators.count();
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int saveIndex = fSaveRestore.count();
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fSaveInterpolators.count() == saveIndex);
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int records = saveIndex / oldCount;
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int newTotal = records * newCount;
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fSaveRestore.setCount(newTotal);
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    do {
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        saveIndex -= oldCount;
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        newTotal -= newCount;
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(saveIndex >= 0);
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(newTotal >= 0);
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memmove(&fSaveRestore[newTotal], &fSaveRestore[saveIndex], oldCount);
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memset(&fSaveRestore[newTotal + oldCount], 0,
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            sizeof(fSaveRestore[0]) * (newCount - oldCount));
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memmove(&fSaveInterpolators[newTotal],
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            &fSaveInterpolators[saveIndex], oldCount);
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memset(&fSaveInterpolators[newTotal + oldCount], 0,
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            sizeof(fSaveRestore[0]) * (newCount - oldCount));
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } while (saveIndex > 0);
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(newTotal == 0);
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::calcDurations(int index)
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAnimateBase* animate = fAnimators[index];
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMSec duration = animate->dur;
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkState& state = fState[index];
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch (state.fMode) {
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      case SkApply::kMode_immediate:
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      case SkApply::kMode_create:
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        duration = state.fSteps ? state.fSteps * SK_MSec1 : 1;
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//    case SkApply::kMode_hold: {
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      int entries = animate->entries();
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      SkScriptValue value;
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      value.fOperand = animate->getValues()[entries - 1];
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      value.fType = animate->getValuesType();
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      bool result = SkScriptEngine::ConvertTo(NULL, SkType_Int, &value);
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      SkASSERT(result);
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      duration = value.fOperand.fS32 * SK_MSec1;
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      break;
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//    }
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    state.fDuration = duration;
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMSec maxTime = state.fBegin + duration;
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fMaxTime < maxTime)
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fMaxTime = maxTime;
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::create(SkDrawable* drawable, SkMSec time) {
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fApply.fLastTime = time;
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fApply.refresh(fMaker);
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < fAnimators.count(); index++) {
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* animate = fAnimators[index];
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkOperandInterpolator& interpolator = *fInterpolators[index];
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int count = animate->components();
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (animate->formula.size() > 0) {
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkTDOperandArray values;
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            values.setCount(count);
177d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            SkDEBUGCODE(bool success = ) animate->fFieldInfo->setValue(fMaker, &values, 0, 0, NULL,
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                animate->getValuesType(), animate->formula);
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkASSERT(success);
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fApply.applyValues(index, values.begin(), count, animate->getValuesType(), time);
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkAutoSTMalloc<16, SkOperand> values(count);
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            interpolator.timeToValues(time, values.get());
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fApply.applyValues(index, values.get(), count, animate->getValuesType(), time);
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    drawable->enable(fMaker);
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fAnimators.count() == fInterpolators.count());
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkActive::immediate(bool enable) {
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMSec time = 0;
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool result = false;
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDrawable* drawable = fApply.scope;
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMSec final = fMaxTime;
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    do {
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool applied = fAnimators.count() == 0;
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fApply.fLastTime = time;
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fApply.refresh(fMaker);
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int index = 0; index < fAnimators.count(); index++) {
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkAnimateBase* animate = fAnimators[index];
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkState& state = fState[index];
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (state.fMode != SkApply::kMode_immediate)
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                continue;
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (state.fBegin > time)
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                continue;
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (time > state.fBegin + state.fDuration)
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                continue;
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            applied = true;
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkOperandInterpolator& interpolator = *fInterpolators[index];
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int count = animate->components();
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (animate->formula.size() > 0) {
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkTDOperandArray values;
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                values.setCount(count);
215d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                SkDEBUGCODE(bool success = ) animate->fFieldInfo->setValue(fMaker, &values, 0, 0, NULL,
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    animate->getValuesType(), animate->formula);
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkASSERT(success);
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fApply.applyValues(index, values.begin(), count, animate->getValuesType(), time);
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else {
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkAutoSTMalloc<16, SkOperand> values(count);
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                interpolator.timeToValues(time, values.get());
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fApply.applyValues(index, values.get(), count, animate->getValuesType(), time);
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (enable)
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            drawable->enable(fMaker);
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        else if (applied)
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            result |= drawable->draw(fMaker);
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        time += SK_MSec1;
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } while (time <= final);
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return result;
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::fixInterpolator(SkBool save) {
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int animators = fAnimators.count();
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < animators; index++) {
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* animate = fAnimators[index];
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (save) { // saved slots increased
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            animate->refresh(fMaker);
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkOperand* values = animate->getValues();
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            setInterpolator(index, values);
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            saveInterpolatorValues(index);
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            restoreInterpolatorValues(index);
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkMSec SkActive::getTime(SkMSec inTime, int animatorIndex) {
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fState[animatorIndex].fTicks = inTime;
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return inTime - fState[animatorIndex].fStartTime;
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkActive::initializeSave() {
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int animators = fAnimators.count();
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int activeTotal = fDrawIndex + animators;
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int oldCount = fSaveRestore.count();
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (oldCount < activeTotal) {
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fSaveRestore.setCount(activeTotal);
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memset(&fSaveRestore[oldCount], 0, sizeof(fSaveRestore[0]) * (activeTotal - oldCount));
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fSaveInterpolators.count() == oldCount);
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fSaveInterpolators.setCount(activeTotal);
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memset(&fSaveInterpolators[oldCount], 0,
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            sizeof(fSaveInterpolators[0]) * (activeTotal - oldCount));
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return false;
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::initState(SkApply* apply, int offset) {
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = fState.count();
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = offset; index < count; index++) {
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkState& state = fState[index];
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* animate = fAnimators[index];
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 // def SK_DEBUG
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (animate->fHasEndEvent)
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkDebugf("%8x %8x active initState:\n", this, animate);
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkOperand* from = animate->getValues();
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fStartTime = state.fBegin = apply->begin + animate->begin;
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fMode = apply->mode;
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fTransition = apply->transition;
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fPickup = (SkBool8) apply->pickup;
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fRestore = (SkBool8) apply->restore;
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fSave = apply->begin;
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fStarted = false;
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fSteps = apply->steps;
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fTicks = 0;
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fUnpostedEndEvent = (SkBool8) animate->fHasEndEvent;
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        calcDurations(index);
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        setInterpolator(index, from);
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (count == 0 && (apply->mode == SkApply::kMode_immediate || apply->mode == SkApply::kMode_create))
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fMaxTime = apply->begin + apply->steps * SK_MSec1;
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::pickUp(SkActive* existing) {
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTDOperandArray existingValues;
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < fAnimators.count(); index++) {
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* animate = fAnimators[index];
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(animate->getValuesType() == SkType_Float);
30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int components = animate->components();
30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkOperand* from = animate->getValues();
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkOperand* to = &from[animate->components()];
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        existingValues.setCount(components);
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        existing->fInterpolators[index]->timeToValues(
30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            existing->fState[index].fTicks - existing->fState[index].fStartTime, existingValues.begin());
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar originalSum = 0;
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar workingSum = 0;
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int cIndex = 0; cIndex < components; cIndex++) {
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkScalar delta = to[cIndex].fScalar - from[cIndex].fScalar;
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            originalSum += SkScalarMul(delta, delta);
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            delta = to[cIndex].fScalar - existingValues[cIndex].fScalar;
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            workingSum += SkScalarMul(delta, delta);
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (workingSum < originalSum) {
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkScalar originalDistance = SkScalarSqrt(originalSum);
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkScalar workingDistance = SkScalarSqrt(workingSum);
32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            existing->fState[index].fDuration = (SkMSec) SkScalarMulDiv(fState[index].fDuration,
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                workingDistance, originalDistance);
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fInterpolators[index]->reset(components, 2, SkType_Float);
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fInterpolators[index]->setKeyFrame(0, 0, existingValues.begin(), animate->blend[0]);
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fInterpolators[index]->setKeyFrame(1, fState[index].fDuration, to, animate->blend[0]);
32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::resetInterpolators() {
33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int animators = fAnimators.count();
33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < animators; index++) {
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* animate = fAnimators[index];
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkOperand* values = animate->getValues();
33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        setInterpolator(index, values);
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::resetState() {
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fDrawIndex = 0;
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = fState.count();
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < count; index++) {
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkState& state = fState[index];
34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* animate = fAnimators[index];
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 // def SK_DEBUG
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (animate->fHasEndEvent)
34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkDebugf("%8x %8x active resetState: has end event\n", this, animate);
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fStartTime = state.fBegin = fApply.begin + animate->begin;
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fStarted = false;
35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fTicks = 0;
35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::restoreInterpolatorValues(int index) {
35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkOperandInterpolator& interpolator = *fInterpolators[index];
35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    index += fDrawIndex ;
35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = interpolator.getValuesCount();
35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memcpy(interpolator.getValues(), fSaveInterpolators[index], count * sizeof(SkOperand));
35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::saveInterpolatorValues(int index) {
36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkOperandInterpolator& interpolator = *fInterpolators[index];
36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    index += fDrawIndex ;
36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = interpolator.getValuesCount();
36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkOperand* cache = new SkOperand[count];    // this should use sk_malloc/sk_free since SkOperand does not have a constructor/destructor
36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fSaveInterpolators[index] = cache;
36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memcpy(cache,   interpolator.getValues(), count * sizeof(SkOperand));
36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::setInterpolator(int index, SkOperand* from) {
37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (from == NULL) // legitimate for set string
37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAnimateBase* animate = fAnimators[index];
37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int entries = animate->entries();
37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(entries > 0);
37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMSec duration = fState[index].fDuration;
37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int components = animate->components();
37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkOperandInterpolator& interpolator = *fInterpolators[index];
37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    interpolator.reset(components, entries == 1 ? 2 : entries, animate->getValuesType());
38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    interpolator.setMirror(SkToBool(animate->fMirror));
38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    interpolator.setReset(SkToBool(animate->fReset));
38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    interpolator.setRepeatCount(animate->repeat);
38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (entries == 1) {
38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        interpolator.setKeyFrame(0, 0, from, animate->blend[0]);
38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        interpolator.setKeyFrame(1, duration, from, animate->blend[0]);
38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int entry = 0; entry < entries; entry++) {
38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int blendIndex = SkMin32(animate->blend.count() - 1, entry);
39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        interpolator.setKeyFrame(entry, entry * duration / (entries - 1), from,
39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            animate->blend[blendIndex]);
39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        from += components;
39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::setSteps(int steps) {
39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = fState.count();
39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMaxTime = 0;
39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < count; index++) {
40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkState& state = fState[index];
40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fSteps = steps;
40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        calcDurations(index);
40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::start() {
40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = fState.count();
40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(count == fAnimators.count());
40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(count == fInterpolators.count());
41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < count; index++) {
41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkState& state = fState[index];
41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (state.fStarted)
41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            continue;
41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fStarted = true;
41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkString debugOut;
41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkMSec time = fMaker.getAppTime();
41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.appendS32(time - fMaker.fDebugTimeBase);
41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append(" active start adjust delay id=");
42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append(fApply._id);
42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append("; ");
42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append(fAnimators[index]->_id);
42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append("=");
42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.appendS32(fAnimators[index]->fStart - fMaker.fDebugTimeBase);
42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append(":");
42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.appendS32(state.fStartTime);
42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (state.fStartTime > 0) {
42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkMSec future = fAnimators[index]->fStart + state.fStartTime;
43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (future > fMaker.fEnableTime)
43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fMaker.notifyInvalTime(future);
43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            else
43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fMaker.notifyInval();
43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            debugOut.append(":");
43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            debugOut.appendS32(future - fMaker.fDebugTimeBase);
43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (state.fStartTime >= fMaker.fAdjustedStart) {
44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            state.fStartTime -= fMaker.fAdjustedStart;
44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            debugOut.append(" (less adjust = ");
44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            debugOut.appendS32(fMaker.fAdjustedStart);
44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        state.fStartTime += fAnimators[index]->fStart;
44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append(") new start = ");
44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.appendS32(state.fStartTime - fMaker.fDebugTimeBase);
45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("%s\n", debugOut.c_str());
45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      SkASSERT((int) (state.fStartTime - fMaker.fDebugTimeBase) >= 0);
45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fAnimators.count() == fInterpolators.count());
45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkActive::validate() {
45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = fState.count();
46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(count == fAnimators.count());
46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(count == fInterpolators.count());
46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int index = 0; index < count; index++) {
46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fAnimators[index]);
46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(fInterpolators[index]);
46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      SkAnimateBase* test = fAnimators[index];
46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      SkASSERT(fApply.scope == test->fTarget || fApply.scope->contains(test->fTarget));
46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// think about this
47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// there should only be one animate object, not two, to go up and down
47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// when the apply with reverse came into play, it needs to pick up the value
47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// of the existing animate object then remove it from the list
47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// the code below should only be bumping fSave, and there shouldn't be anything
47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// it needs to be synchronized with
47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// however, if there are two animates both operating on the same field, then
47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// when one replaces the other, it may make sense to pick up the old value as a starting
48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// value for the new one somehow.
48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//void SkActive::SkState::bumpSave() {
48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  if (fMode != SkApply::kMode_hold)
48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      return;
48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  if (fTransition == SkApply::kTransition_reverse) {
48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      if (fSave > 0)
48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//          fSave -= SK_MSec1;
48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  } else if (fSave < fDuration)
48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      fSave += SK_MSec1;
49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//}
49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkMSec SkActive::SkState::getRelativeTime(SkMSec time) {
49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMSec result = time;
49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  if (fMode == SkApply::kMode_hold)
49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      result = fSave;
49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  else
49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fTransition == SkApply::kTransition_reverse) {
49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (SkMSec_LT(fDuration, time))
49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            result = 0;
50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        else
50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            result = fDuration - time;
50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
50380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return result;
50480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
505