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 "SkADrawable.h"
16 #include "SkDrawGroup.h"
17 #include "SkDrawMatrix.h"
18 #include "SkInterpolator.h"
19 #include "SkTime.h"
20
SkDisplayList()21 SkDisplayList::SkDisplayList() : fDrawBounds(true), fUnionBounds(false), fInTime(0) {
22 }
23
~SkDisplayList()24 SkDisplayList::~SkDisplayList() {
25 }
26
append(SkActive * active)27 void SkDisplayList::append(SkActive* active) {
28 *fActiveList.append() = active;
29 }
30
draw(SkAnimateMaker & maker,SkMSec inTime)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 SkADrawable* 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
findGroup(SkADrawable * match,SkTDDrawableArray ** list,SkGroup ** parent,SkGroup ** found,SkTDDrawableArray ** grandList)53 int SkDisplayList::findGroup(SkADrawable* match, SkTDDrawableArray** list,
54 SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) {
55 *parent = nullptr;
56 *list = &fDrawList;
57 *grandList = &fDrawList;
58 return SearchForMatch(match, list, parent, found, grandList);
59 }
60
hardReset()61 void SkDisplayList::hardReset() {
62 fDrawList.reset();
63 fActiveList.reset();
64 }
65
onIRect(const SkIRect & r)66 bool SkDisplayList::onIRect(const SkIRect& r) {
67 fBounds = r;
68 return fDrawBounds;
69 }
70
SearchForMatch(SkADrawable * match,SkTDDrawableArray ** list,SkGroup ** parent,SkGroup ** found,SkTDDrawableArray ** grandList)71 int SkDisplayList::SearchForMatch(SkADrawable* match, SkTDDrawableArray** list,
72 SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) {
73 *found = nullptr;
74 for (int index = 0; index < (*list)->count(); index++) {
75 SkADrawable* 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 (SkADrawable** ptr = apply->fScopes.begin(); ptr < apply->fScopes.end(); ptr++) {
86 SkADrawable* 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
SearchGroupForMatch(SkADrawable * draw,SkADrawable * match,SkTDDrawableArray ** list,SkGroup ** parent,SkGroup ** found,SkTDDrawableArray ** grandList,int & index)100 bool SkDisplayList::SearchGroupForMatch(SkADrawable* draw, SkADrawable* 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
reset()116 void SkDisplayList::reset() {
117 for (int index = 0; index < fDrawList.count(); index++) {
118 SkADrawable* draw = fDrawList[index];
119 if (draw->isApply() == false)
120 continue;
121 SkApply* apply = (SkApply*) draw;
122 apply->reset();
123 }
124 }
125
remove(SkActive * active)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
dump(SkAnimateMaker * maker)137 void SkDisplayList::dump(SkAnimateMaker* maker) {
138 fIndent = 0;
139 dumpInner(maker);
140 }
141
dumpInner(SkAnimateMaker * maker)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
validate()152 void SkDisplayList::validate() {
153 for (int index = 0; index < fDrawList.count(); index++) {
154 SkADrawable* draw = fDrawList[index];
155 draw->validate();
156 }
157 }
158 #endif
159