|
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 |