1
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include "SkAnimateActive.h"
11#include "SkAnimateBase.h"
12#include "SkAnimateMaker.h"
13#include "SkAnimateSet.h"
14#include "SkDrawGroup.h"
15#ifdef SK_DEBUG
16#include "SkTime.h"
17#endif
18
19// SkActive holds array of interpolators
20
21SkActive::SkActive(SkApply& apply, SkAnimateMaker& maker) : fApply(apply),
22    fMaxTime(0), fMaker(maker), fDrawIndex(0), fDrawMax(0) {
23}
24
25void SkActive::init()
26{
27    fAnimators = fApply.fAnimators;
28    int animators = fAnimators.count();
29    fInterpolators.setCount(animators);
30    memset(fInterpolators.begin(), 0, animators * sizeof(SkOperandInterpolator*));
31    fState.setCount(animators);
32    int index;
33    for (index = 0; index < animators; index++)
34        fInterpolators[index] = SkNEW(SkOperandInterpolator);
35    initState(&fApply, 0);
36//  for (index = 0; index < animators; index++)
37//      fState[index].bumpSave();
38    SkASSERT(fInterpolators.count() == fAnimators.count());
39}
40
41SkActive::~SkActive() {
42    int index;
43    for (index = 0; index < fSaveRestore.count(); index++)
44        delete[] fSaveRestore[index];
45    for (index = 0; index < fSaveInterpolators.count(); index++)
46        delete[] fSaveInterpolators[index];
47    for (index = 0; index < fInterpolators.count(); index++)
48        delete fInterpolators[index];
49}
50
51void SkActive::advance() {
52    if (fDrawMax < fDrawIndex)
53        fDrawMax = fDrawIndex;
54    fDrawIndex += fAnimators.count();
55}
56
57void SkActive::append(SkApply* apply) {
58    int oldCount = fAnimators.count();
59    SkTDAnimateArray& animates = apply->fAnimators;
60    int newCount = animates.count();
61    int index;
62    int total = oldCount + newCount;
63    if (total == 0)
64        return;
65    fInterpolators.setCount(total);
66    memset(&fInterpolators.begin()[oldCount], 0, newCount * sizeof(SkOperandInterpolator*));
67    for (index = oldCount; index < total; index++)
68        fInterpolators[index] = SkNEW(SkOperandInterpolator);
69    fAnimators.setCount(total);
70    memcpy(&fAnimators[oldCount], animates.begin(), sizeof(fAnimators[0]) *
71        newCount);
72    fState.setCount(total);
73    initState(apply, oldCount);
74    SkASSERT(fApply.scope == apply->scope);
75    for (index = 0; index < newCount; index++) {
76        SkAnimateBase* test = animates[index];
77//      SkASSERT(fApply.scope == test->fTarget || fApply.scope->contains(test->fTarget));
78        SkActive::SkState& testState = fState[oldCount + index];
79        for (int inner = 0; inner < oldCount; inner++) {
80            SkAnimateBase* oldGuard = fAnimators[inner];
81            SkActive::SkState& oldState = fState[inner];
82            if (oldGuard->fTarget == test->fTarget && oldGuard->fFieldInfo == test->fFieldInfo &&
83                    testState.fBegin == oldState.fBegin) {
84                delete fInterpolators[inner];
85                fInterpolators.remove(inner);
86                fAnimators.remove(inner);
87                testState.fSave = oldState.fSave;
88                if (oldState.fUnpostedEndEvent) {
89//                  SkDEBUGF(("%8x %8x active append: post on end\n", this, oldGuard));
90                    fMaker.postOnEnd(oldGuard, oldState.fBegin + oldState.fDuration);
91                }
92                fState.remove(inner);
93                if (fApply.restore) {
94                    int saveIndex = fSaveRestore.count();
95                    SkASSERT(fSaveInterpolators.count() == saveIndex);
96                    saveIndex += inner;
97                    do {
98                        saveIndex -= oldCount;
99                        delete[] fSaveRestore[saveIndex];
100                        fSaveRestore.remove(saveIndex);
101                        delete[] fSaveInterpolators[saveIndex];
102                        fSaveInterpolators.remove(saveIndex);
103                    } while (saveIndex > 0);
104                }
105                oldCount--;
106                break;
107            }
108        }
109    }
110//  total = oldCount + newCount;
111//  for (index = oldCount; index < total; index++)
112//      fState[index].bumpSave();
113    SkASSERT(fInterpolators.count() == fAnimators.count());
114}
115
116void SkActive::appendSave(int oldCount) {
117    SkASSERT(fDrawMax == 0);    // if true, we can optimize below quite a bit
118    int newCount = fAnimators.count();
119    int saveIndex = fSaveRestore.count();
120    SkASSERT(fSaveInterpolators.count() == saveIndex);
121    int records = saveIndex / oldCount;
122    int newTotal = records * newCount;
123    fSaveRestore.setCount(newTotal);
124    do {
125        saveIndex -= oldCount;
126        newTotal -= newCount;
127        SkASSERT(saveIndex >= 0);
128        SkASSERT(newTotal >= 0);
129        memmove(&fSaveRestore[newTotal], &fSaveRestore[saveIndex], oldCount);
130        memset(&fSaveRestore[newTotal + oldCount], 0,
131            sizeof(fSaveRestore[0]) * (newCount - oldCount));
132        memmove(&fSaveInterpolators[newTotal],
133            &fSaveInterpolators[saveIndex], oldCount);
134        memset(&fSaveInterpolators[newTotal + oldCount], 0,
135            sizeof(fSaveRestore[0]) * (newCount - oldCount));
136    } while (saveIndex > 0);
137    SkASSERT(newTotal == 0);
138}
139
140void SkActive::calcDurations(int index)
141{
142    SkAnimateBase* animate = fAnimators[index];
143    SkMSec duration = animate->dur;
144    SkState& state = fState[index];
145    switch (state.fMode) {
146      case SkApply::kMode_immediate:
147      case SkApply::kMode_create:
148        duration = state.fSteps ? state.fSteps * SK_MSec1 : 1;
149        break;
150//    case SkApply::kMode_hold: {
151//      int entries = animate->entries();
152//      SkScriptValue value;
153//      value.fOperand = animate->getValues()[entries - 1];
154//      value.fType = animate->getValuesType();
155//      bool result = SkScriptEngine::ConvertTo(NULL, SkType_Int, &value);
156//      SkASSERT(result);
157//      duration = value.fOperand.fS32 * SK_MSec1;
158//      break;
159//    }
160    }
161    state.fDuration = duration;
162    SkMSec maxTime = state.fBegin + duration;
163    if (fMaxTime < maxTime)
164        fMaxTime = maxTime;
165}
166
167void SkActive::create(SkDrawable* drawable, SkMSec time) {
168    fApply.fLastTime = time;
169    fApply.refresh(fMaker);
170    for (int index = 0; index < fAnimators.count(); index++) {
171        SkAnimateBase* animate = fAnimators[index];
172        SkOperandInterpolator& interpolator = *fInterpolators[index];
173        int count = animate->components();
174        if (animate->formula.size() > 0) {
175            SkTDOperandArray values;
176            values.setCount(count);
177            SkDEBUGCODE(bool success = ) animate->fFieldInfo->setValue(fMaker, &values, 0, 0, NULL,
178                animate->getValuesType(), animate->formula);
179            SkASSERT(success);
180            fApply.applyValues(index, values.begin(), count, animate->getValuesType(), time);
181        } else {
182            SkAutoSTMalloc<16, SkOperand> values(count);
183            interpolator.timeToValues(time, values.get());
184            fApply.applyValues(index, values.get(), count, animate->getValuesType(), time);
185        }
186    }
187    drawable->enable(fMaker);
188    SkASSERT(fAnimators.count() == fInterpolators.count());
189}
190
191bool SkActive::immediate(bool enable) {
192    SkMSec time = 0;
193    bool result = false;
194    SkDrawable* drawable = fApply.scope;
195    SkMSec final = fMaxTime;
196    do {
197        bool applied = fAnimators.count() == 0;
198        fApply.fLastTime = time;
199        fApply.refresh(fMaker);
200        for (int index = 0; index < fAnimators.count(); index++) {
201            SkAnimateBase* animate = fAnimators[index];
202            SkState& state = fState[index];
203            if (state.fMode != SkApply::kMode_immediate)
204                continue;
205            if (state.fBegin > time)
206                continue;
207            if (time > state.fBegin + state.fDuration)
208                continue;
209            applied = true;
210            SkOperandInterpolator& interpolator = *fInterpolators[index];
211            int count = animate->components();
212            if (animate->formula.size() > 0) {
213                SkTDOperandArray values;
214                values.setCount(count);
215                SkDEBUGCODE(bool success = ) animate->fFieldInfo->setValue(fMaker, &values, 0, 0, NULL,
216                    animate->getValuesType(), animate->formula);
217                SkASSERT(success);
218                fApply.applyValues(index, values.begin(), count, animate->getValuesType(), time);
219            } else {
220                SkAutoSTMalloc<16, SkOperand> values(count);
221                interpolator.timeToValues(time, values.get());
222                fApply.applyValues(index, values.get(), count, animate->getValuesType(), time);
223            }
224        }
225        if (enable)
226            drawable->enable(fMaker);
227        else if (applied)
228            result |= drawable->draw(fMaker);
229        time += SK_MSec1;
230    } while (time <= final);
231    return result;
232}
233
234void SkActive::fixInterpolator(SkBool save) {
235    int animators = fAnimators.count();
236    for (int index = 0; index < animators; index++) {
237        SkAnimateBase* animate = fAnimators[index];
238        if (save) { // saved slots increased
239            animate->refresh(fMaker);
240            SkOperand* values = animate->getValues();
241            setInterpolator(index, values);
242            saveInterpolatorValues(index);
243        } else
244            restoreInterpolatorValues(index);
245    }
246}
247
248SkMSec SkActive::getTime(SkMSec inTime, int animatorIndex) {
249    fState[animatorIndex].fTicks = inTime;
250    return inTime - fState[animatorIndex].fStartTime;
251}
252
253bool SkActive::initializeSave() {
254    int animators = fAnimators.count();
255    int activeTotal = fDrawIndex + animators;
256    int oldCount = fSaveRestore.count();
257    if (oldCount < activeTotal) {
258        fSaveRestore.setCount(activeTotal);
259        memset(&fSaveRestore[oldCount], 0, sizeof(fSaveRestore[0]) * (activeTotal - oldCount));
260        SkASSERT(fSaveInterpolators.count() == oldCount);
261        fSaveInterpolators.setCount(activeTotal);
262        memset(&fSaveInterpolators[oldCount], 0,
263            sizeof(fSaveInterpolators[0]) * (activeTotal - oldCount));
264        return true;
265    }
266    return false;
267}
268
269void SkActive::initState(SkApply* apply, int offset) {
270    int count = fState.count();
271    for (int index = offset; index < count; index++) {
272        SkState& state = fState[index];
273        SkAnimateBase* animate = fAnimators[index];
274#if 0 // def SK_DEBUG
275        if (animate->fHasEndEvent)
276            SkDebugf("%8x %8x active initState:\n", this, animate);
277#endif
278        SkOperand* from = animate->getValues();
279        state.fStartTime = state.fBegin = apply->begin + animate->begin;
280        state.fMode = apply->mode;
281        state.fTransition = apply->transition;
282#if 0
283        state.fPickup = (SkBool8) apply->pickup;
284#endif
285        state.fRestore = (SkBool8) apply->restore;
286        state.fSave = apply->begin;
287        state.fStarted = false;
288        state.fSteps = apply->steps;
289        state.fTicks = 0;
290        state.fUnpostedEndEvent = (SkBool8) animate->fHasEndEvent;
291        calcDurations(index);
292        setInterpolator(index, from);
293    }
294    if (count == 0 && (apply->mode == SkApply::kMode_immediate || apply->mode == SkApply::kMode_create))
295        fMaxTime = apply->begin + apply->steps * SK_MSec1;
296}
297
298void SkActive::pickUp(SkActive* existing) {
299    SkTDOperandArray existingValues;
300    for (int index = 0; index < fAnimators.count(); index++) {
301        SkAnimateBase* animate = fAnimators[index];
302        SkASSERT(animate->getValuesType() == SkType_Float);
303        int components = animate->components();
304        SkOperand* from = animate->getValues();
305        SkOperand* to = &from[animate->components()];
306        existingValues.setCount(components);
307        existing->fInterpolators[index]->timeToValues(
308            existing->fState[index].fTicks - existing->fState[index].fStartTime, existingValues.begin());
309        SkScalar originalSum = 0;
310        SkScalar workingSum = 0;
311        for (int cIndex = 0; cIndex < components; cIndex++) {
312            SkScalar delta = to[cIndex].fScalar - from[cIndex].fScalar;
313            originalSum += SkScalarMul(delta, delta);
314            delta = to[cIndex].fScalar - existingValues[cIndex].fScalar;
315            workingSum += SkScalarMul(delta, delta);
316        }
317        if (workingSum < originalSum) {
318            SkScalar originalDistance = SkScalarSqrt(originalSum);
319            SkScalar workingDistance = SkScalarSqrt(workingSum);
320            existing->fState[index].fDuration = (SkMSec) SkScalarMulDiv(fState[index].fDuration,
321                workingDistance, originalDistance);
322        }
323        fInterpolators[index]->reset(components, 2, SkType_Float);
324        fInterpolators[index]->setKeyFrame(0, 0, existingValues.begin(), animate->blend[0]);
325        fInterpolators[index]->setKeyFrame(1, fState[index].fDuration, to, animate->blend[0]);
326    }
327}
328
329void SkActive::resetInterpolators() {
330    int animators = fAnimators.count();
331    for (int index = 0; index < animators; index++) {
332        SkAnimateBase* animate = fAnimators[index];
333        SkOperand* values = animate->getValues();
334        setInterpolator(index, values);
335    }
336}
337
338void SkActive::resetState() {
339    fDrawIndex = 0;
340    int count = fState.count();
341    for (int index = 0; index < count; index++) {
342        SkState& state = fState[index];
343        SkAnimateBase* animate = fAnimators[index];
344#if 0 // def SK_DEBUG
345        if (animate->fHasEndEvent)
346            SkDebugf("%8x %8x active resetState: has end event\n", this, animate);
347#endif
348        state.fStartTime = state.fBegin = fApply.begin + animate->begin;
349        state.fStarted = false;
350        state.fTicks = 0;
351    }
352}
353
354void SkActive::restoreInterpolatorValues(int index) {
355    SkOperandInterpolator& interpolator = *fInterpolators[index];
356    index += fDrawIndex ;
357    int count = interpolator.getValuesCount();
358    memcpy(interpolator.getValues(), fSaveInterpolators[index], count * sizeof(SkOperand));
359}
360
361void SkActive::saveInterpolatorValues(int index) {
362    SkOperandInterpolator& interpolator = *fInterpolators[index];
363    index += fDrawIndex ;
364    int count = interpolator.getValuesCount();
365    SkOperand* cache = new SkOperand[count];    // this should use sk_malloc/sk_free since SkOperand does not have a constructor/destructor
366    fSaveInterpolators[index] = cache;
367    memcpy(cache,   interpolator.getValues(), count * sizeof(SkOperand));
368}
369
370void SkActive::setInterpolator(int index, SkOperand* from) {
371    if (from == NULL) // legitimate for set string
372        return;
373    SkAnimateBase* animate = fAnimators[index];
374    int entries = animate->entries();
375    SkASSERT(entries > 0);
376    SkMSec duration = fState[index].fDuration;
377    int components = animate->components();
378    SkOperandInterpolator& interpolator = *fInterpolators[index];
379    interpolator.reset(components, entries == 1 ? 2 : entries, animate->getValuesType());
380    interpolator.setMirror(SkToBool(animate->fMirror));
381    interpolator.setReset(SkToBool(animate->fReset));
382    interpolator.setRepeatCount(animate->repeat);
383    if (entries == 1) {
384        interpolator.setKeyFrame(0, 0, from, animate->blend[0]);
385        interpolator.setKeyFrame(1, duration, from, animate->blend[0]);
386        return;
387    }
388    for (int entry = 0; entry < entries; entry++) {
389        int blendIndex = SkMin32(animate->blend.count() - 1, entry);
390        interpolator.setKeyFrame(entry, entry * duration / (entries - 1), from,
391            animate->blend[blendIndex]);
392        from += components;
393    }
394}
395
396void SkActive::setSteps(int steps) {
397    int count = fState.count();
398    fMaxTime = 0;
399    for (int index = 0; index < count; index++) {
400        SkState& state = fState[index];
401        state.fSteps = steps;
402        calcDurations(index);
403    }
404}
405
406void SkActive::start() {
407    int count = fState.count();
408    SkASSERT(count == fAnimators.count());
409    SkASSERT(count == fInterpolators.count());
410    for (int index = 0; index < count; index++) {
411        SkState& state = fState[index];
412        if (state.fStarted)
413            continue;
414        state.fStarted = true;
415#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
416        SkString debugOut;
417        SkMSec time = fMaker.getAppTime();
418        debugOut.appendS32(time - fMaker.fDebugTimeBase);
419        debugOut.append(" active start adjust delay id=");
420        debugOut.append(fApply._id);
421        debugOut.append("; ");
422        debugOut.append(fAnimators[index]->_id);
423        debugOut.append("=");
424        debugOut.appendS32(fAnimators[index]->fStart - fMaker.fDebugTimeBase);
425        debugOut.append(":");
426        debugOut.appendS32(state.fStartTime);
427#endif
428        if (state.fStartTime > 0) {
429            SkMSec future = fAnimators[index]->fStart + state.fStartTime;
430            if (future > fMaker.fEnableTime)
431                fMaker.notifyInvalTime(future);
432            else
433                fMaker.notifyInval();
434#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
435            debugOut.append(":");
436            debugOut.appendS32(future - fMaker.fDebugTimeBase);
437#endif
438        }
439        if (state.fStartTime >= fMaker.fAdjustedStart) {
440            state.fStartTime -= fMaker.fAdjustedStart;
441#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
442            debugOut.append(" (less adjust = ");
443            debugOut.appendS32(fMaker.fAdjustedStart);
444#endif
445        }
446        state.fStartTime += fAnimators[index]->fStart;
447#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
448        debugOut.append(") new start = ");
449        debugOut.appendS32(state.fStartTime - fMaker.fDebugTimeBase);
450        SkDebugf("%s\n", debugOut.c_str());
451//      SkASSERT((int) (state.fStartTime - fMaker.fDebugTimeBase) >= 0);
452#endif
453    }
454    SkASSERT(fAnimators.count() == fInterpolators.count());
455}
456
457#ifdef SK_DEBUG
458void SkActive::validate() {
459    int count = fState.count();
460    SkASSERT(count == fAnimators.count());
461    SkASSERT(count == fInterpolators.count());
462    for (int index = 0; index < count; index++) {
463        SkASSERT(fAnimators[index]);
464        SkASSERT(fInterpolators[index]);
465//      SkAnimateBase* test = fAnimators[index];
466//      SkASSERT(fApply.scope == test->fTarget || fApply.scope->contains(test->fTarget));
467    }
468}
469#endif
470
471// think about this
472// there should only be one animate object, not two, to go up and down
473// when the apply with reverse came into play, it needs to pick up the value
474// of the existing animate object then remove it from the list
475// the code below should only be bumping fSave, and there shouldn't be anything
476// it needs to be synchronized with
477
478// however, if there are two animates both operating on the same field, then
479// when one replaces the other, it may make sense to pick up the old value as a starting
480// value for the new one somehow.
481
482//void SkActive::SkState::bumpSave() {
483//  if (fMode != SkApply::kMode_hold)
484//      return;
485//  if (fTransition == SkApply::kTransition_reverse) {
486//      if (fSave > 0)
487//          fSave -= SK_MSec1;
488//  } else if (fSave < fDuration)
489//      fSave += SK_MSec1;
490//}
491
492SkMSec SkActive::SkState::getRelativeTime(SkMSec time) {
493    SkMSec result = time;
494//  if (fMode == SkApply::kMode_hold)
495//      result = fSave;
496//  else
497    if (fTransition == SkApply::kTransition_reverse) {
498        if (SkMSec_LT(fDuration, time))
499            result = 0;
500        else
501            result = fDuration - time;
502    }
503    return result;
504}
505