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