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]); } }
bool SkAnimatorScript::EvalID(const char* token, size_t len, void* user, SkScriptValue* value) { SkAnimatorScript* engine = (SkAnimatorScript*) user; SkTDict<SkDisplayable*>* ids = &engine->fMaker.fIDs; SkDisplayable* displayable; bool success = ids->find(token, len, &displayable); if (success == false) { displayable = engine->fWorking; if (SK_LITERAL_STR_EQUAL("parent", token, len)) { SkDisplayable* parent = displayable->getParent(); if (parent == false) parent = engine->fParent; if (parent) { value->fOperand.fDisplayable = parent; value->fType = SkType_Displayable; return true; } } if (displayable && EvalMember(token, len, displayable, engine, value)) return true; value->fOperand.fString = NULL; value->fType = SkType_String; } else { SkDisplayable* working = engine->fWorking; value->fOperand.fDisplayable = displayable; value->fType = SkType_Displayable; if (displayable->canContainDependents() && working && working->isAnimate()) { SkAnimateBase* animator = (SkAnimateBase*) working; if (animator->isDynamic()) { SkDisplayDepend* depend = (SkDisplayDepend* ) displayable; depend->addDependent(working); } } } return true; }
void SkApply::onEndElement(SkAnimateMaker& maker) { SkDrawable* scopePtr = scope; while (scopePtr && scopePtr->isApply()) { SkApply* scopedApply = (SkApply*) scopePtr; if (scopedApply->scope == this) { maker.setErrorCode(SkDisplayXMLParserError::kApplyScopesItself); return; } scopePtr = scopedApply->scope; } if (mode == kMode_create) return; if (scope != NULL && steps >= 0 && scope->isApply() == false && scope->isDrawable()) scope->setSteps(steps); for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < fAnimators.end(); animPtr++) { SkAnimateBase* anim = *animPtr; //for reusing apply statements with dynamic scope if (anim->fTarget == NULL || anim->fTargetIsScope) { anim->fTargetIsScope = true; if (scope) anim->fTarget = scope; else anim->setTarget(maker); anim->onEndElement(maker); // allows animate->fFieldInfo to be set } if (scope != NULL && steps >= 0 && anim->fTarget != scope && anim->fTarget->isDrawable()) anim->fTarget->setSteps(steps); } }
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; } }
void SkActive::initState(SkApply* apply, int offset) { int count = fState.count(); for (int index = offset; index < count; index++) { SkState& state = fState[index]; SkAnimateBase* animate = fAnimators[index]; #if 0 // def SK_DEBUG if (animate->fHasEndEvent) SkDebugf("%8x %8x active initState:\n", this, animate); #endif SkOperand* from = animate->getValues(); state.fStartTime = state.fBegin = apply->begin + animate->begin; state.fMode = apply->mode; state.fTransition = apply->transition; #if 0 state.fPickup = (SkBool8) apply->pickup; #endif state.fRestore = (SkBool8) apply->restore; state.fSave = apply->begin; state.fStarted = false; state.fSteps = apply->steps; state.fTicks = 0; state.fUnpostedEndEvent = (SkBool8) animate->fHasEndEvent; calcDurations(index); setInterpolator(index, from); } if (count == 0 && (apply->mode == SkApply::kMode_immediate || apply->mode == SkApply::kMode_create)) fMaxTime = apply->begin + apply->steps * SK_MSec1; }
void SkDisplayDepend::dirty() { SkDisplayable** last = fDependents.end(); for (SkDisplayable** depPtr = fDependents.begin(); depPtr < last; depPtr++) { SkAnimateBase* animate = (SkAnimateBase* ) *depPtr; animate->setChanged(true); } }
void SkApply::refresh(SkAnimateMaker& maker) { for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < fAnimators.end(); animPtr++) { SkAnimateBase* animate = *animPtr; animate->onEndElement(maker); } if (fActive) fActive->resetInterpolators(); }
void SkActive::resetInterpolators() { int animators = fAnimators.count(); for (int index = 0; index < animators; index++) { SkAnimateBase* animate = fAnimators[index]; SkOperand* values = animate->getValues(); setInterpolator(index, values); } }
void SkDisplayEvent::onEndElement(SkAnimateMaker& maker) { if (kind == kUser) return; maker.fEvents.addEvent(this); if (kind == kOnEnd) { SkDEBUGCODE(bool found = ) maker.find(target.c_str(), &fTarget); SkASSERT(found); SkASSERT(fTarget && fTarget->isAnimate()); SkAnimateBase* animate = (SkAnimateBase*) fTarget; animate->setHasEndEvent(); }
void SkActive::fixInterpolator(SkBool save) { int animators = fAnimators.count(); for (int index = 0; index < animators; index++) { SkAnimateBase* animate = fAnimators[index]; if (save) { // saved slots increased animate->refresh(fMaker); SkOperand* values = animate->getValues(); setInterpolator(index, values); saveInterpolatorValues(index); } else restoreInterpolatorValues(index); } }
void SkApply::dump(SkAnimateMaker* maker) { dumpBase(maker); if (dynamicScope.isEmpty() == false) SkDebugf("dynamicScope=\"%s\" ", dynamicScope.c_str()); if (dontDraw) SkDebugf("dontDraw=\"true\" "); if (begin != 0) //perhaps we want this no matter what? SkDebugf("begin=\"%g\" ", (float) begin/1000.0f); //is this correct? if (interval != (SkMSec) -1) SkDebugf("interval=\"%g\" ", (float) interval/1000.0f); if (steps != -1) SkDebugf("steps=\"%d\" ", steps); if (restore) SkDebugf("restore=\"true\" "); if (transition == kTransition_reverse) SkDebugf("transition=\"reverse\" "); if (mode == kMode_immediate) { SkDebugf("mode=\"immediate\" "); } else if (mode == kMode_create) { SkDebugf("mode=\"create\" "); } bool closedYet = false; SkDisplayList::fIndent += 4; int save = SkDisplayList::fDumpIndex; if (scope) { if (closedYet == false) { SkDebugf(">\n"); closedYet = true; } scope->dump(maker); } int index; // if (fActive) { for (index = 0; index < fAnimators.count(); index++) { if (closedYet == false) { SkDebugf(">\n"); closedYet = true; } SkAnimateBase* animator = fAnimators[index]; animator->dump(maker); // } } SkDisplayList::fIndent -= 4; SkDisplayList::fDumpIndex = save; if (closedYet) dumpEnd(maker); else SkDebugf("/>\n"); }
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 {
bool SkApply::setProperty(int index, SkScriptValue& scriptValue) { switch (index) { case SK_PROPERTY(animator): { SkAnimateBase* animate = (SkAnimateBase*) scriptValue.fOperand.fDisplayable; SkASSERT(animate->isAnimate()); *fAnimators.append() = animate; return true; } case SK_PROPERTY(steps): steps = scriptValue.fOperand.fS32; if (fActive) fActive->setSteps(steps); return true; } return false; }
void SkApply::applyValues(int animatorIndex, SkOperand* values, int count, SkDisplayTypes valuesType, SkMSec time) { SkAnimateBase* animator = fActive->fAnimators[animatorIndex]; const SkMemberInfo * info = animator->fFieldInfo; SkASSERT(animator); SkASSERT(info != NULL); SkDisplayTypes type = (SkDisplayTypes) info->fType; SkDisplayable* target = getTarget(animator); if (animator->hasExecute() || type == SkType_MemberFunction || type == SkType_MemberProperty) { SkDisplayable* executor = animator->hasExecute() ? animator : target; if (type != SkType_MemberProperty) { SkTDArray<SkScriptValue> typedValues; for (int index = 0; index < count; index++) { SkScriptValue temp; temp.fType = valuesType; temp.fOperand = values[index]; *typedValues.append() = temp; } executor->executeFunction(target, info->functionIndex(), typedValues, info->getType(), NULL); } else { SkScriptValue scriptValue; scriptValue.fOperand = values[0]; scriptValue.fType = info->getType(); target->setProperty(info->propertyIndex(), scriptValue); } } else { SkTypedArray converted; if (type == SkType_ARGB) { if (count == 4) { // !!! assert that it is SkType_Float ? animator->packARGB(&values->fScalar, count, &converted); values = converted.begin(); count = converted.count(); } else { SkASSERT(count == 1); } } // SkASSERT(type == SkType_ARGB || type == SkType_String ||info->isSettable()); if (type == SkType_String || type == SkType_DynamicString) info->setString(target, values->fString); else if (type == SkType_Drawable || type == SkType_Displayable) target->setReference(info, values->fDisplayable); else info->setValue(target, values, count); } }
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; }