blob: 57f29f7a21ac3d384d5901f3edcf614df0871c7a [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/* 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
29SkDisplayList::SkDisplayList() : fDrawBounds(true), fUnionBounds(false), fInTime(0) {
30}
31
32SkDisplayList::~SkDisplayList() {
33}
34
35void SkDisplayList::append(SkActive* active) {
36 *fActiveList.append() = active;
37}
38
39bool 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
61int 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
69void SkDisplayList::hardReset() {
70 fDrawList.reset();
71 fActiveList.reset();
72}
73
74bool SkDisplayList::onIRect(const SkIRect& r) {
75 fBounds = r;
76 return fDrawBounds;
77}
78
79int 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
108bool 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
124void 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
134void 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
142int SkDisplayList::fDumpIndex;
143int SkDisplayList::fIndent;
144
145void SkDisplayList::dump(SkAnimateMaker* maker) {
146 fIndent = 0;
147 dumpInner(maker);
148}
149
150void 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
160void 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