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