gfx/skia/trunk/src/animator/SkDisplayApply.cpp

changeset 0
6474c204b198
     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

mercurial