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 SkApply::save(int index) { SkAnimateBase* animate = fActive->fAnimators[index]; const SkMemberInfo * info = animate->fFieldInfo; SkDisplayable* target = getTarget(animate); // if (animate->hasExecute()) // info = animate->getResolvedInfo(); SkDisplayTypes type = (SkDisplayTypes) info->fType; if (type == SkType_MemberFunction) return; // nothing to save size_t size = info->getSize(target); int count = (int) (size / sizeof(SkScalar)); bool useLast = true; // !!! this all may be unneeded, at least in the dynamic case ?? int activeIndex = fActive->fDrawIndex + index; SkTDOperandArray last; if (fActive->fSaveRestore[activeIndex] == NULL) { fActive->fSaveRestore[activeIndex] = new SkOperand[count]; useLast = false; } else { last.setCount(count); memcpy(last.begin(), fActive->fSaveRestore[activeIndex], count * sizeof(SkOperand)); } if (type != SkType_MemberProperty) { info->getValue(target, fActive->fSaveRestore[activeIndex], count); if (useLast) info->setValue(target, last.begin(), count); } else { SkScriptValue scriptValue; bool success = target->getProperty(info->propertyIndex(), &scriptValue); SkASSERT(success == true); SkASSERT(scriptValue.fType == SkType_Float); fActive->fSaveRestore[activeIndex][0] = scriptValue.fOperand; if (useLast) { SkScriptValue scriptValue; scriptValue.fType = type; scriptValue.fOperand = last[0]; target->setProperty(info->propertyIndex(), scriptValue); } } // !!! end of unneeded }
bool SkAnimatorScript::EvalMemberCommon(SkScriptEngine* engine, const SkMemberInfo* info, SkDisplayable* displayable, SkScriptValue* value) { SkDisplayTypes original; SkDisplayTypes type = original = (SkDisplayTypes) info->getType(); if (info->fType == SkType_Array) type = SkType_Array; switch (type) { case SkType_ARGB: type = SkType_Int; case SkType_Boolean: case SkType_Int: case SkType_MSec: case SkType_Float: SkASSERT(info->getCount() == 1); if (info->fType != SkType_MemberProperty && info->fType != SkType_MemberFunction) value->fOperand.fS32 = *(int32_t*) info->memberData(displayable); // OK for SkScalar too if (type == SkType_MSec) { value->fOperand.fScalar = SkScalarDiv((SkScalar) value->fOperand.fS32, 1000); // dividing two ints is the same as dividing two scalars type = SkType_Float; } break; case SkType_String: { SkString* displayableString; if (info->fType != SkType_MemberProperty && info->fType != SkType_MemberFunction) { info->getString(displayable, &displayableString); value->fOperand.fString = new SkString(*displayableString); } } break; case SkType_Array: { SkASSERT(info->fType != SkType_MemberProperty); // !!! incomplete SkTDOperandArray* displayableArray = (SkTDOperandArray*) info->memberData(displayable); if (displayable->getType() == SkType_Array) { SkDisplayArray* typedArray = (SkDisplayArray*) displayable; original = typedArray->values.getType(); } SkASSERT(original != SkType_Unknown); SkTypedArray* array = value->fOperand.fArray = new SkTypedArray(original); engine->track(array); int count = displayableArray->count(); if (count > 0) { array->setCount(count); memcpy(array->begin(), displayableArray->begin(), count * sizeof(SkOperand)); } } break; default: SkASSERT(0); // unimplemented } value->fType = type; return true; }
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 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; }
SkDisplayable* SkDisplayable::deepCopy(SkAnimateMaker* maker) { SkDisplayTypes type = getType(); if (type == SkType_Unknown) { SkASSERT(0); return NULL; } SkDisplayable* copy = SkDisplayType::CreateInstance(maker, type); int index = -1; int propIndex = 0; const SkMemberInfo* info; do { info = copy->getMember(++index); if (info == NULL) break; if (info->fType == SkType_MemberProperty) { SkScriptValue value; if (getProperty(propIndex, &value)) copy->setProperty(propIndex, value); propIndex++; continue; } if (info->fType == SkType_MemberFunction) continue; if (info->fType == SkType_Array) { SkTDOperandArray* array = (SkTDOperandArray*) info->memberData(this); int arrayCount; if (array == NULL || (arrayCount = array->count()) == 0) continue; SkTDOperandArray* copyArray = (SkTDOperandArray*) info->memberData(copy); copyArray->setCount(arrayCount); SkDisplayTypes elementType; if (type == SkType_Array) { SkDisplayArray* dispArray = (SkDisplayArray*) this; elementType = dispArray->values.getType(); } else elementType = info->arrayType(); size_t elementSize = SkMemberInfo::GetSize(elementType); size_t byteSize = elementSize * arrayCount; memcpy(copyArray->begin(), array->begin(), byteSize); continue; } if (SkDisplayType::IsDisplayable(maker, info->fType)) { SkDisplayable** displayable = (SkDisplayable**) info->memberData(this); if (*displayable == NULL || *displayable == (SkDisplayable*) -1) continue; SkDisplayable* deeper = (*displayable)->deepCopy(maker); info->setMemberData(copy, deeper, sizeof(deeper)); continue; } if (info->fType == SkType_String || info->fType == SkType_DynamicString) { SkString* string; info->getString(this, &string); info->setString(copy, string); continue; } void* data = info->memberData(this); size_t size = SkMemberInfo::GetSize(info->fType); info->setMemberData(copy, data, size); } while (true); copy->dirty(); return copy; }
void SkDisplayable::dumpAttrs(SkAnimateMaker* maker) { SkDisplayTypes type = getType(); if (type == SkType_Unknown) { //SkDebugf("/>\n"); return; } SkDisplayable* blankCopy = SkDisplayType::CreateInstance(maker, type); int index = -1; int propIndex = 0; const SkMemberInfo* info; const SkMemberInfo* blankInfo; SkScriptValue value; SkScriptValue blankValue; SkOperand values[2]; SkOperand blankValues[2]; do { info = this->getMember(++index); if (NULL == info) { //SkDebugf("\n"); break; } if (SkType_MemberProperty == info->fType) { if (getProperty(propIndex, &value)) { blankCopy->getProperty(propIndex, &blankValue); //last two are dummies dumpValues(info, value.fType, value.fOperand, blankValue.fOperand, value.fOperand, blankValue.fOperand); } propIndex++; continue; } if (SkDisplayType::IsDisplayable(maker, info->fType)) { continue; } if (info->fType == SkType_MemberFunction) continue; if (info->fType == SkType_Array) { SkTDOperandArray* array = (SkTDOperandArray*) info->memberData(this); int arrayCount; if (array == NULL || (arrayCount = array->count()) == 0) continue; SkDisplayTypes elementType; if (type == SkType_Array) { SkDisplayArray* dispArray = (SkDisplayArray*) this; elementType = dispArray->values.getType(); } else elementType = info->arrayType(); bool firstElem = true; SkDebugf("%s=\"[", info->fName); for (SkOperand* op = array->begin(); op < array->end(); op++) { if (!firstElem) SkDebugf(","); switch (elementType) { case SkType_Displayable: SkDebugf("%s", op->fDisplayable->id); break; case SkType_Int: SkDebugf("%d", op->fS32); break; case SkType_Float: #ifdef SK_CAN_USE_FLOAT SkDebugf("%g", SkScalarToFloat(op->fScalar)); #else SkDebugf("%x", op->fScalar); #endif break; case SkType_String: case SkType_DynamicString: SkDebugf("%s", op->fString->c_str()); break; default: break; } firstElem = false; } SkDebugf("]\" "); continue; } if (info->fType == SkType_String || info->fType == SkType_DynamicString) { SkString* string; info->getString(this, &string); if (string->isEmpty() == false) SkDebugf("%s=\"%s\"\t", info->fName, string->c_str()); continue; } blankInfo = blankCopy->getMember(index); int i = info->fCount; info->getValue(this, values, i); blankInfo->getValue(blankCopy, blankValues, i); dumpValues(info, info->fType, values[0], blankValues[0], values[1], blankValues[1]); } while (true); delete blankCopy; }