blob: f4299033932261f4cd3e1062c1f9ef8ff22e5213 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
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 if (state.fMode == SkApply::kMode_immediate || state.fMode == SkApply::kMode_create)
146 duration = state.fSteps ? state.fSteps * SK_MSec1 : 1;
147// else if (state.fMode == SkApply::kMode_hold) {
148// int entries = animate->entries();
149// SkScriptValue value;
150// value.fOperand = animate->getValues()[entries - 1];
151// value.fType = animate->getValuesType();
152// bool result = SkScriptEngine::ConvertTo(NULL, SkType_Int, &value);
153// SkASSERT(result);
154// duration = value.fOperand.fS32 * SK_MSec1;
155// }
156 state.fDuration = duration;
157 SkMSec maxTime = state.fBegin + duration;
158 if (fMaxTime < maxTime)
159 fMaxTime = maxTime;
160}
161
162void SkActive::create(SkDrawable* drawable, SkMSec time) {
163 fApply.fLastTime = time;
164 fApply.refresh(fMaker);
165 for (int index = 0; index < fAnimators.count(); index++) {
166 SkAnimateBase* animate = fAnimators[index];
167 SkOperandInterpolator& interpolator = *fInterpolators[index];
168 int count = animate->components();
169 if (animate->formula.size() > 0) {
170 SkTDOperandArray values;
171 values.setCount(count);
172 bool success = animate->fFieldInfo->setValue(fMaker, &values, 0, 0, NULL,
173 animate->getValuesType(), animate->formula);
174 SkASSERT(success);
175 fApply.applyValues(index, values.begin(), count, animate->getValuesType(), time);
176 } else {
177 SkAutoSTMalloc<16, SkOperand> values(count);
178 interpolator.timeToValues(time, values.get());
179 fApply.applyValues(index, values.get(), count, animate->getValuesType(), time);
180 }
181 }
182 drawable->enable(fMaker);
183 SkASSERT(fAnimators.count() == fInterpolators.count());
184}
185
186bool SkActive::immediate(bool enable) {
187 SkMSec time = 0;
188 bool result = false;
189 SkDrawable* drawable = fApply.scope;
190 SkMSec final = fMaxTime;
191 do {
192 bool applied = fAnimators.count() == 0;
193 fApply.fLastTime = time;
194 fApply.refresh(fMaker);
195 for (int index = 0; index < fAnimators.count(); index++) {
196 SkAnimateBase* animate = fAnimators[index];
197 SkState& state = fState[index];
198 if (state.fMode != SkApply::kMode_immediate)
199 continue;
200 if (state.fBegin > time)
201 continue;
202 if (time > state.fBegin + state.fDuration)
203 continue;
204 applied = true;
205 SkOperandInterpolator& interpolator = *fInterpolators[index];
206 int count = animate->components();
207 if (animate->formula.size() > 0) {
208 SkTDOperandArray values;
209 values.setCount(count);
210 bool success = animate->fFieldInfo->setValue(fMaker, &values, 0, 0, NULL,
211 animate->getValuesType(), animate->formula);
212 SkASSERT(success);
213 fApply.applyValues(index, values.begin(), count, animate->getValuesType(), time);
214 } else {
215 SkAutoSTMalloc<16, SkOperand> values(count);
216 interpolator.timeToValues(time, values.get());
217 fApply.applyValues(index, values.get(), count, animate->getValuesType(), time);
218 }
219 }
220 if (enable)
221 drawable->enable(fMaker);
222 else if (applied)
223 result |= drawable->draw(fMaker);
224 time += SK_MSec1;
225 } while (time <= final);
226 return result;
227}
228
229void SkActive::fixInterpolator(SkBool save) {
230 int animators = fAnimators.count();
231 for (int index = 0; index < animators; index++) {
232 SkAnimateBase* animate = fAnimators[index];
233 if (save) { // saved slots increased
234 animate->refresh(fMaker);
235 SkOperand* values = animate->getValues();
236 setInterpolator(index, values);
237 saveInterpolatorValues(index);
238 } else
239 restoreInterpolatorValues(index);
240 }
241}
242
243SkMSec SkActive::getTime(SkMSec inTime, int animatorIndex) {
244 fState[animatorIndex].fTicks = inTime;
245 return inTime - fState[animatorIndex].fStartTime;
246}
247
248bool SkActive::initializeSave() {
249 int animators = fAnimators.count();
250 int activeTotal = fDrawIndex + animators;
251 int oldCount = fSaveRestore.count();
252 if (oldCount < activeTotal) {
253 fSaveRestore.setCount(activeTotal);
254 memset(&fSaveRestore[oldCount], 0, sizeof(fSaveRestore[0]) * (activeTotal - oldCount));
255 SkASSERT(fSaveInterpolators.count() == oldCount);
256 fSaveInterpolators.setCount(activeTotal);
257 memset(&fSaveInterpolators[oldCount], 0,
258 sizeof(fSaveInterpolators[0]) * (activeTotal - oldCount));
259 return true;
260 }
261 return false;
262}
263
264void SkActive::initState(SkApply* apply, int offset) {
265 int count = fState.count();
266 for (int index = offset; index < count; index++) {
267 SkState& state = fState[index];
268 SkAnimateBase* animate = fAnimators[index];
269#if 0 // def SK_DEBUG
270 if (animate->fHasEndEvent)
271 SkDebugf("%8x %8x active initState:\n", this, animate);
272#endif
273 SkOperand* from = animate->getValues();
274 state.fStartTime = state.fBegin = apply->begin + animate->begin;
275 state.fMode = apply->mode;
276 state.fTransition = apply->transition;
277#if 0
278 state.fPickup = (SkBool8) apply->pickup;
279#endif
280 state.fRestore = (SkBool8) apply->restore;
281 state.fSave = apply->begin;
282 state.fStarted = false;
283 state.fSteps = apply->steps;
284 state.fTicks = 0;
285 state.fUnpostedEndEvent = (SkBool8) animate->fHasEndEvent;
286 calcDurations(index);
287 setInterpolator(index, from);
288 }
289 if (count == 0 && (apply->mode == SkApply::kMode_immediate || apply->mode == SkApply::kMode_create))
290 fMaxTime = apply->begin + apply->steps * SK_MSec1;
291}
292
293void SkActive::pickUp(SkActive* existing) {
294 SkTDOperandArray existingValues;
295 for (int index = 0; index < fAnimators.count(); index++) {
296 SkAnimateBase* animate = fAnimators[index];
297 SkASSERT(animate->getValuesType() == SkType_Float);
298 int components = animate->components();
299 SkOperand* from = animate->getValues();
300 SkOperand* to = &from[animate->components()];
301 existingValues.setCount(components);
302 existing->fInterpolators[index]->timeToValues(
303 existing->fState[index].fTicks - existing->fState[index].fStartTime, existingValues.begin());
304 SkScalar originalSum = 0;
305 SkScalar workingSum = 0;
306 for (int cIndex = 0; cIndex < components; cIndex++) {
307 SkScalar delta = to[cIndex].fScalar - from[cIndex].fScalar;
308 originalSum += SkScalarMul(delta, delta);
309 delta = to[cIndex].fScalar - existingValues[cIndex].fScalar;
310 workingSum += SkScalarMul(delta, delta);
311 }
312 if (workingSum < originalSum) {
313 SkScalar originalDistance = SkScalarSqrt(originalSum);
314 SkScalar workingDistance = SkScalarSqrt(workingSum);
315 existing->fState[index].fDuration = (SkMSec) SkScalarMulDiv(fState[index].fDuration,
316 workingDistance, originalDistance);
317 }
318 fInterpolators[index]->reset(components, 2, SkType_Float);
319 fInterpolators[index]->setKeyFrame(0, 0, existingValues.begin(), animate->blend[0]);
320 fInterpolators[index]->setKeyFrame(1, fState[index].fDuration, to, animate->blend[0]);
321 }
322}
323
324void SkActive::resetInterpolators() {
325 int animators = fAnimators.count();
326 for (int index = 0; index < animators; index++) {
327 SkAnimateBase* animate = fAnimators[index];
328 SkOperand* values = animate->getValues();
329 setInterpolator(index, values);
330 }
331}
332
333void SkActive::resetState() {
334 fDrawIndex = 0;
335 int count = fState.count();
336 for (int index = 0; index < count; index++) {
337 SkState& state = fState[index];
338 SkAnimateBase* animate = fAnimators[index];
339#if 0 // def SK_DEBUG
340 if (animate->fHasEndEvent)
341 SkDebugf("%8x %8x active resetState: has end event\n", this, animate);
342#endif
343 state.fStartTime = state.fBegin = fApply.begin + animate->begin;
344 state.fStarted = false;
345 state.fTicks = 0;
346 }
347}
348
349void SkActive::restoreInterpolatorValues(int index) {
350 SkOperandInterpolator& interpolator = *fInterpolators[index];
351 index += fDrawIndex ;
352 int count = interpolator.getValuesCount();
353 memcpy(interpolator.getValues(), fSaveInterpolators[index], count * sizeof(SkOperand));
354}
355
356void SkActive::saveInterpolatorValues(int index) {
357 SkOperandInterpolator& interpolator = *fInterpolators[index];
358 index += fDrawIndex ;
359 int count = interpolator.getValuesCount();
360 SkOperand* cache = new SkOperand[count]; // this should use sk_malloc/sk_free since SkOperand does not have a constructor/destructor
361 fSaveInterpolators[index] = cache;
362 memcpy(cache, interpolator.getValues(), count * sizeof(SkOperand));
363}
364
365void SkActive::setInterpolator(int index, SkOperand* from) {
366 if (from == NULL) // legitimate for set string
367 return;
368 SkAnimateBase* animate = fAnimators[index];
369 int entries = animate->entries();
370 SkASSERT(entries > 0);
371 SkMSec duration = fState[index].fDuration;
372 int components = animate->components();
373 SkOperandInterpolator& interpolator = *fInterpolators[index];
374 interpolator.reset(components, entries == 1 ? 2 : entries, animate->getValuesType());
375 interpolator.setMirror(SkToBool(animate->fMirror));
376 interpolator.setReset(SkToBool(animate->fReset));
377 interpolator.setRepeatCount(animate->repeat);
378 if (entries == 1) {
379 interpolator.setKeyFrame(0, 0, from, animate->blend[0]);
380 interpolator.setKeyFrame(1, duration, from, animate->blend[0]);
381 return;
382 }
383 for (int entry = 0; entry < entries; entry++) {
384 int blendIndex = SkMin32(animate->blend.count() - 1, entry);
385 interpolator.setKeyFrame(entry, entry * duration / (entries - 1), from,
386 animate->blend[blendIndex]);
387 from += components;
388 }
389}
390
391void SkActive::setSteps(int steps) {
392 int count = fState.count();
393 fMaxTime = 0;
394 for (int index = 0; index < count; index++) {
395 SkState& state = fState[index];
396 state.fSteps = steps;
397 calcDurations(index);
398 }
399}
400
401void SkActive::start() {
402 int count = fState.count();
403 SkASSERT(count == fAnimators.count());
404 SkASSERT(count == fInterpolators.count());
405 for (int index = 0; index < count; index++) {
406 SkState& state = fState[index];
407 if (state.fStarted)
408 continue;
409 state.fStarted = true;
410#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
411 SkString debugOut;
412 SkMSec time = fMaker.getAppTime();
413 debugOut.appendS32(time - fMaker.fDebugTimeBase);
414 debugOut.append(" active start adjust delay id=");
415 debugOut.append(fApply._id);
416 debugOut.append("; ");
417 debugOut.append(fAnimators[index]->_id);
418 debugOut.append("=");
419 debugOut.appendS32(fAnimators[index]->fStart - fMaker.fDebugTimeBase);
420 debugOut.append(":");
421 debugOut.appendS32(state.fStartTime);
422#endif
423 if (state.fStartTime > 0) {
424 SkMSec future = fAnimators[index]->fStart + state.fStartTime;
425 if (future > fMaker.fEnableTime)
426 fMaker.notifyInvalTime(future);
427 else
428 fMaker.notifyInval();
429#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
430 debugOut.append(":");
431 debugOut.appendS32(future - fMaker.fDebugTimeBase);
432#endif
433 }
434 if (state.fStartTime >= fMaker.fAdjustedStart) {
435 state.fStartTime -= fMaker.fAdjustedStart;
436#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
437 debugOut.append(" (less adjust = ");
438 debugOut.appendS32(fMaker.fAdjustedStart);
439#endif
440 }
441 state.fStartTime += fAnimators[index]->fStart;
442#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
443 debugOut.append(") new start = ");
444 debugOut.appendS32(state.fStartTime - fMaker.fDebugTimeBase);
445 SkDebugf("%s\n", debugOut.c_str());
446// SkASSERT((int) (state.fStartTime - fMaker.fDebugTimeBase) >= 0);
447#endif
448 }
449 SkASSERT(fAnimators.count() == fInterpolators.count());
450}
451
452#ifdef SK_DEBUG
453void SkActive::validate() {
454 int count = fState.count();
455 SkASSERT(count == fAnimators.count());
456 SkASSERT(count == fInterpolators.count());
457 for (int index = 0; index < count; index++) {
458 SkASSERT(fAnimators[index]);
459 SkASSERT(fInterpolators[index]);
460// SkAnimateBase* test = fAnimators[index];
461// SkASSERT(fApply.scope == test->fTarget || fApply.scope->contains(test->fTarget));
462 }
463}
464#endif
465
466// think about this
467// there should only be one animate object, not two, to go up and down
468// when the apply with reverse came into play, it needs to pick up the value
469// of the existing animate object then remove it from the list
470// the code below should only be bumping fSave, and there shouldn't be anything
471// it needs to be synchronized with
472
473// however, if there are two animates both operating on the same field, then
474// when one replaces the other, it may make sense to pick up the old value as a starting
475// value for the new one somehow.
476
477//void SkActive::SkState::bumpSave() {
478// if (fMode != SkApply::kMode_hold)
479// return;
480// if (fTransition == SkApply::kTransition_reverse) {
481// if (fSave > 0)
482// fSave -= SK_MSec1;
483// } else if (fSave < fDuration)
484// fSave += SK_MSec1;
485//}
486
487SkMSec SkActive::SkState::getRelativeTime(SkMSec time) {
488 SkMSec result = time;
489// if (fMode == SkApply::kMode_hold)
490// result = fSave;
491// else
492 if (fTransition == SkApply::kTransition_reverse) {
493 if (SkMSec_LT(fDuration, time))
494 result = 0;
495 else
496 result = fDuration - time;
497 }
498 return result;
499}
500
501