1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/animator/SkDrawGroup.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,321 @@ 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 "SkDrawGroup.h" 1.14 +#include "SkAnimateMaker.h" 1.15 +#include "SkAnimatorScript.h" 1.16 +#include "SkCanvas.h" 1.17 +#include "SkDisplayApply.h" 1.18 +#include "SkPaint.h" 1.19 +#ifdef SK_DEBUG 1.20 +#include "SkDisplayList.h" 1.21 +#endif 1.22 + 1.23 +#if SK_USE_CONDENSED_INFO == 0 1.24 + 1.25 +const SkMemberInfo SkGroup::fInfo[] = { 1.26 + SK_MEMBER(condition, String), 1.27 + SK_MEMBER(enableCondition, String) 1.28 +}; 1.29 + 1.30 +#endif 1.31 + 1.32 +DEFINE_GET_MEMBER(SkGroup); 1.33 + 1.34 +SkGroup::SkGroup() : fParentList(NULL), fOriginal(NULL) { 1.35 +} 1.36 + 1.37 +SkGroup::~SkGroup() { 1.38 + if (fOriginal) // has been copied 1.39 + return; 1.40 + int index = 0; 1.41 + int max = fCopies.count() << 5; 1.42 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.43 + if (index >= max || markedForDelete(index)) 1.44 + delete *ptr; 1.45 +// else { 1.46 +// SkApply* apply = (SkApply*) *ptr; 1.47 +// SkASSERT(apply->isApply()); 1.48 +// SkASSERT(apply->getScope()); 1.49 +// delete apply->getScope(); 1.50 +// } 1.51 + index++; 1.52 + } 1.53 +} 1.54 + 1.55 +bool SkGroup::addChild(SkAnimateMaker& , SkDisplayable* child) { 1.56 + SkASSERT(child); 1.57 +// SkASSERT(child->isDrawable()); 1.58 + *fChildren.append() = (SkDrawable*) child; 1.59 + if (child->isGroup()) { 1.60 + SkGroup* groupie = (SkGroup*) child; 1.61 + SkASSERT(groupie->fParentList == NULL); 1.62 + groupie->fParentList = &fChildren; 1.63 + } 1.64 + return true; 1.65 +} 1.66 + 1.67 +bool SkGroup::contains(SkDisplayable* match) { 1.68 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.69 + SkDrawable* drawable = *ptr; 1.70 + if (drawable == match || drawable->contains(match)) 1.71 + return true; 1.72 + } 1.73 + return false; 1.74 +} 1.75 + 1.76 +SkGroup* SkGroup::copy() { 1.77 + SkGroup* result = new SkGroup(); 1.78 + result->fOriginal = this; 1.79 + result->fChildren = fChildren; 1.80 + return result; 1.81 +} 1.82 + 1.83 +SkBool SkGroup::copySet(int index) { 1.84 + return (fCopies[index >> 5] & 1 << (index & 0x1f)) != 0; 1.85 +} 1.86 + 1.87 +SkDisplayable* SkGroup::deepCopy(SkAnimateMaker* maker) { 1.88 + SkDisplayable* copy = INHERITED::deepCopy(maker); 1.89 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.90 + SkDisplayable* displayable = (SkDisplayable*)*ptr; 1.91 + SkDisplayable* deeperCopy = displayable->deepCopy(maker); 1.92 + ((SkGroup*)copy)->addChild(*maker, deeperCopy); 1.93 + } 1.94 + return copy; 1.95 +} 1.96 + 1.97 +bool SkGroup::doEvent(SkDisplayEvent::Kind kind, SkEventState* state) { 1.98 + bool handled = false; 1.99 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.100 + SkDrawable* drawable = *ptr; 1.101 + if (drawable->isDrawable() == false) 1.102 + continue; 1.103 + handled |= drawable->doEvent(kind, state); 1.104 + } 1.105 + return handled; 1.106 +} 1.107 + 1.108 +bool SkGroup::draw(SkAnimateMaker& maker) { 1.109 + bool conditionTrue = ifCondition(maker, this, condition); 1.110 + bool result = false; 1.111 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.112 + SkDrawable* drawable = *ptr; 1.113 + if (drawable->isDrawable() == false) 1.114 + continue; 1.115 + if (conditionTrue == false) { 1.116 + if (drawable->isApply()) 1.117 + ((SkApply*) drawable)->disable(); 1.118 + continue; 1.119 + } 1.120 + maker.validate(); 1.121 + result |= drawable->draw(maker); 1.122 + maker.validate(); 1.123 + } 1.124 + return result; 1.125 +} 1.126 + 1.127 +#ifdef SK_DUMP_ENABLED 1.128 +void SkGroup::dump(SkAnimateMaker* maker) { 1.129 + dumpBase(maker); 1.130 + if (condition.size() > 0) 1.131 + SkDebugf("condition=\"%s\" ", condition.c_str()); 1.132 + if (enableCondition.size() > 0) 1.133 + SkDebugf("enableCondition=\"%s\" ", enableCondition.c_str()); 1.134 + dumpDrawables(maker); 1.135 +} 1.136 + 1.137 +void SkGroup::dumpDrawables(SkAnimateMaker* maker) { 1.138 + SkDisplayList::fIndent += 4; 1.139 + int save = SkDisplayList::fDumpIndex; 1.140 + SkDisplayList::fDumpIndex = 0; 1.141 + bool closedYet = false; 1.142 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.143 + if (closedYet == false) { 1.144 + closedYet = true; 1.145 + SkDebugf(">\n"); 1.146 + } 1.147 + SkDrawable* drawable = *ptr; 1.148 + drawable->dump(maker); 1.149 + SkDisplayList::fDumpIndex++; 1.150 + } 1.151 + SkDisplayList::fIndent -= 4; 1.152 + SkDisplayList::fDumpIndex = save; 1.153 + if (closedYet) //we had children, now it's time to close the group 1.154 + dumpEnd(maker); 1.155 + else //no children 1.156 + SkDebugf("/>\n"); 1.157 +} 1.158 + 1.159 +void SkGroup::dumpEvents() { 1.160 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.161 + SkDrawable* drawable = *ptr; 1.162 + drawable->dumpEvents(); 1.163 + } 1.164 +} 1.165 +#endif 1.166 + 1.167 +bool SkGroup::enable(SkAnimateMaker& maker ) { 1.168 + reset(); 1.169 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.170 + SkDrawable* drawable = *ptr; 1.171 + if (ifCondition(maker, drawable, enableCondition) == false) 1.172 + continue; 1.173 + drawable->enable(maker); 1.174 + } 1.175 + return true; // skip add; already added so that scope is findable by children 1.176 +} 1.177 + 1.178 +int SkGroup::findGroup(SkDrawable* match, SkTDDrawableArray** list, 1.179 + SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList) { 1.180 + *list = &fChildren; 1.181 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.182 + SkDrawable* drawable = *ptr; 1.183 + if (drawable->isGroup()) { 1.184 + SkGroup* childGroup = (SkGroup*) drawable; 1.185 + if (childGroup->fOriginal == match) 1.186 + goto foundMatch; 1.187 + } 1.188 + if (drawable == match) { 1.189 +foundMatch: 1.190 + *parent = this; 1.191 + return (int) (ptr - fChildren.begin()); 1.192 + } 1.193 + } 1.194 + *grandList = &fChildren; 1.195 + return SkDisplayList::SearchForMatch(match, list, parent, found, grandList); 1.196 +} 1.197 + 1.198 +bool SkGroup::hasEnable() const { 1.199 + return true; 1.200 +} 1.201 + 1.202 +bool SkGroup::ifCondition(SkAnimateMaker& maker, SkDrawable*, 1.203 + SkString& conditionString) { 1.204 + if (conditionString.size() == 0) 1.205 + return true; 1.206 + int32_t result; 1.207 + bool success = SkAnimatorScript::EvaluateInt(maker, this, conditionString.c_str(), &result); 1.208 +#ifdef SK_DUMP_ENABLED 1.209 + if (maker.fDumpGConditions) { 1.210 + SkDebugf("group: "); 1.211 + dumpBase(&maker); 1.212 + SkDebugf("condition=%s ", conditionString.c_str()); 1.213 + if (success == false) 1.214 + SkDebugf("(script failed)\n"); 1.215 + else 1.216 + SkDebugf("success=%s\n", result != 0 ? "true" : "false"); 1.217 + } 1.218 +#endif 1.219 + return success && result != 0; 1.220 +} 1.221 + 1.222 +void SkGroup::initialize() { 1.223 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.224 + SkDrawable* drawable = *ptr; 1.225 + if (drawable->isDrawable() == false) 1.226 + continue; 1.227 + drawable->initialize(); 1.228 + } 1.229 +} 1.230 + 1.231 +void SkGroup::markCopyClear(int index) { 1.232 + if (index < 0) 1.233 + index = fChildren.count(); 1.234 + fCopies[index >> 5] &= ~(1 << (index & 0x1f)); 1.235 +} 1.236 + 1.237 +void SkGroup::markCopySet(int index) { 1.238 + if (index < 0) 1.239 + index = fChildren.count(); 1.240 + fCopies[index >> 5] |= 1 << (index & 0x1f); 1.241 +} 1.242 + 1.243 +void SkGroup::markCopySize(int index) { 1.244 + if (index < 0) 1.245 + index = fChildren.count() + 1; 1.246 + int oldLongs = fCopies.count(); 1.247 + int newLongs = (index >> 5) + 1; 1.248 + if (oldLongs < newLongs) { 1.249 + fCopies.setCount(newLongs); 1.250 + memset(&fCopies[oldLongs], 0, (newLongs - oldLongs) << 2); 1.251 + } 1.252 +} 1.253 + 1.254 +void SkGroup::reset() { 1.255 + if (fOriginal) // has been copied 1.256 + return; 1.257 + int index = 0; 1.258 + int max = fCopies.count() << 5; 1.259 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.260 + if (index >= max || copySet(index) == false) 1.261 + continue; 1.262 + SkApply* apply = (SkApply*) *ptr; 1.263 + SkASSERT(apply->isApply()); 1.264 + SkASSERT(apply->getScope()); 1.265 + *ptr = apply->getScope(); 1.266 + markCopyClear(index); 1.267 + index++; 1.268 + } 1.269 +} 1.270 + 1.271 +bool SkGroup::resolveIDs(SkAnimateMaker& maker, SkDisplayable* orig, SkApply* apply) { 1.272 + SkGroup* original = (SkGroup*) orig; 1.273 + SkTDDrawableArray& originalChildren = original->fChildren; 1.274 + SkDrawable** originalPtr = originalChildren.begin(); 1.275 + SkDrawable** ptr = fChildren.begin(); 1.276 + SkDrawable** end = fChildren.end(); 1.277 + SkDrawable** origChild = ((SkGroup*) orig)->fChildren.begin(); 1.278 + while (ptr < end) { 1.279 + SkDrawable* drawable = *ptr++; 1.280 + maker.resolveID(drawable, *origChild++); 1.281 + if (drawable->resolveIDs(maker, *originalPtr++, apply) == true) 1.282 + return true; // failed 1.283 + } 1.284 + return false; 1.285 +} 1.286 + 1.287 +void SkGroup::setSteps(int steps) { 1.288 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.289 + SkDrawable* drawable = *ptr; 1.290 + if (drawable->isDrawable() == false) 1.291 + continue; 1.292 + drawable->setSteps(steps); 1.293 + } 1.294 +} 1.295 + 1.296 +#ifdef SK_DEBUG 1.297 +void SkGroup::validate() { 1.298 + for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 1.299 + SkDrawable* drawable = *ptr; 1.300 + drawable->validate(); 1.301 + } 1.302 +} 1.303 +#endif 1.304 + 1.305 +#if SK_USE_CONDENSED_INFO == 0 1.306 + 1.307 +const SkMemberInfo SkSave::fInfo[] = { 1.308 + SK_MEMBER_INHERITED 1.309 +}; 1.310 + 1.311 +#endif 1.312 + 1.313 +DEFINE_GET_MEMBER(SkSave); 1.314 + 1.315 +bool SkSave::draw(SkAnimateMaker& maker) { 1.316 + maker.fCanvas->save(); 1.317 + SkPaint* save = maker.fPaint; 1.318 + SkPaint local = SkPaint(*maker.fPaint); 1.319 + maker.fPaint = &local; 1.320 + bool result = INHERITED::draw(maker); 1.321 + maker.fPaint = save; 1.322 + maker.fCanvas->restore(); 1.323 + return result; 1.324 +}