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