1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/animator/SkAnimateMaker.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,372 @@ 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 "SkAnimateMaker.h" 1.14 +#include "SkAnimator.h" 1.15 +#include "SkAnimatorScript.h" 1.16 +#include "SkDisplayable.h" 1.17 +#include "SkDisplayApply.h" 1.18 +#include "SkDisplayList.h" 1.19 +#include "SkDisplayMovie.h" 1.20 +#include "SkDisplayType.h" 1.21 +#include "SkExtras.h" 1.22 +#include "SkMemberInfo.h" 1.23 +#include "SkStream.h" 1.24 +#include "SkSystemEventTypes.h" 1.25 +#include "SkTime.h" 1.26 + 1.27 +class DefaultTimeline : public SkAnimator::Timeline { 1.28 + virtual SkMSec getMSecs() const { 1.29 + return SkTime::GetMSecs(); 1.30 + } 1.31 +} gDefaultTimeline; 1.32 + 1.33 +SkAnimateMaker::SkAnimateMaker(SkAnimator* animator, SkCanvas* canvas, SkPaint* paint) 1.34 + : fActiveEvent(NULL), fAdjustedStart(0), fCanvas(canvas), fEnableTime(0), 1.35 + fHostEventSinkID(0), fMinimumInterval((SkMSec) -1), fPaint(paint), fParentMaker(NULL), 1.36 + fTimeline(&gDefaultTimeline), fInInclude(false), fInMovie(false), 1.37 + fFirstScriptError(false), fLoaded(false), fIDs(256), fAnimator(animator) 1.38 +{ 1.39 + fScreenplay.time = 0; 1.40 +#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING 1.41 + fDebugTimeBase = (SkMSec) -1; 1.42 +#endif 1.43 +#ifdef SK_DUMP_ENABLED 1.44 + fDumpEvents = fDumpGConditions = fDumpPosts = false; 1.45 +#endif 1.46 +} 1.47 + 1.48 +SkAnimateMaker::~SkAnimateMaker() { 1.49 + deleteMembers(); 1.50 +} 1.51 + 1.52 +#if 0 1.53 +SkMSec SkAnimateMaker::adjustDelay(SkMSec expectedBase, SkMSec delay) { 1.54 + SkMSec appTime = (*fTimeCallBack)(); 1.55 + if (appTime) 1.56 + delay -= appTime - expectedBase; 1.57 + if (delay < 0) 1.58 + delay = 0; 1.59 + return delay; 1.60 +} 1.61 +#endif 1.62 + 1.63 +void SkAnimateMaker::appendActive(SkActive* active) { 1.64 + fDisplayList.append(active); 1.65 +} 1.66 + 1.67 +void SkAnimateMaker::clearExtraPropertyCallBack(SkDisplayTypes type) { 1.68 + SkExtras** end = fExtras.end(); 1.69 + for (SkExtras** extraPtr = fExtras.begin(); extraPtr < end; extraPtr++) { 1.70 + SkExtras* extra = *extraPtr; 1.71 + if (extra->definesType(type)) { 1.72 + extra->fExtraCallBack = NULL; 1.73 + extra->fExtraStorage = NULL; 1.74 + break; 1.75 + } 1.76 + } 1.77 +} 1.78 + 1.79 +bool SkAnimateMaker::computeID(SkDisplayable* displayable, SkDisplayable* parent, SkString* newID) { 1.80 + const char* script; 1.81 + if (findKey(displayable, &script) == false) 1.82 + return true; 1.83 + return SkAnimatorScript::EvaluateString(*this, displayable, parent, script, newID); 1.84 +} 1.85 + 1.86 +SkDisplayable* SkAnimateMaker::createInstance(const char name[], size_t len) { 1.87 + SkDisplayTypes type = SkDisplayType::GetType(this, name, len ); 1.88 + if ((int)type >= 0) 1.89 + return SkDisplayType::CreateInstance(this, type); 1.90 + return NULL; 1.91 +} 1.92 + 1.93 +// differs from SkAnimator::decodeStream in that it does not reset error state 1.94 +bool SkAnimateMaker::decodeStream(SkStream* stream) 1.95 +{ 1.96 + SkDisplayXMLParser parser(*this); 1.97 + return parser.parse(*stream); 1.98 +} 1.99 + 1.100 +// differs from SkAnimator::decodeURI in that it does not set URI base 1.101 +bool SkAnimateMaker::decodeURI(const char uri[]) { 1.102 +// SkDebugf("animator decode %s\n", uri); 1.103 + 1.104 +// SkStream* stream = SkStream::GetURIStream(fPrefix.c_str(), uri); 1.105 + SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(uri)); 1.106 + if (stream.get()) { 1.107 + bool success = decodeStream(stream); 1.108 + if (hasError() && fError.hasNoun() == false) 1.109 + fError.setNoun(uri); 1.110 + return success; 1.111 + } else { 1.112 + return false; 1.113 + } 1.114 +} 1.115 + 1.116 +#if defined SK_DEBUG && 0 1.117 +//used for the if'd out section of deleteMembers 1.118 +#include "SkTSearch.h" 1.119 + 1.120 +extern "C" { 1.121 + int compare_disp(const void* a, const void* b) { 1.122 + return *(const SkDisplayable**)a - *(const SkDisplayable**)b; 1.123 + } 1.124 +} 1.125 +#endif 1.126 + 1.127 +void SkAnimateMaker::delayEnable(SkApply* apply, SkMSec time) { 1.128 + int index = fDelayed.find(apply); 1.129 + if (index < 0) { 1.130 + *fDelayed.append() = apply; 1.131 + } 1.132 + 1.133 + (new SkEvent(SK_EventType_Delay, fAnimator->getSinkID()))->postTime(time); 1.134 +} 1.135 + 1.136 +void SkAnimateMaker::deleteMembers() { 1.137 + int index; 1.138 +#if defined SK_DEBUG && 0 1.139 + //this code checks to see if helpers are among the children, but it is not complete - 1.140 + //it should check the children of the children 1.141 + int result; 1.142 + SkTDArray<SkDisplayable*> children(fChildren.begin(), fChildren.count()); 1.143 + SkQSort(children.begin(), children.count(), sizeof(SkDisplayable*),compare_disp); 1.144 + for (index = 0; index < fHelpers.count(); index++) { 1.145 + SkDisplayable* helper = fHelpers[index]; 1.146 + result = SkTSearch(children.begin(), children.count(), helper, sizeof(SkDisplayable*)); 1.147 + SkASSERT(result < 0); 1.148 + } 1.149 +#endif 1.150 + for (index = 0; index < fChildren.count(); index++) { 1.151 + SkDisplayable* child = fChildren[index]; 1.152 + delete child; 1.153 + } 1.154 + for (index = 0; index < fHelpers.count(); index++) { 1.155 + SkDisplayable* helper = fHelpers[index]; 1.156 + delete helper; 1.157 + } 1.158 + for (index = 0; index < fExtras.count(); index++) { 1.159 + SkExtras* extras = fExtras[index]; 1.160 + delete extras; 1.161 + } 1.162 +} 1.163 + 1.164 +void SkAnimateMaker::doDelayedEvent() { 1.165 + fEnableTime = getAppTime(); 1.166 + for (int index = 0; index < fDelayed.count(); ) { 1.167 + SkDisplayable* child = fDelayed[index]; 1.168 + SkASSERT(child->isApply()); 1.169 + SkApply* apply = (SkApply*) child; 1.170 + apply->interpolate(*this, fEnableTime); 1.171 + if (apply->hasDelayedAnimator()) 1.172 + index++; 1.173 + else 1.174 + fDelayed.remove(index); 1.175 + } 1.176 +} 1.177 + 1.178 +bool SkAnimateMaker::doEvent(const SkEvent& event) { 1.179 + return (!fInMovie || fLoaded) && fAnimator->doEvent(event); 1.180 +} 1.181 + 1.182 +#ifdef SK_DUMP_ENABLED 1.183 +void SkAnimateMaker::dump(const char* match) { 1.184 + SkTDict<SkDisplayable*>::Iter iter(fIDs); 1.185 + const char* name; 1.186 + SkDisplayable* result; 1.187 + while ((name = iter.next(&result)) != NULL) { 1.188 + if (strcmp(match,name) == 0) 1.189 + result->dump(this); 1.190 + } 1.191 +} 1.192 +#endif 1.193 + 1.194 +int SkAnimateMaker::dynamicProperty(SkString& nameStr, SkDisplayable** displayablePtr ) { 1.195 + const char* name = nameStr.c_str(); 1.196 + const char* dot = strchr(name, '.'); 1.197 + SkASSERT(dot); 1.198 + SkDisplayable* displayable; 1.199 + if (find(name, dot - name, &displayable) == false) { 1.200 + SkASSERT(0); 1.201 + return 0; 1.202 + } 1.203 + const char* fieldName = dot + 1; 1.204 + const SkMemberInfo* memberInfo = displayable->getMember(fieldName); 1.205 + *displayablePtr = displayable; 1.206 + return (int) memberInfo->fOffset; 1.207 +} 1.208 + 1.209 +SkMSec SkAnimateMaker::getAppTime() const { 1.210 + return fTimeline->getMSecs(); 1.211 +} 1.212 + 1.213 +#ifdef SK_DEBUG 1.214 +SkAnimator* SkAnimateMaker::getRoot() 1.215 +{ 1.216 + SkAnimateMaker* maker = this; 1.217 + while (maker->fParentMaker) 1.218 + maker = maker->fParentMaker; 1.219 + return maker == this ? NULL : maker->fAnimator; 1.220 +} 1.221 +#endif 1.222 + 1.223 +void SkAnimateMaker::helperAdd(SkDisplayable* trackMe) { 1.224 + SkASSERT(fHelpers.find(trackMe) < 0); 1.225 + *fHelpers.append() = trackMe; 1.226 +} 1.227 + 1.228 +void SkAnimateMaker::helperRemove(SkDisplayable* alreadyTracked) { 1.229 + int helperIndex = fHelpers.find(alreadyTracked); 1.230 + if (helperIndex >= 0) 1.231 + fHelpers.remove(helperIndex); 1.232 +} 1.233 + 1.234 +#if 0 1.235 +void SkAnimateMaker::loadMovies() { 1.236 + for (SkDisplayable** dispPtr = fMovies.begin(); dispPtr < fMovies.end(); dispPtr++) { 1.237 + SkDisplayable* displayable = *dispPtr; 1.238 + SkASSERT(displayable->getType() == SkType_Movie); 1.239 + SkDisplayMovie* movie = (SkDisplayMovie*) displayable; 1.240 + SkAnimateMaker* movieMaker = movie->fMovie.fMaker; 1.241 + movieMaker->fEvents.doEvent(*movieMaker, SkDisplayEvent::kOnload, NULL); 1.242 + movieMaker->fEvents.removeEvent(SkDisplayEvent::kOnload, NULL); 1.243 + movieMaker->loadMovies(); 1.244 + } 1.245 +} 1.246 +#endif 1.247 + 1.248 +void SkAnimateMaker::notifyInval() { 1.249 + if (fHostEventSinkID) 1.250 + fAnimator->onEventPost(new SkEvent(SK_EventType_Inval), fHostEventSinkID); 1.251 +} 1.252 + 1.253 +void SkAnimateMaker::notifyInvalTime(SkMSec time) { 1.254 + if (fHostEventSinkID) 1.255 + fAnimator->onEventPostTime(new SkEvent(SK_EventType_Inval), fHostEventSinkID, time); 1.256 +} 1.257 + 1.258 +void SkAnimateMaker::postOnEnd(SkAnimateBase* animate, SkMSec end) { 1.259 + SkEvent evt; 1.260 + evt.setS32("time", animate->getStart() + end); 1.261 + evt.setPtr("anim", animate); 1.262 + evt.setType(SK_EventType_OnEnd); 1.263 + SkEventSinkID sinkID = fAnimator->getSinkID(); 1.264 + fAnimator->onEventPost(new SkEvent(evt), sinkID); 1.265 +} 1.266 + 1.267 +void SkAnimateMaker::reset() { 1.268 + deleteMembers(); 1.269 + fChildren.reset(); 1.270 + fHelpers.reset(); 1.271 + fIDs.reset(); 1.272 + fEvents.reset(); 1.273 + fDisplayList.hardReset(); 1.274 +} 1.275 + 1.276 +void SkAnimateMaker::removeActive(SkActive* active) { 1.277 + if (active == NULL) 1.278 + return; 1.279 + fDisplayList.remove(active); 1.280 +} 1.281 + 1.282 +bool SkAnimateMaker::resolveID(SkDisplayable* displayable, SkDisplayable* original) { 1.283 + SkString newID; 1.284 + bool success = computeID(original, NULL, &newID); 1.285 + if (success) 1.286 + setID(displayable, newID); 1.287 + return success; 1.288 +} 1.289 + 1.290 +void SkAnimateMaker::setErrorString() { 1.291 + fErrorString.reset(); 1.292 + if (fError.hasError()) { 1.293 + SkString err; 1.294 + if (fFileName.size() > 0) 1.295 + fErrorString.set(fFileName.c_str()); 1.296 + else 1.297 + fErrorString.set("screenplay error"); 1.298 + int line = fError.getLineNumber(); 1.299 + if (line >= 0) { 1.300 + fErrorString.append(", "); 1.301 + fErrorString.append("line "); 1.302 + fErrorString.appendS32(line); 1.303 + } 1.304 + fErrorString.append(": "); 1.305 + fError.getErrorString(&err); 1.306 + fErrorString.append(err); 1.307 +#if defined SK_DEBUG 1.308 + SkDebugf("%s\n", fErrorString.c_str()); 1.309 +#endif 1.310 + } 1.311 +} 1.312 + 1.313 +void SkAnimateMaker::setEnableTime(SkMSec appTime, SkMSec expectedTime) { 1.314 +#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING 1.315 + SkString debugOut; 1.316 + SkMSec time = getAppTime(); 1.317 + debugOut.appendS32(time - fDebugTimeBase); 1.318 + debugOut.append(" set enable old enable="); 1.319 + debugOut.appendS32(fEnableTime - fDebugTimeBase); 1.320 + debugOut.append(" old adjust="); 1.321 + debugOut.appendS32(fAdjustedStart); 1.322 + debugOut.append(" new enable="); 1.323 + debugOut.appendS32(expectedTime - fDebugTimeBase); 1.324 + debugOut.append(" new adjust="); 1.325 + debugOut.appendS32(appTime - expectedTime); 1.326 + SkDebugf("%s\n", debugOut.c_str()); 1.327 +#endif 1.328 + fAdjustedStart = appTime - expectedTime; 1.329 + fEnableTime = expectedTime; 1.330 + SkDisplayable** firstMovie = fMovies.begin(); 1.331 + SkDisplayable** endMovie = fMovies.end(); 1.332 + for (SkDisplayable** ptr = firstMovie; ptr < endMovie; ptr++) { 1.333 + SkDisplayMovie* movie = (SkDisplayMovie*) *ptr; 1.334 + movie->fMovie.fMaker->setEnableTime(appTime, expectedTime); 1.335 + } 1.336 +} 1.337 + 1.338 +void SkAnimateMaker::setExtraPropertyCallBack(SkDisplayTypes type, 1.339 + SkScriptEngine::_propertyCallBack callBack, void* userStorage) { 1.340 + SkExtras** end = fExtras.end(); 1.341 + for (SkExtras** extraPtr = fExtras.begin(); extraPtr < end; extraPtr++) { 1.342 + SkExtras* extra = *extraPtr; 1.343 + if (extra->definesType(type)) { 1.344 + extra->fExtraCallBack = callBack; 1.345 + extra->fExtraStorage = userStorage; 1.346 + break; 1.347 + } 1.348 + } 1.349 +} 1.350 + 1.351 +void SkAnimateMaker::setID(SkDisplayable* displayable, const SkString& newID) { 1.352 + fIDs.set(newID.c_str(), displayable); 1.353 +#ifdef SK_DEBUG 1.354 + displayable->_id.set(newID); 1.355 + displayable->id = displayable->_id.c_str(); 1.356 +#endif 1.357 +} 1.358 + 1.359 +void SkAnimateMaker::setScriptError(const SkScriptEngine& engine) { 1.360 + SkString errorString; 1.361 +#ifdef SK_DEBUG 1.362 + engine.getErrorString(&errorString); 1.363 +#endif 1.364 + setErrorNoun(errorString); 1.365 + setErrorCode(SkDisplayXMLParserError::kErrorInScript); 1.366 +} 1.367 + 1.368 +bool SkAnimateMaker::GetStep(const char* token, size_t len, void* stepPtr, SkScriptValue* value) { 1.369 + if (SK_LITERAL_STR_EQUAL("step", token, len)) { 1.370 + value->fOperand.fS32 = *(int32_t*) stepPtr; 1.371 + value->fType = SkType_Int; 1.372 + return true; 1.373 + } 1.374 + return false; 1.375 +}