1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/animator/SkDisplayApply.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,804 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkDisplayApply.h" 1.14 +#include "SkAnimateActive.h" 1.15 +#include "SkAnimateMaker.h" 1.16 +#include "SkAnimateSet.h" 1.17 +#include "SkAnimatorScript.h" 1.18 +#include "SkDisplayType.h" 1.19 +#include "SkDrawGroup.h" 1.20 +#include "SkParse.h" 1.21 +#include "SkScript.h" 1.22 +#include "SkSystemEventTypes.h" 1.23 +#ifdef SK_DEBUG 1.24 +#include "SkTime.h" 1.25 +#endif 1.26 +#include <ctype.h> 1.27 + 1.28 +enum SkApply_Properties { 1.29 + SK_PROPERTY(animator), 1.30 + SK_PROPERTY(step), 1.31 + SK_PROPERTY(steps), 1.32 + SK_PROPERTY(time) 1.33 +}; 1.34 + 1.35 +#if SK_USE_CONDENSED_INFO == 0 1.36 + 1.37 +// if no attibutes, enclosed displayable is both scope & target 1.38 +// only if both scope & target are specified, or if target and enclosed displayable, are scope and target different 1.39 +const SkMemberInfo SkApply::fInfo[] = { 1.40 + SK_MEMBER_PROPERTY(animator, Animate), 1.41 + SK_MEMBER(begin, MSec), 1.42 + SK_MEMBER(dontDraw, Boolean), 1.43 + SK_MEMBER(dynamicScope, String), 1.44 + SK_MEMBER(interval, MSec), // recommended redraw interval 1.45 + SK_MEMBER(mode, ApplyMode), 1.46 +#if 0 1.47 + SK_MEMBER(pickup, Boolean), 1.48 +#endif 1.49 + SK_MEMBER(restore, Boolean), 1.50 + SK_MEMBER(scope, Drawable), // thing that scopes animation (unnamed enclosed displayable goes here) 1.51 + SK_MEMBER_PROPERTY(step, Int), 1.52 + SK_MEMBER_PROPERTY(steps, Int), 1.53 + SK_MEMBER_PROPERTY(time, MSec), 1.54 + SK_MEMBER(transition, ApplyTransition) 1.55 +}; 1.56 + 1.57 +#endif 1.58 + 1.59 +DEFINE_GET_MEMBER(SkApply); 1.60 + 1.61 +SkApply::SkApply() : begin(0), dontDraw(false), interval((SkMSec) -1), mode((Mode) -1), /*pickup(false), */ 1.62 + restore(false), scope(NULL), steps(-1), transition((Transition) -1), fActive(NULL), /*fCurrentScope(NULL),*/ 1.63 + fLastTime(0), fAppended(false), fContainsScope(false), fDeleteScope(false), fEmbedded(false), 1.64 + fEnabled(false), fEnabling(false) { 1.65 +} 1.66 + 1.67 +SkApply::~SkApply() { 1.68 + for (SkDrawable** curPtr = fScopes.begin(); curPtr < fScopes.end(); curPtr++) 1.69 + delete *curPtr; 1.70 + if (fDeleteScope) 1.71 + delete scope; 1.72 + // !!! caller must call maker.removeActive(fActive) 1.73 + delete fActive; 1.74 +} 1.75 + 1.76 +void SkApply::activate(SkAnimateMaker& maker) { 1.77 + if (fActive != NULL) { 1.78 + if (fActive->fDrawIndex == 0 && fActive->fDrawMax == 0) 1.79 + return; // if only one use, nothing more to do 1.80 + if (restore == false) 1.81 + return; // all share same state, regardless of instance number 1.82 + bool save = fActive->initializeSave(); 1.83 + fActive->fixInterpolator(save); 1.84 + } else { 1.85 + fActive = new SkActive(*this, maker); 1.86 + fActive->init(); 1.87 + maker.appendActive(fActive); 1.88 + if (restore) { 1.89 + fActive->initializeSave(); 1.90 + int animators = fAnimators.count(); 1.91 + for (int index = 0; index < animators; index++) 1.92 + fActive->saveInterpolatorValues(index); 1.93 + } 1.94 + } 1.95 +} 1.96 + 1.97 +void SkApply::append(SkApply* apply) { 1.98 + if (fActive == NULL) 1.99 + return; 1.100 + int oldCount = fActive->fAnimators.count(); 1.101 + fActive->append(apply); 1.102 + if (restore) { 1.103 + fActive->appendSave(oldCount); 1.104 + int newCount = fActive->fAnimators.count(); 1.105 + for (int index = oldCount; index < newCount; index++) 1.106 + fActive->saveInterpolatorValues(index); 1.107 + } 1.108 +} 1.109 + 1.110 +void SkApply::applyValues(int animatorIndex, SkOperand* values, int count, 1.111 + SkDisplayTypes valuesType, SkMSec time) 1.112 +{ 1.113 + SkAnimateBase* animator = fActive->fAnimators[animatorIndex]; 1.114 + const SkMemberInfo * info = animator->fFieldInfo; 1.115 + SkASSERT(animator); 1.116 + SkASSERT(info != NULL); 1.117 + SkDisplayTypes type = (SkDisplayTypes) info->fType; 1.118 + SkDisplayable* target = getTarget(animator); 1.119 + if (animator->hasExecute() || type == SkType_MemberFunction || type == SkType_MemberProperty) { 1.120 + SkDisplayable* executor = animator->hasExecute() ? animator : target; 1.121 + if (type != SkType_MemberProperty) { 1.122 + SkTDArray<SkScriptValue> typedValues; 1.123 + for (int index = 0; index < count; index++) { 1.124 + SkScriptValue temp; 1.125 + temp.fType = valuesType; 1.126 + temp.fOperand = values[index]; 1.127 + *typedValues.append() = temp; 1.128 + } 1.129 + executor->executeFunction(target, info->functionIndex(), typedValues, info->getType(), NULL); 1.130 + } else { 1.131 + SkScriptValue scriptValue; 1.132 + scriptValue.fOperand = values[0]; 1.133 + scriptValue.fType = info->getType(); 1.134 + target->setProperty(info->propertyIndex(), scriptValue); 1.135 + } 1.136 + } else { 1.137 + SkTypedArray converted; 1.138 + if (type == SkType_ARGB) { 1.139 + if (count == 4) { 1.140 + // !!! assert that it is SkType_Float ? 1.141 + animator->packARGB(&values->fScalar, count, &converted); 1.142 + values = converted.begin(); 1.143 + count = converted.count(); 1.144 + } else { 1.145 + SkASSERT(count == 1); 1.146 + } 1.147 + } 1.148 +// SkASSERT(type == SkType_ARGB || type == SkType_String ||info->isSettable()); 1.149 + if (type == SkType_String || type == SkType_DynamicString) 1.150 + info->setString(target, values->fString); 1.151 + else if (type == SkType_Drawable || type == SkType_Displayable) 1.152 + target->setReference(info, values->fDisplayable); 1.153 + else 1.154 + info->setValue(target, values, count); 1.155 + } 1.156 +} 1.157 + 1.158 +bool SkApply::contains(SkDisplayable* child) { 1.159 + for (SkDrawable** curPtr = fScopes.begin(); curPtr < fScopes.end(); curPtr++) { 1.160 + if (*curPtr == child || (*curPtr)->contains(child)) 1.161 + return true; 1.162 + } 1.163 + return fDeleteScope && scope == child; 1.164 +} 1.165 + 1.166 +SkDisplayable* SkApply::deepCopy(SkAnimateMaker* maker) { 1.167 + SkDrawable* saveScope = scope; 1.168 + scope = NULL; 1.169 + SkApply* result = (SkApply*) INHERITED::deepCopy(maker); 1.170 + result->scope = scope = saveScope; 1.171 + SkAnimateBase** end = fAnimators.end(); 1.172 + for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < end; animPtr++) { 1.173 + SkAnimateBase* anim = (SkAnimateBase*) (*animPtr)->deepCopy(maker); 1.174 + *result->fAnimators.append() = anim; 1.175 + maker->helperAdd(anim); 1.176 + } 1.177 + return result; 1.178 +} 1.179 + 1.180 +void SkApply::disable() { 1.181 + //!!! this is the right thing to do, but has bad side effects because of other problems 1.182 + // currently, if an apply is in a g and scopes a statement in another g, it ends up as members 1.183 + // of both containers. The disabling here incorrectly disables both instances 1.184 + // maybe the fEnabled flag needs to be moved to the fActive data so that both 1.185 + // instances are not affected. 1.186 +// fEnabled = false; 1.187 +} 1.188 + 1.189 +bool SkApply::draw(SkAnimateMaker& maker) { 1.190 + if (scope ==NULL) 1.191 + return false; 1.192 + if (scope->isApply() || scope->isDrawable() == false) 1.193 + return false; 1.194 + if (fEnabled == false) 1.195 + enable(maker); 1.196 + SkASSERT(scope); 1.197 + activate(maker); 1.198 + if (mode == kMode_immediate) 1.199 + return fActive->draw(); 1.200 + bool result = interpolate(maker, maker.getInTime()); 1.201 + if (dontDraw == false) { 1.202 +// if (scope->isDrawable()) 1.203 + result |= scope->draw(maker); 1.204 + } 1.205 + if (restore) { 1.206 + for (int index = 0; index < fActive->fAnimators.count(); index++) 1.207 + endSave(index); 1.208 + fActive->advance(); 1.209 + } 1.210 + return result; 1.211 +} 1.212 + 1.213 +#ifdef SK_DUMP_ENABLED 1.214 +void SkApply::dump(SkAnimateMaker* maker) { 1.215 + dumpBase(maker); 1.216 + if (dynamicScope.isEmpty() == false) 1.217 + SkDebugf("dynamicScope=\"%s\" ", dynamicScope.c_str()); 1.218 + if (dontDraw) 1.219 + SkDebugf("dontDraw=\"true\" "); 1.220 + if (begin != 0) //perhaps we want this no matter what? 1.221 + SkDebugf("begin=\"%g\" ", (float) begin/1000.0f); //is this correct? 1.222 + if (interval != (SkMSec) -1) 1.223 + SkDebugf("interval=\"%g\" ", (float) interval/1000.0f); 1.224 + if (steps != -1) 1.225 + SkDebugf("steps=\"%d\" ", steps); 1.226 + if (restore) 1.227 + SkDebugf("restore=\"true\" "); 1.228 + if (transition == kTransition_reverse) 1.229 + SkDebugf("transition=\"reverse\" "); 1.230 + if (mode == kMode_immediate) { 1.231 + SkDebugf("mode=\"immediate\" "); 1.232 + } 1.233 + else if (mode == kMode_create) { 1.234 + SkDebugf("mode=\"create\" "); 1.235 + } 1.236 + bool closedYet = false; 1.237 + SkDisplayList::fIndent += 4; 1.238 + int save = SkDisplayList::fDumpIndex; 1.239 + if (scope) { 1.240 + if (closedYet == false) { 1.241 + SkDebugf(">\n"); 1.242 + closedYet = true; 1.243 + } 1.244 + scope->dump(maker); 1.245 + } 1.246 + int index; 1.247 +// if (fActive) { 1.248 + for (index = 0; index < fAnimators.count(); index++) { 1.249 + if (closedYet == false) { 1.250 + SkDebugf(">\n"); 1.251 + closedYet = true; 1.252 + } 1.253 + SkAnimateBase* animator = fAnimators[index]; 1.254 + animator->dump(maker); 1.255 +// } 1.256 + } 1.257 + SkDisplayList::fIndent -= 4; 1.258 + SkDisplayList::fDumpIndex = save; 1.259 + if (closedYet) 1.260 + dumpEnd(maker); 1.261 + else 1.262 + SkDebugf("/>\n"); 1.263 +} 1.264 +#endif 1.265 + 1.266 +bool SkApply::enable(SkAnimateMaker& maker) { 1.267 + fEnabled = true; 1.268 + bool initialized = fActive != NULL; 1.269 + if (dynamicScope.size() > 0) 1.270 + enableDynamic(maker); 1.271 + if (maker.fError.hasError()) 1.272 + return false; 1.273 + int animators = fAnimators.count(); 1.274 + int index; 1.275 + for (index = 0; index < animators; index++) { 1.276 + SkAnimateBase* animator = fAnimators[index]; 1.277 + animator->fStart = maker.fEnableTime; 1.278 + animator->fResetPending = animator->fReset; 1.279 + } 1.280 + if (scope && scope->isApply()) 1.281 + ((SkApply*) scope)->setEmbedded(); 1.282 +/* if (mode == kMode_once) { 1.283 + if (scope) { 1.284 + activate(maker); 1.285 + interpolate(maker, maker.fEnableTime); 1.286 + inactivate(maker); 1.287 + } 1.288 + return true; 1.289 + }*/ 1.290 + if ((mode == kMode_immediate || mode == kMode_create) && scope == NULL) 1.291 + return false; // !!! error? 1.292 + bool enableMe = scope && (scope->hasEnable() || scope->isApply() || scope->isDrawable() == false); 1.293 + if ((mode == kMode_immediate && enableMe) || mode == kMode_create) 1.294 + activate(maker); // for non-drawables like post, prime them here 1.295 + if (mode == kMode_immediate && enableMe) 1.296 + fActive->enable(); 1.297 + if (mode == kMode_create && scope != NULL) { 1.298 + enableCreate(maker); 1.299 + return true; 1.300 + } 1.301 + if (mode == kMode_immediate) { 1.302 + return scope->isApply() || scope->isDrawable() == false; 1.303 + } 1.304 + refresh(maker); 1.305 + SkDisplayList& displayList = maker.fDisplayList; 1.306 + SkDrawable* drawable; 1.307 +#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING 1.308 + SkString debugOut; 1.309 + SkMSec time = maker.getAppTime(); 1.310 + debugOut.appendS32(time - maker.fDebugTimeBase); 1.311 + debugOut.append(" apply enable id="); 1.312 + debugOut.append(_id); 1.313 + debugOut.append("; start="); 1.314 + debugOut.appendS32(maker.fEnableTime - maker.fDebugTimeBase); 1.315 + SkDebugf("%s\n", debugOut.c_str()); 1.316 +#endif 1.317 + if (scope == NULL || scope->isApply() || scope->getType() == SkType_Movie || scope->isDrawable() == false) { 1.318 + activate(maker); // for non-drawables like post, prime them here 1.319 + if (initialized) { 1.320 + append(this); 1.321 + } 1.322 + fEnabling = true; 1.323 + interpolate(maker, maker.fEnableTime); 1.324 + fEnabling = false; 1.325 + if (scope != NULL && dontDraw == false) 1.326 + scope->enable(maker); 1.327 + return true; 1.328 + } else if (initialized && restore == false) 1.329 + append(this); 1.330 +#if 0 1.331 + bool wasActive = inactivate(maker); // start fresh 1.332 + if (wasActive) { 1.333 + activate(maker); 1.334 + interpolate(maker, maker.fEnableTime); 1.335 + return true; 1.336 + } 1.337 +#endif 1.338 +// start here; 1.339 + // now that one apply might embed another, only the parent apply should replace the scope 1.340 + // or get appended to the display list 1.341 + // similarly, an apply added by an add immediate has already been located in the display list 1.342 + // and should not get moved or added again here 1.343 + if (fEmbedded) { 1.344 + return false; // already added to display list by embedder 1.345 + } 1.346 + drawable = (SkDrawable*) scope; 1.347 + SkTDDrawableArray* parentList; 1.348 + SkTDDrawableArray* grandList; 1.349 + SkGroup* parentGroup; 1.350 + SkGroup* thisGroup; 1.351 + int old = displayList.findGroup(drawable, &parentList, &parentGroup, &thisGroup, &grandList); 1.352 + if (old < 0) 1.353 + goto append; 1.354 + else if (fContainsScope) { 1.355 + if ((*parentList)[old] != this || restore) { 1.356 +append: 1.357 + if (parentGroup) 1.358 + parentGroup->markCopySize(old); 1.359 + if (parentList->count() < 10000) { 1.360 + fAppended = true; 1.361 + *parentList->append() = this; 1.362 + } else 1.363 + maker.setErrorCode(SkDisplayXMLParserError::kDisplayTreeTooDeep); 1.364 + old = -1; 1.365 + } else 1.366 + reset(); 1.367 + } else { 1.368 + SkASSERT(old < parentList->count()); 1.369 + if ((*parentList)[old]->isApply()) { 1.370 + SkApply* apply = (SkApply*) (*parentList)[old]; 1.371 + if (apply != this && apply->fActive == NULL) 1.372 + apply->activate(maker); 1.373 + apply->append(this); 1.374 + parentGroup = NULL; 1.375 + } else { 1.376 + if (parentGroup) 1.377 + parentGroup->markCopySize(old); 1.378 + SkDrawable** newApplyLocation = &(*parentList)[old]; 1.379 + SkGroup* pGroup; 1.380 + int oldApply = displayList.findGroup(this, &parentList, &pGroup, &thisGroup, &grandList); 1.381 + if (oldApply >= 0) { 1.382 + (*parentList)[oldApply] = (SkDrawable*) SkDisplayType::CreateInstance(&maker, SkType_Apply); 1.383 + parentGroup = NULL; 1.384 + fDeleteScope = true; 1.385 + } 1.386 + *newApplyLocation = this; 1.387 + } 1.388 + } 1.389 + if (parentGroup) { 1.390 + parentGroup->markCopySet(old); 1.391 + fDeleteScope = dynamicScope.size() == 0; 1.392 + } 1.393 + return true; 1.394 +} 1.395 + 1.396 +void SkApply::enableCreate(SkAnimateMaker& maker) { 1.397 + SkString newID; 1.398 + for (int step = 0; step <= steps; step++) { 1.399 + fLastTime = step * SK_MSec1; 1.400 + bool success = maker.computeID(scope, this, &newID); 1.401 + if (success == false) 1.402 + return; 1.403 + if (maker.find(newID.c_str(), NULL)) 1.404 + continue; 1.405 + SkApply* copy = (SkApply*) deepCopy(&maker); // work on copy of animator state 1.406 + if (mode == kMode_create) 1.407 + copy->mode = (Mode) -1; 1.408 + SkDrawable* copyScope = copy->scope = (SkDrawable*) scope->deepCopy(&maker); 1.409 + *fScopes.append() = copyScope; 1.410 + if (copyScope->resolveIDs(maker, scope, this)) { 1.411 + step = steps; // quit 1.412 + goto next; // resolveIDs failed 1.413 + } 1.414 + if (newID.size() > 0) 1.415 + maker.setID(copyScope, newID); 1.416 + if (copy->resolveIDs(maker, this, this)) { // fix up all fields, including target 1.417 + step = steps; // quit 1.418 + goto next; // resolveIDs failed 1.419 + } 1.420 + copy->activate(maker); 1.421 + copy->interpolate(maker, step * SK_MSec1); 1.422 + maker.removeActive(copy->fActive); 1.423 + next: 1.424 + delete copy; 1.425 + } 1.426 +} 1.427 + 1.428 +void SkApply::enableDynamic(SkAnimateMaker& maker) { 1.429 + SkASSERT(mode != kMode_create); // create + dynamic are not currently compatible 1.430 + SkDisplayable* newScope; 1.431 + bool success = SkAnimatorScript::EvaluateDisplayable(maker, this, dynamicScope.c_str(), 1.432 + &newScope); 1.433 + if (success && scope != newScope) { 1.434 + SkTDDrawableArray* pList, * gList; 1.435 + SkGroup* pGroup = NULL, * found = NULL; 1.436 + int old = maker.fDisplayList.findGroup(scope, &pList, &pGroup, &found, &gList); 1.437 + if (pList && old >= 0 && (*pList)[old]->isApply() && (*pList)[old] != this) { 1.438 + if (fAppended == false) { 1.439 + if (found != NULL) { 1.440 + SkDisplayable* oldChild = (*pList)[old]; 1.441 + if (oldChild->isApply() && found->copySet(old)) { 1.442 + found->markCopyClear(old); 1.443 + // delete oldChild; 1.444 + } 1.445 + } 1.446 + (*pList)[old] = scope; 1.447 + } else 1.448 + pList->remove(old); 1.449 + } 1.450 + scope = (SkDrawable*) newScope; 1.451 + onEndElement(maker); 1.452 + } 1.453 + maker.removeActive(fActive); 1.454 + delete fActive; 1.455 + fActive = NULL; 1.456 +} 1.457 + 1.458 +void SkApply::endSave(int index) { 1.459 + SkAnimateBase* animate = fActive->fAnimators[index]; 1.460 + const SkMemberInfo* info = animate->fFieldInfo; 1.461 + SkDisplayTypes type = (SkDisplayTypes) info->fType; 1.462 + if (type == SkType_MemberFunction) 1.463 + return; 1.464 + SkDisplayable* target = getTarget(animate); 1.465 + size_t size = info->getSize(target); 1.466 + int count = (int) (size / sizeof(SkScalar)); 1.467 + int activeIndex = fActive->fDrawIndex + index; 1.468 + SkOperand* last = new SkOperand[count]; 1.469 + SkAutoTDelete<SkOperand> autoLast(last); 1.470 + if (type != SkType_MemberProperty) { 1.471 + info->getValue(target, last, count); 1.472 + SkOperand* saveOperand = fActive->fSaveRestore[activeIndex]; 1.473 + if (saveOperand) 1.474 + info->setValue(target, fActive->fSaveRestore[activeIndex], count); 1.475 + } else { 1.476 + SkScriptValue scriptValue; 1.477 + SkDEBUGCODE(bool success = ) target->getProperty(info->propertyIndex(), &scriptValue); 1.478 + SkASSERT(success == true); 1.479 + last[0] = scriptValue.fOperand; 1.480 + scriptValue.fOperand = fActive->fSaveRestore[activeIndex][0]; 1.481 + target->setProperty(info->propertyIndex(), scriptValue); 1.482 + } 1.483 + SkOperand* save = fActive->fSaveRestore[activeIndex]; 1.484 + if (save) 1.485 + memcpy(save, last, count * sizeof(SkOperand)); 1.486 +} 1.487 + 1.488 +bool SkApply::getProperty(int index, SkScriptValue* value) const { 1.489 + switch (index) { 1.490 + case SK_PROPERTY(step): 1.491 + value->fType = SkType_Int; 1.492 + value->fOperand.fS32 = fLastTime / SK_MSec1; 1.493 + break; 1.494 + case SK_PROPERTY(steps): 1.495 + value->fType = SkType_Int; 1.496 + value->fOperand.fS32 = steps; 1.497 + break; 1.498 + case SK_PROPERTY(time): 1.499 + value->fType = SkType_MSec; 1.500 + value->fOperand.fS32 = fLastTime; 1.501 + break; 1.502 + default: 1.503 + // SkASSERT(0); 1.504 + return false; 1.505 + } 1.506 + return true; 1.507 +} 1.508 + 1.509 +void SkApply::getStep(SkScriptValue* value) { 1.510 + getProperty(SK_PROPERTY(step), value); 1.511 +} 1.512 + 1.513 +SkDrawable* SkApply::getTarget(SkAnimateBase* animate) { 1.514 + if (animate->fTargetIsScope == false || mode != kMode_create) 1.515 + return animate->fTarget; 1.516 + return scope; 1.517 +} 1.518 + 1.519 +bool SkApply::hasDelayedAnimator() const { 1.520 + SkAnimateBase* const* animEnd = fAnimators.end(); 1.521 + for (SkAnimateBase* const* animPtr = fAnimators.begin(); animPtr < animEnd; animPtr++) { 1.522 + SkAnimateBase* const animator = *animPtr; 1.523 + if (animator->fDelayed) 1.524 + return true; 1.525 + } 1.526 + return false; 1.527 +} 1.528 + 1.529 +bool SkApply::hasEnable() const { 1.530 + return true; 1.531 +} 1.532 + 1.533 +bool SkApply::inactivate(SkAnimateMaker& maker) { 1.534 + if (fActive == NULL) 1.535 + return false; 1.536 + maker.removeActive(fActive); 1.537 + delete fActive; 1.538 + fActive = NULL; 1.539 + return true; 1.540 +} 1.541 + 1.542 +#ifdef SK_DEBUG 1.543 +SkMSec lastTime = (SkMSec) -1; 1.544 +#endif 1.545 + 1.546 +bool SkApply::interpolate(SkAnimateMaker& maker, SkMSec rawTime) { 1.547 + if (fActive == NULL) 1.548 + return false; 1.549 + bool result = false; 1.550 +#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING 1.551 + SkMSec time = maker.getAppTime(); 1.552 + if (lastTime == (SkMSec) -1) 1.553 + lastTime = rawTime - 1; 1.554 + if (fActive != NULL && 1.555 + strcmp(id, "a3") == 0 && rawTime > lastTime) { 1.556 + lastTime += 1000; 1.557 + SkString debugOut; 1.558 + debugOut.appendS32(time - maker.fDebugTimeBase); 1.559 + debugOut.append(" apply id="); 1.560 + debugOut.append(_id); 1.561 + debugOut.append("; "); 1.562 + debugOut.append(fActive->fAnimators[0]->_id); 1.563 + debugOut.append("="); 1.564 + debugOut.appendS32(rawTime - fActive->fState[0].fStartTime); 1.565 + debugOut.append(")"); 1.566 + SkDebugf("%s\n", debugOut.c_str()); 1.567 + } 1.568 +#endif 1.569 + fActive->start(); 1.570 + if (restore) 1.571 + fActive->initializeSave(); 1.572 + int animators = fActive->fAnimators.count(); 1.573 + for (int inner = 0; inner < animators; inner++) { 1.574 + SkAnimateBase* animate = fActive->fAnimators[inner]; 1.575 + if (animate->fChanged) { 1.576 + animate->fChanged = false; 1.577 + animate->fStart = rawTime; 1.578 + // SkTypedArray values; 1.579 + // int count = animate->fValues.count(); 1.580 + // values.setCount(count); 1.581 + // memcpy(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count); 1.582 + animate->onEndElement(maker); 1.583 + // if (memcmp(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count) != 0) { 1.584 + fActive->append(this); 1.585 + fActive->start(); 1.586 + // } 1.587 + } 1.588 + SkMSec time = fActive->getTime(rawTime, inner); 1.589 + SkActive::SkState& state = fActive->fState[inner]; 1.590 + if (SkMSec_LT(rawTime, state.fStartTime)) { 1.591 + if (fEnabling) { 1.592 + animate->fDelayed = true; 1.593 + maker.delayEnable(this, state.fStartTime); 1.594 + } 1.595 + continue; 1.596 + } else 1.597 + animate->fDelayed = false; 1.598 + SkMSec innerTime = fLastTime = state.getRelativeTime(time); 1.599 + if (restore) 1.600 + fActive->restoreInterpolatorValues(inner); 1.601 + if (animate->fReset) { 1.602 + if (transition != SkApply::kTransition_reverse) { 1.603 + if (SkMSec_LT(state.fBegin + state.fDuration, innerTime)) { 1.604 + if (animate->fResetPending) { 1.605 + innerTime = 0; 1.606 + animate->fResetPending = false; 1.607 + } else 1.608 + continue; 1.609 + } 1.610 + } else if (innerTime == 0) { 1.611 + if (animate->fResetPending) { 1.612 + innerTime = state.fBegin + state.fDuration; 1.613 + animate->fResetPending = false; 1.614 + } else 1.615 + continue; 1.616 + } 1.617 + } 1.618 + int count = animate->components(); 1.619 + SkAutoSTMalloc<16, SkOperand> values(count); 1.620 + SkInterpolatorBase::Result interpResult = fActive->fInterpolators[inner]->timeToValues( 1.621 + innerTime, values.get()); 1.622 + result |= (interpResult != SkInterpolatorBase::kFreezeEnd_Result); 1.623 + if (((transition != SkApply::kTransition_reverse && interpResult == SkInterpolatorBase::kFreezeEnd_Result) || 1.624 + (transition == SkApply::kTransition_reverse && fLastTime == 0)) && state.fUnpostedEndEvent) { 1.625 +// SkDEBUGF(("interpolate: post on end\n")); 1.626 + state.fUnpostedEndEvent = false; 1.627 + maker.postOnEnd(animate, state.fBegin + state.fDuration); 1.628 + maker.fAdjustedStart = 0; // !!! left over from synchronizing animation days, undoubtably out of date (and broken) 1.629 + } 1.630 + if (animate->formula.size() > 0) { 1.631 + if (fLastTime > animate->dur) 1.632 + fLastTime = animate->dur; 1.633 + SkTypedArray formulaValues; 1.634 + formulaValues.setCount(count); 1.635 + SkDEBUGCODE(bool success = ) animate->fFieldInfo->setValue(maker, &formulaValues, 0, 0, NULL, 1.636 + animate->getValuesType(), animate->formula); 1.637 + SkASSERT(success); 1.638 + if (restore) 1.639 + save(inner); // save existing value 1.640 + applyValues(inner, formulaValues.begin(), count, animate->getValuesType(), innerTime); 1.641 + } else { 1.642 + if (restore) 1.643 + save(inner); // save existing value 1.644 + applyValues(inner, values.get(), count, animate->getValuesType(), innerTime); 1.645 + } 1.646 + } 1.647 + return result; 1.648 +} 1.649 + 1.650 +void SkApply::initialize() { 1.651 + if (scope == NULL) 1.652 + return; 1.653 + if (scope->isApply() || scope->isDrawable() == false) 1.654 + return; 1.655 + scope->initialize(); 1.656 +} 1.657 + 1.658 +void SkApply::onEndElement(SkAnimateMaker& maker) 1.659 +{ 1.660 + SkDrawable* scopePtr = scope; 1.661 + while (scopePtr && scopePtr->isApply()) { 1.662 + SkApply* scopedApply = (SkApply*) scopePtr; 1.663 + if (scopedApply->scope == this) { 1.664 + maker.setErrorCode(SkDisplayXMLParserError::kApplyScopesItself); 1.665 + return; 1.666 + } 1.667 + scopePtr = scopedApply->scope; 1.668 + } 1.669 + if (mode == kMode_create) 1.670 + return; 1.671 + if (scope != NULL && steps >= 0 && scope->isApply() == false && scope->isDrawable()) 1.672 + scope->setSteps(steps); 1.673 + for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < fAnimators.end(); animPtr++) { 1.674 + SkAnimateBase* anim = *animPtr; 1.675 + //for reusing apply statements with dynamic scope 1.676 + if (anim->fTarget == NULL || anim->fTargetIsScope) { 1.677 + anim->fTargetIsScope = true; 1.678 + if (scope) 1.679 + anim->fTarget = scope; 1.680 + else 1.681 + anim->setTarget(maker); 1.682 + anim->onEndElement(maker); // allows animate->fFieldInfo to be set 1.683 + } 1.684 + if (scope != NULL && steps >= 0 && anim->fTarget != scope && anim->fTarget->isDrawable()) 1.685 + anim->fTarget->setSteps(steps); 1.686 + } 1.687 +} 1.688 + 1.689 +const SkMemberInfo* SkApply::preferredChild(SkDisplayTypes type) { 1.690 + SkASSERT(SkDisplayType::IsAnimate(type) == false); 1.691 + fContainsScope = true; 1.692 + return getMember("scope"); // !!! cwap! need to refer to member through enum like kScope instead 1.693 +} 1.694 + 1.695 +void SkApply::refresh(SkAnimateMaker& maker) { 1.696 + for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < fAnimators.end(); animPtr++) { 1.697 + SkAnimateBase* animate = *animPtr; 1.698 + animate->onEndElement(maker); 1.699 + } 1.700 + if (fActive) 1.701 + fActive->resetInterpolators(); 1.702 +} 1.703 + 1.704 +void SkApply::reset() { 1.705 + if (fActive) 1.706 + fActive->resetState(); 1.707 +} 1.708 + 1.709 +bool SkApply::resolveIDs(SkAnimateMaker& maker, SkDisplayable* original, SkApply* apply) { // replace to/formula strings in animators of the form xxx.step with the step value, if xxx.step is in scope 1.710 + if (resolveField(maker, apply, &dynamicScope) == false) 1.711 + return true; // failed 1.712 + SkAnimateBase** endPtr = fAnimators.end(); 1.713 + SkAnimateBase** origPtr = ((SkApply*) original)->fAnimators.begin(); 1.714 + for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < endPtr; ) { 1.715 + SkAnimateBase* animator = *animPtr++; 1.716 + maker.resolveID(animator, *origPtr++); 1.717 + if (resolveField(maker, this, &animator->target) == false) 1.718 + return true; 1.719 + if (resolveField(maker, this, &animator->from) == false) 1.720 + return true; 1.721 + if (resolveField(maker, this, &animator->to) == false) 1.722 + return true; 1.723 + if (resolveField(maker, this, &animator->formula) == false) 1.724 + return true; 1.725 + } 1.726 +// setEmbedded(); 1.727 + onEndElement(maker); 1.728 + return false; // succeeded 1.729 +} 1.730 + 1.731 +bool SkApply::resolveField(SkAnimateMaker& maker, SkDisplayable* parent, SkString* str) { 1.732 + const char* script = str->c_str(); 1.733 + if (str->startsWith("#string:") == false) 1.734 + return true; 1.735 + script += sizeof("#string:") - 1; 1.736 + return SkAnimatorScript::EvaluateString(maker, this, parent, script, str); 1.737 +} 1.738 + 1.739 +void SkApply::save(int index) { 1.740 + SkAnimateBase* animate = fActive->fAnimators[index]; 1.741 + const SkMemberInfo * info = animate->fFieldInfo; 1.742 + SkDisplayable* target = getTarget(animate); 1.743 +// if (animate->hasExecute()) 1.744 +// info = animate->getResolvedInfo(); 1.745 + SkDisplayTypes type = (SkDisplayTypes) info->fType; 1.746 + if (type == SkType_MemberFunction) 1.747 + return; // nothing to save 1.748 + size_t size = info->getSize(target); 1.749 + int count = (int) (size / sizeof(SkScalar)); 1.750 + bool useLast = true; 1.751 +// !!! this all may be unneeded, at least in the dynamic case ?? 1.752 + int activeIndex = fActive->fDrawIndex + index; 1.753 + SkTDOperandArray last; 1.754 + if (fActive->fSaveRestore[activeIndex] == NULL) { 1.755 + fActive->fSaveRestore[activeIndex] = new SkOperand[count]; 1.756 + useLast = false; 1.757 + } else { 1.758 + last.setCount(count); 1.759 + memcpy(last.begin(), fActive->fSaveRestore[activeIndex], count * sizeof(SkOperand)); 1.760 + } 1.761 + if (type != SkType_MemberProperty) { 1.762 + info->getValue(target, fActive->fSaveRestore[activeIndex], count); 1.763 + if (useLast) 1.764 + info->setValue(target, last.begin(), count); 1.765 + } else { 1.766 + SkScriptValue scriptValue; 1.767 + SkDEBUGCODE(bool success = ) target->getProperty(info->propertyIndex(), &scriptValue); 1.768 + SkASSERT(success == true); 1.769 + SkASSERT(scriptValue.fType == SkType_Float); 1.770 + fActive->fSaveRestore[activeIndex][0] = scriptValue.fOperand; 1.771 + if (useLast) { 1.772 + SkScriptValue scriptValue; 1.773 + scriptValue.fType = type; 1.774 + scriptValue.fOperand = last[0]; 1.775 + target->setProperty(info->propertyIndex(), scriptValue); 1.776 + } 1.777 + } 1.778 +// !!! end of unneeded 1.779 +} 1.780 + 1.781 +bool SkApply::setProperty(int index, SkScriptValue& scriptValue) { 1.782 + switch (index) { 1.783 + case SK_PROPERTY(animator): { 1.784 + SkAnimateBase* animate = (SkAnimateBase*) scriptValue.fOperand.fDisplayable; 1.785 + SkASSERT(animate->isAnimate()); 1.786 + *fAnimators.append() = animate; 1.787 + return true; 1.788 + } 1.789 + case SK_PROPERTY(steps): 1.790 + steps = scriptValue.fOperand.fS32; 1.791 + if (fActive) 1.792 + fActive->setSteps(steps); 1.793 + return true; 1.794 + } 1.795 + return false; 1.796 +} 1.797 + 1.798 +void SkApply::setSteps(int _steps) { 1.799 + steps = _steps; 1.800 +} 1.801 + 1.802 +#ifdef SK_DEBUG 1.803 +void SkApply::validate() { 1.804 + if (fActive) 1.805 + fActive->validate(); 1.806 +} 1.807 +#endif