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
SkDisplayList()29 SkDisplayList::SkDisplayList() : fDrawBounds(true), fUnionBounds(false), fInTime(0) {
30 }
31
~SkDisplayList()32 SkDisplayList::~SkDisplayList() {
33 }
34
append(SkActive * active)35 void SkDisplayList::append(SkActive* active) {
36 *fActiveList.append() = active;
37 }
38
draw(SkAnimateMaker & maker,SkMSec inTime)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
findGroup(SkDrawable * match,SkTDDrawableArray ** list,SkGroup ** parent,SkGroup ** found,SkTDDrawableArray ** grandList)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
hardReset()69 void SkDisplayList::hardReset() {
70 fDrawList.reset();
71 fActiveList.reset();
72 }
73
onIRect(const SkIRect & r)74 bool SkDisplayList::onIRect(const SkIRect& r) {
75 fBounds = r;
76 return fDrawBounds;
77 }
78
SearchForMatch(SkDrawable * match,SkTDDrawableArray ** list,SkGroup ** parent,SkGroup ** found,SkTDDrawableArray ** grandList)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
SearchGroupForMatch(SkDrawable * draw,SkDrawable * match,SkTDDrawableArray ** list,SkGroup ** parent,SkGroup ** found,SkTDDrawableArray ** grandList,int & index)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
reset()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
remove(SkActive * active)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
dump(SkAnimateMaker * maker)145 void SkDisplayList::dump(SkAnimateMaker* maker) {
146 fIndent = 0;
147 dumpInner(maker);
148 }
149
dumpInner(SkAnimateMaker * maker)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
validate()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