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