• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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