void SkActive::create(SkADrawable* drawable, SkMSec time) { fApply.fLastTime = time; fApply.refresh(fMaker); for (int index = 0; index < fAnimators.count(); index++) { SkAnimateBase* animate = fAnimators[index]; SkOperandInterpolator& interpolator = *fInterpolators[index]; int count = animate->components(); if (animate->formula.size() > 0) { SkTDOperandArray values; values.setCount(count); SkDEBUGCODE(bool success = ) animate->fFieldInfo->setValue(fMaker, &values, 0, 0, NULL, animate->getValuesType(), animate->formula); SkASSERT(success); fApply.applyValues(index, values.begin(), count, animate->getValuesType(), time); } else {
void SkActive::pickUp(SkActive* existing) { SkTDOperandArray existingValues; for (int index = 0; index < fAnimators.count(); index++) { SkAnimateBase* animate = fAnimators[index]; SkASSERT(animate->getValuesType() == SkType_Float); int components = animate->components(); SkOperand* from = animate->getValues(); SkOperand* to = &from[animate->components()]; existingValues.setCount(components); existing->fInterpolators[index]->timeToValues( existing->fState[index].fTicks - existing->fState[index].fStartTime, existingValues.begin()); SkScalar originalSum = 0; SkScalar workingSum = 0; for (int cIndex = 0; cIndex < components; cIndex++) { SkScalar delta = to[cIndex].fScalar - from[cIndex].fScalar; originalSum += SkScalarMul(delta, delta); delta = to[cIndex].fScalar - existingValues[cIndex].fScalar; workingSum += SkScalarMul(delta, delta); } if (workingSum < originalSum) { SkScalar originalDistance = SkScalarSqrt(originalSum); SkScalar workingDistance = SkScalarSqrt(workingSum); existing->fState[index].fDuration = (SkMSec) SkScalarMulDiv(fState[index].fDuration, workingDistance, originalDistance); } fInterpolators[index]->reset(components, 2, SkType_Float); fInterpolators[index]->setKeyFrame(0, 0, existingValues.begin(), animate->blend[0]); fInterpolators[index]->setKeyFrame(1, fState[index].fDuration, to, animate->blend[0]); } }
void SkActive::setInterpolator(int index, SkOperand* from) { if (from == NULL) // legitimate for set string return; SkAnimateBase* animate = fAnimators[index]; int entries = animate->entries(); SkASSERT(entries > 0); SkMSec duration = fState[index].fDuration; int components = animate->components(); SkOperandInterpolator& interpolator = *fInterpolators[index]; interpolator.reset(components, entries == 1 ? 2 : entries, animate->getValuesType()); interpolator.setMirror(SkToBool(animate->fMirror)); interpolator.setReset(SkToBool(animate->fReset)); interpolator.setRepeatCount(animate->repeat); if (entries == 1) { interpolator.setKeyFrame(0, 0, from, animate->blend[0]); interpolator.setKeyFrame(1, duration, from, animate->blend[0]); return; } for (int entry = 0; entry < entries; entry++) { int blendIndex = SkMin32(animate->blend.count() - 1, entry); interpolator.setKeyFrame(entry, entry * duration / (entries - 1), from, animate->blend[blendIndex]); from += components; } }
bool SkActive::immediate(bool enable) { SkMSec time = 0; bool result = false; SkDrawable* drawable = fApply.scope; SkMSec final = fMaxTime; do { bool applied = fAnimators.count() == 0; fApply.fLastTime = time; fApply.refresh(fMaker); for (int index = 0; index < fAnimators.count(); index++) { SkAnimateBase* animate = fAnimators[index]; SkState& state = fState[index]; if (state.fMode != SkApply::kMode_immediate) continue; if (state.fBegin > time) continue; if (time > state.fBegin + state.fDuration) continue; applied = true; SkOperandInterpolator& interpolator = *fInterpolators[index]; int count = animate->components(); if (animate->formula.size() > 0) { SkTDOperandArray values; values.setCount(count); bool success = animate->fFieldInfo->setValue(fMaker, &values, 0, 0, NULL, animate->getValuesType(), animate->formula); SkASSERT(success); fApply.applyValues(index, values.begin(), count, animate->getValuesType(), time); } else { SkAutoSTMalloc<16, SkOperand> values(count); interpolator.timeToValues(time, values.get()); fApply.applyValues(index, values.get(), count, animate->getValuesType(), time); } } if (enable) drawable->enable(fMaker); else if (applied) result |= drawable->draw(fMaker); time += SK_MSec1; } while (time <= final); return result; }
bool SkApply::interpolate(SkAnimateMaker& maker, SkMSec rawTime) { if (fActive == NULL) return false; bool result = false; #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING SkMSec time = maker.getAppTime(); if (lastTime == (SkMSec) -1) lastTime = rawTime - 1; if (fActive != NULL && strcmp(id, "a3") == 0 && rawTime > lastTime) { lastTime += 1000; SkString debugOut; debugOut.appendS32(time - maker.fDebugTimeBase); debugOut.append(" apply id="); debugOut.append(_id); debugOut.append("; "); debugOut.append(fActive->fAnimators[0]->_id); debugOut.append("="); debugOut.appendS32(rawTime - fActive->fState[0].fStartTime); debugOut.append(")"); SkDebugf("%s\n", debugOut.c_str()); } #endif fActive->start(); if (restore) fActive->initializeSave(); int animators = fActive->fAnimators.count(); for (int inner = 0; inner < animators; inner++) { SkAnimateBase* animate = fActive->fAnimators[inner]; if (animate->fChanged) { animate->fChanged = false; animate->fStart = rawTime; // SkTypedArray values; // int count = animate->fValues.count(); // values.setCount(count); // memcpy(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count); animate->onEndElement(maker); // if (memcmp(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count) != 0) { fActive->append(this); fActive->start(); // } } SkMSec time = fActive->getTime(rawTime, inner); SkActive::SkState& state = fActive->fState[inner]; if (SkMSec_LT(rawTime, state.fStartTime)) { if (fEnabling) { animate->fDelayed = true; maker.delayEnable(this, state.fStartTime); } continue; } else animate->fDelayed = false; SkMSec innerTime = fLastTime = state.getRelativeTime(time); if (restore) fActive->restoreInterpolatorValues(inner); if (animate->fReset) { if (transition != SkApply::kTransition_reverse) { if (SkMSec_LT(state.fBegin + state.fDuration, innerTime)) { if (animate->fResetPending) { innerTime = 0; animate->fResetPending = false; } else continue; } } else if (innerTime == 0) { if (animate->fResetPending) { innerTime = state.fBegin + state.fDuration; animate->fResetPending = false; } else continue; } } int count = animate->components(); SkAutoSTMalloc<16, SkOperand> values(count); SkInterpolatorBase::Result interpResult = fActive->fInterpolators[inner]->timeToValues( innerTime, values.get()); result |= (interpResult != SkInterpolatorBase::kFreezeEnd_Result); if ((transition != SkApply::kTransition_reverse && interpResult == SkInterpolatorBase::kFreezeEnd_Result || transition == SkApply::kTransition_reverse && fLastTime == 0) && state.fUnpostedEndEvent) { // SkDEBUGF(("interpolate: post on end\n")); state.fUnpostedEndEvent = false; maker.postOnEnd(animate, state.fBegin + state.fDuration); maker.fAdjustedStart = 0; // !!! left over from synchronizing animation days, undoubtably out of date (and broken) } if (animate->formula.size() > 0) { if (fLastTime > animate->dur) fLastTime = animate->dur; SkTypedArray formulaValues; formulaValues.setCount(count); bool success = animate->fFieldInfo->setValue(maker, &formulaValues, 0, 0, NULL, animate->getValuesType(), animate->formula); SkASSERT(success); if (restore) save(inner); // save existing value applyValues(inner, formulaValues.begin(), count, animate->getValuesType(), innerTime); } else { if (restore) save(inner); // save existing value applyValues(inner, values.get(), count, animate->getValuesType(), innerTime); } } return result; }