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 
SkActive(SkApply & apply,SkAnimateMaker & maker)21 SkActive::SkActive(SkApply& apply, SkAnimateMaker& maker) : fApply(apply),
22     fMaxTime(0), fMaker(maker), fDrawIndex(0), fDrawMax(0) {
23 }
24 
init()25 void 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] = new SkOperandInterpolator;
35     initState(&fApply, 0);
36 //  for (index = 0; index < animators; index++)
37 //      fState[index].bumpSave();
38     SkASSERT(fInterpolators.count() == fAnimators.count());
39 }
40 
~SkActive()41 SkActive::~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 
advance()51 void SkActive::advance() {
52     if (fDrawMax < fDrawIndex)
53         fDrawMax = fDrawIndex;
54     fDrawIndex += fAnimators.count();
55 }
56 
append(SkApply * apply)57 void 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] = new 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 
appendSave(int oldCount)116 void 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 
calcDurations(int index)140 void 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(nullptr, 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 
create(SkADrawable * drawable,SkMSec time)167 void SkActive::create(SkADrawable* 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, nullptr,
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 
immediate(bool enable)191 bool SkActive::immediate(bool enable) {
192     SkMSec time = 0;
193     bool result = false;
194     SkADrawable* 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, nullptr,
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 
fixInterpolator(SkBool save)234 void 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 
getTime(SkMSec inTime,int animatorIndex)248 SkMSec SkActive::getTime(SkMSec inTime, int animatorIndex) {
249     fState[animatorIndex].fTicks = inTime;
250     return inTime - fState[animatorIndex].fStartTime;
251 }
252 
initializeSave()253 bool 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 
initState(SkApply * apply,int offset)269 void 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 
pickUp(SkActive * existing)298 void 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 
resetInterpolators()329 void 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 
resetState()338 void 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 
restoreInterpolatorValues(int index)354 void 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 
saveInterpolatorValues(int index)361 void 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 
setInterpolator(int index,SkOperand * from)370 void SkActive::setInterpolator(int index, SkOperand* from) {
371     if (from == nullptr) // 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 
setSteps(int steps)396 void 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 
start()406 void 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
validate()458 void 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 
getRelativeTime(SkMSec time)492 SkMSec 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