1 #define LOG_TAG "Layer"
2 #define LOG_NDEBUG 1
3
4 #include "config.h"
5 #include "Layer.h"
6
7 #include "AndroidLog.h"
8 #include "SkCanvas.h"
9
10 //#define DEBUG_DRAW_LAYER_BOUNDS
11 //#define DEBUG_TRACK_NEW_DELETE
12
13 #ifdef DEBUG_TRACK_NEW_DELETE
14 static int gLayerAllocCount;
15 #endif
16
17 ///////////////////////////////////////////////////////////////////////////////
18
Layer()19 Layer::Layer() {
20 fParent = NULL;
21 m_opacity = SK_Scalar1;
22 m_size.set(0, 0);
23 m_position.set(0, 0);
24 m_anchorPoint.set(SK_ScalarHalf, SK_ScalarHalf);
25
26 m_matrix.reset();
27 m_childrenMatrix.reset();
28 m_shouldInheritFromRootTransform = false;
29
30 m_hasOverflowChildren = false;
31 m_state = 0;
32
33 #ifdef DEBUG_TRACK_NEW_DELETE
34 gLayerAllocCount += 1;
35 SkDebugf("Layer new: %d\n", gLayerAllocCount);
36 #endif
37 }
38
Layer(const Layer & src)39 Layer::Layer(const Layer& src) : INHERITED() {
40 fParent = NULL;
41 m_opacity = src.m_opacity;
42 m_size = src.m_size;
43 m_position = src.m_position;
44 m_scrollOffset = src.m_scrollOffset;
45 m_anchorPoint = src.m_anchorPoint;
46
47 m_matrix = src.m_matrix;
48 m_childrenMatrix = src.m_childrenMatrix;
49 m_shouldInheritFromRootTransform = src.m_shouldInheritFromRootTransform;
50
51 m_hasOverflowChildren = src.m_hasOverflowChildren;
52 m_state = 0;
53
54 #ifdef DEBUG_TRACK_NEW_DELETE
55 gLayerAllocCount += 1;
56 SkDebugf("Layer copy: %d\n", gLayerAllocCount);
57 #endif
58 }
59
~Layer()60 Layer::~Layer() {
61 removeChildren();
62
63 #ifdef DEBUG_TRACK_NEW_DELETE
64 gLayerAllocCount -= 1;
65 SkDebugf("Layer delete: %d\n", gLayerAllocCount);
66 #endif
67 }
68
69 ///////////////////////////////////////////////////////////////////////////////
70
countChildren() const71 int Layer::countChildren() const {
72 return m_children.count();
73 }
74
getChild(int index) const75 Layer* Layer::getChild(int index) const {
76 if ((unsigned)index < (unsigned)m_children.count()) {
77 SkASSERT(m_children[index]->fParent == this);
78 return m_children[index];
79 }
80 return NULL;
81 }
82
addChild(Layer * child)83 Layer* Layer::addChild(Layer* child) {
84 SkASSERT(this != child);
85 child->ref();
86 child->detachFromParent();
87 SkASSERT(child->fParent == NULL);
88 child->fParent = this;
89
90 *m_children.append() = child;
91 return child;
92 }
93
detachFromParent()94 void Layer::detachFromParent() {
95 if (fParent) {
96 int index = fParent->m_children.find(this);
97 SkASSERT(index >= 0);
98 fParent->m_children.remove(index);
99 fParent = NULL;
100 unref(); // this call might delete us
101 }
102 }
103
removeChildren()104 void Layer::removeChildren() {
105 int count = m_children.count();
106 for (int i = 0; i < count; i++) {
107 Layer* child = m_children[i];
108 SkASSERT(child->fParent == this);
109 child->fParent = NULL; // in case it has more than one owner
110 child->unref();
111 }
112 m_children.reset();
113 }
114
getRootLayer() const115 Layer* Layer::getRootLayer() const {
116 const Layer* root = this;
117 while (root->fParent != NULL) {
118 root = root->fParent;
119 }
120 return const_cast<Layer*>(root);
121 }
122
123 ///////////////////////////////////////////////////////////////////////////////
124
getLocalTransform(SkMatrix * matrix) const125 void Layer::getLocalTransform(SkMatrix* matrix) const {
126 matrix->setTranslate(m_position.fX - m_scrollOffset.x(),
127 m_position.fY - m_scrollOffset.y());
128
129 SkScalar tx = SkScalarMul(m_anchorPoint.fX, m_size.width());
130 SkScalar ty = SkScalarMul(m_anchorPoint.fY, m_size.height());
131 matrix->preTranslate(tx, ty);
132 matrix->preConcat(getMatrix());
133 matrix->preTranslate(-tx, -ty);
134 }
135
localToAncestor(const Layer * ancestor,SkMatrix * matrix) const136 void Layer::localToAncestor(const Layer* ancestor, SkMatrix* matrix) const {
137 if (this == ancestor) {
138 matrix->setIdentity();
139 return;
140 }
141
142 getLocalTransform(matrix);
143
144 // Fixed position layers simply use the root layer's transform.
145 if (shouldInheritFromRootTransform()) {
146 ASSERT(!ancestor);
147 matrix->postConcat(getRootLayer()->getMatrix());
148 return;
149 }
150
151 // Apply the local and child transforms for every layer between this layer
152 // and ancestor.
153 ASSERT(isAncestor(ancestor));
154 for (const Layer* layer = this->fParent; layer != ancestor; layer = layer->fParent) {
155 SkMatrix tmp;
156 layer->getLocalTransform(&tmp);
157 tmp.preConcat(layer->getChildrenMatrix());
158 matrix->postConcat(tmp);
159 }
160
161 // If ancestor is not the root layer, apply its child transformation too.
162 if (ancestor)
163 matrix->postConcat(ancestor->getChildrenMatrix());
164 }
165
166 ///////////////////////////////////////////////////////////////////////////////
167
168 #include "SkString.h"
169
draw(SkCanvas * canvas,android::DrawExtra * extra,SkScalar opacity)170 void Layer::draw(SkCanvas* canvas, android::DrawExtra* extra, SkScalar opacity) {
171 #if 0
172 SkString str1, str2;
173 // getMatrix().toDumpString(&str1);
174 // getChildrenMatrix().toDumpString(&str2);
175 SkDebugf("--- drawlayer %p opacity %g size [%g %g] pos [%g %g] matrix %s children %s\n",
176 this, opacity * getOpacity(), m_size.width(), m_size.height(),
177 m_position.fX, m_position.fY, str1.c_str(), str2.c_str());
178 #endif
179
180 opacity = SkScalarMul(opacity, getOpacity());
181 if (opacity <= 0) {
182 // SkDebugf("---- abort drawing %p opacity %g\n", this, opacity);
183 return;
184 }
185
186 SkAutoCanvasRestore acr(canvas, true);
187
188 // apply our local transform
189 {
190 SkMatrix tmp;
191 getLocalTransform(&tmp);
192 if (shouldInheritFromRootTransform()) {
193 // should we also apply the root's childrenMatrix?
194 canvas->setMatrix(getRootLayer()->getMatrix());
195 }
196 canvas->concat(tmp);
197 }
198
199 onDraw(canvas, opacity, extra, FlattenedLayers);
200
201 #ifdef DEBUG_DRAW_LAYER_BOUNDS
202 {
203 SkRect r = SkRect::MakeSize(getSize());
204 SkPaint p;
205 p.setAntiAlias(true);
206 p.setStyle(SkPaint::kStroke_Style);
207 p.setStrokeWidth(SkIntToScalar(2));
208 p.setColor(0xFFFF44DD);
209 canvas->drawRect(r, p);
210 canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, p);
211 canvas->drawLine(r.fLeft, r.fBottom, r.fRight, r.fTop, p);
212 }
213 #endif
214
215 int count = countChildren();
216 if (count > 0) {
217 canvas->concat(getChildrenMatrix());
218 for (int i = 0; i < count; i++) {
219 getChild(i)->draw(canvas, extra, opacity);
220 }
221 }
222 }
223
isAncestor(const Layer * possibleAncestor) const224 bool Layer::isAncestor(const Layer* possibleAncestor) const {
225 if (!possibleAncestor)
226 return true;
227 for (const Layer* layer = getParent(); layer; layer = layer->getParent()) {
228 if (layer == possibleAncestor)
229 return true;
230 }
231 return false;
232 }
233
setState(WebCore::GLWebViewState * state)234 void Layer::setState(WebCore::GLWebViewState* state) {
235 m_state = state;
236 int count = countChildren();
237 for (int i = 0; i < count; i++)
238 m_children[i]->setState(state);
239 }
240