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