SkMSec SkActive::SkState::getRelativeTime(SkMSec time) { SkMSec result = time; // if (fMode == SkApply::kMode_hold) // result = fSave; // else if (fTransition == SkApply::kTransition_reverse) { if (SkMSec_LT(fDuration, time)) result = 0; else result = fDuration - time; } 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; }