1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef Layer_DEFINED
18#define Layer_DEFINED
19
20#include "TestExport.h"
21#include "SkRefCnt.h"
22#include "SkTDArray.h"
23#include "SkColor.h"
24#include "SkMatrix.h"
25#include "SkPoint.h"
26#include "SkRect.h"
27#include "SkRegion.h"
28#include "SkSize.h"
29
30namespace WebCore {
31class IntRect;
32class GLWebViewState;
33};
34
35class SkCanvas;
36
37class TEST_EXPORT Layer : public SkRefCnt {
38
39public:
40    Layer();
41    Layer(const Layer&);
42    virtual ~Layer();
43
44    // Whether the layer should apply its tranform directly onto the root
45    // layer, rather than using the transforms of all ancestor layers. This is
46    // used for fixed position layers.
47    bool shouldInheritFromRootTransform() const { return m_shouldInheritFromRootTransform; }
48    SkScalar getOpacity() const { return m_opacity; }
49    const SkSize& getSize() const { return m_size; }
50    const SkPoint& getPosition() const { return m_position; }
51    const SkPoint& getAnchorPoint() const { return m_anchorPoint; }
52    const SkMatrix& getMatrix() const { return m_matrix; }
53    const SkMatrix& getChildrenMatrix() const { return m_childrenMatrix; }
54
55    SkScalar getWidth() const { return m_size.width(); }
56    SkScalar getHeight() const { return m_size.height(); }
57
58    void setShouldInheritFromRootTransform(bool inherit) { m_shouldInheritFromRootTransform = inherit; }
59    void setOpacity(SkScalar opacity) { m_opacity = opacity; }
60    void setSize(SkScalar w, SkScalar h) { m_size.set(w, h); }
61    void setPosition(SkScalar x, SkScalar y) { m_position.set(x, y); }
62    void setAnchorPoint(SkScalar x, SkScalar y) { m_anchorPoint.set(x, y); }
63    void setMatrix(const SkMatrix& matrix) { m_matrix = matrix; }
64    void setChildrenMatrix(const SkMatrix& matrix) { m_childrenMatrix = matrix; }
65
66// rendering asset management
67
68    // tell rendering assets to update their tile content with most recent painted data
69    virtual void swapTiles() {}
70
71    // tell rendering assets to use this layer tree for drawing
72    virtual void setIsDrawing(bool isDrawing) {}
73
74    // take rendering assets from drawing tree, or create if they don't exist
75    virtual void setIsPainting(Layer* drawingTree) {}
76
77    // if a similar layer exists in the replacement tree, add invals to it
78    virtual void mergeInvalsInto(Layer* replacementTree) {}
79
80    void markAsDirty(const SkRegion& invalRegion) {
81        m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op);
82    }
83
84    bool isDirty() {
85        return !m_dirtyRegion.isEmpty();
86    }
87
88// drawing
89
90    virtual bool isReady() { return false; }
91
92    // TODO: clean out several of these, leave them in GLWebViewState
93
94    virtual bool prepare(double currentTime, WebCore::IntRect& viewRect,
95                         SkRect& visibleRect, float scale) { return 0; }
96    virtual bool drawGL(WebCore::IntRect& viewRect,
97                        SkRect& visibleRect, float scale) { return 0; }
98    WebCore::GLWebViewState* state() { return m_state; }
99    void setState(WebCore::GLWebViewState* state);
100
101// children
102
103    /** Return the number of layers in our child list.
104     */
105    int countChildren() const;
106
107    /** Return the child at the specified index (starting at 0). This does not
108        affect the reference count of the child.
109     */
110    Layer* getChild(int index) const;
111
112    /** Add this layer to our child list at the end (top-most), and ref() it.
113        If it was already in another hierarchy, remove it from that list.
114        Return the new child.
115     */
116    Layer* addChild(Layer* child);
117
118    /** Remove this layer from its parent's list (or do nothing if it has no
119        parent.) If it had a parent, then unref() is called.
120     */
121    void detachFromParent();
122
123    /** Remove, and unref(), all of the layers in our child list.
124     */
125    void removeChildren();
126
127    /** Return our parent layer, or NULL if we have none.
128     */
129    Layer* getParent() const { return fParent; }
130
131    /** Return the root layer in this hiearchy. If this layer is the root
132        (i.e. has no parent), then this returns itself.
133     */
134    Layer* getRootLayer() const;
135
136    // coordinate system transformations
137
138    /** Return, in matrix, the matix transfomations that are applied locally
139        when this layer draws (i.e. its position and matrix/anchorPoint).
140        This does not include the childrenMatrix, since that is only applied
141        after this layer draws (but before its children draw).
142     */
143    void getLocalTransform(SkMatrix* matrix) const;
144
145    /** Return, in matrix, the concatenation of transforms that are applied
146        from this layer's root parent to the layer itself.
147        This is the matrix that is applied to the layer during drawing.
148     */
149    void localToGlobal(SkMatrix* matrix) const { localToAncestor(0, matrix); }
150
151    /** Return, as a matrix, the transform that converts from this layer's local
152        space to the space of the given ancestor layer. Use NULL for ancestor to
153        represent the root layer. Note that this method must not be called on a
154        fixed position layer with ancestor != NULL.
155
156        For non-fixed position layers, the following holds (in pseudo-code for
157        brevity) ...
158        SkMatrix localToAncestor = layer->localToAncestor(ancestor);
159        SkMatrix ancestorToGlobal = ancestor->localToAncestor(NULL);
160        SkMatrix localToGlobal = layer->localToGlobal();
161        ASSERT(localToAncestor * ancestorToGlobal == localToGlobal);
162     */
163    void localToAncestor(const Layer* ancestor, SkMatrix* matrix) const;
164
165    // paint method
166
167    virtual bool drawCanvas(SkCanvas*) { return false; }
168    void draw(SkCanvas*, SkScalar opacity);
169    void draw(SkCanvas* canvas) {
170        this->draw(canvas, SK_Scalar1);
171    }
172
173    void setHasOverflowChildren(bool value) { m_hasOverflowChildren = value; }
174
175    virtual bool contentIsScrollable() const { return false; }
176
177protected:
178    virtual void onDraw(SkCanvas*, SkScalar opacity);
179
180    bool m_hasOverflowChildren;
181
182    bool isAncestor(const Layer*) const;
183
184    Layer* fParent;
185    SkScalar m_opacity;
186    SkSize m_size;
187    // The position of the origin of the layer, relative to the parent layer.
188    SkPoint m_position;
189    // The point in the layer used as the origin for local transformations,
190    // expressed as a fraction of the layer size.
191    SkPoint m_anchorPoint;
192    SkMatrix m_matrix;
193    SkMatrix m_childrenMatrix;
194    bool m_shouldInheritFromRootTransform;
195
196    SkTDArray<Layer*> m_children;
197
198    // invalidation region
199    SkRegion m_dirtyRegion;
200
201    WebCore::GLWebViewState* m_state;
202
203    typedef SkRefCnt INHERITED;
204};
205
206#endif
207