1 /* libs/graphics/animator/SkDisplayList.cpp 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #include "SkDisplayList.h" 19 #include "SkAnimateActive.h" 20 #include "SkAnimateBase.h" 21 #include "SkAnimateMaker.h" 22 #include "SkDisplayApply.h" 23 #include "SkDrawable.h" 24 #include "SkDrawGroup.h" 25 #include "SkDrawMatrix.h" 26 #include "SkInterpolator.h" 27 #include "SkTime.h" 28 29 SkDisplayList::SkDisplayList() : fDrawBounds(true), fUnionBounds(false), fInTime(0) { 30 } 31 32 SkDisplayList::~SkDisplayList() { 33 } 34 35 void SkDisplayList::append(SkActive* active) { 36 *fActiveList.append() = active; 37 } 38 39 bool SkDisplayList::draw(SkAnimateMaker& maker, SkMSec inTime) { 40 validate(); 41 fInTime = inTime; 42 bool result = false; 43 fInvalBounds.setEmpty(); 44 if (fDrawList.count()) { 45 for (SkActive** activePtr = fActiveList.begin(); activePtr < fActiveList.end(); activePtr++) { 46 SkActive* active = *activePtr; 47 active->reset(); 48 } 49 for (int index = 0; index < fDrawList.count(); index++) { 50 SkDrawable* draw = fDrawList[index]; 51 draw->initialize(); // allow matrices to reset themselves 52 SkASSERT(draw->isDrawable()); 53 validate(); 54 result |= draw->draw(maker); 55 } 56 } 57 validate(); 58 return result; 59 } 60 61 int SkDisplayList::findGroup(SkDrawable* match, SkTDDrawableArray** list, 62 SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) { 63 *parent = NULL; 64 *list = &fDrawList; 65 *grandList = &fDrawList; 66 return SearchForMatch(match, list, parent, found, grandList); 67 } 68 69 void SkDisplayList::hardReset() { 70 fDrawList.reset(); 71 fActiveList.reset(); 72 } 73 74 bool SkDisplayList::onIRect(const SkIRect& r) { 75 fBounds = r; 76 return fDrawBounds; 77 } 78 79 int SkDisplayList::SearchForMatch(SkDrawable* match, SkTDDrawableArray** list, 80 SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) { 81 *found = NULL; 82 for (int index = 0; index < (*list)->count(); index++) { 83 SkDrawable* draw = (**list)[index]; 84 if (draw == match) 85 return index; 86 if (draw->isApply()) { 87 SkApply* apply = (SkApply*) draw; 88 if (apply->scope == match) 89 return index; 90 if (apply->scope->isGroup() && SearchGroupForMatch(apply->scope, match, list, parent, found, grandList, index)) 91 return index; 92 if (apply->mode == SkApply::kMode_create) { 93 for (SkDrawable** ptr = apply->fScopes.begin(); ptr < apply->fScopes.end(); ptr++) { 94 SkDrawable* scope = *ptr; 95 if (scope == match) 96 return index; 97 //perhaps should call SearchGroupForMatch here as well (on scope) 98 } 99 } 100 } 101 if (draw->isGroup() && SearchGroupForMatch(draw, match, list, parent, found, grandList, index)) 102 return index; 103 104 } 105 return -1; 106 } 107 108 bool SkDisplayList::SearchGroupForMatch(SkDrawable* draw, SkDrawable* match, SkTDDrawableArray** list, 109 SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList, int &index) { 110 SkGroup* group = (SkGroup*) draw; 111 if (group->getOriginal() == match) 112 return true; 113 SkTDDrawableArray* saveList = *list; 114 int groupIndex = group->findGroup(match, list, parent, found, grandList); 115 if (groupIndex >= 0) { 116 *found = group; 117 index = groupIndex; 118 return true; 119 } 120 *list = saveList; 121 return false; 122 } 123 124 void SkDisplayList::reset() { 125 for (int index = 0; index < fDrawList.count(); index++) { 126 SkDrawable* draw = fDrawList[index]; 127 if (draw->isApply() == false) 128 continue; 129 SkApply* apply = (SkApply*) draw; 130 apply->reset(); 131 } 132 } 133 134 void SkDisplayList::remove(SkActive* active) { 135 int index = fActiveList.find(active); 136 SkASSERT(index >= 0); 137 fActiveList.remove(index); // !!! could use shuffle instead 138 SkASSERT(fActiveList.find(active) < 0); 139 } 140 141 #ifdef SK_DUMP_ENABLED 142 int SkDisplayList::fDumpIndex; 143 int SkDisplayList::fIndent; 144 145 void SkDisplayList::dump(SkAnimateMaker* maker) { 146 fIndent = 0; 147 dumpInner(maker); 148 } 149 150 void SkDisplayList::dumpInner(SkAnimateMaker* maker) { 151 for (int index = 0; index < fDrawList.count(); index++) { 152 fDumpIndex = index; 153 fDrawList[fDumpIndex]->dump(maker); 154 } 155 } 156 157 #endif 158 159 #ifdef SK_DEBUG 160 void SkDisplayList::validate() { 161 for (int index = 0; index < fDrawList.count(); index++) { 162 SkDrawable* draw = fDrawList[index]; 163 draw->validate(); 164 } 165 } 166 #endif 167 168 169