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 ANDROID_HWUI_SNAPSHOT_H
18#define ANDROID_HWUI_SNAPSHOT_H
19
20#include <GLES2/gl2.h>
21#include <GLES2/gl2ext.h>
22
23#include <utils/RefBase.h>
24#include <ui/Region.h>
25
26#include <SkRegion.h>
27
28#include "Layer.h"
29#include "Matrix.h"
30#include "Rect.h"
31
32namespace android {
33namespace uirenderer {
34
35/**
36 * A snapshot holds information about the current state of the rendering
37 * surface. A snapshot is usually created whenever the user calls save()
38 * and discarded when the user calls restore(). Once a snapshot is created,
39 * it can hold information for deferred rendering.
40 *
41 * Each snapshot has a link to a previous snapshot, indicating the previous
42 * state of the renderer.
43 */
44class Snapshot: public LightRefBase<Snapshot> {
45public:
46
47    Snapshot();
48    Snapshot(const sp<Snapshot>& s, int saveFlags);
49
50    /**
51     * Various flags set on ::flags.
52     */
53    enum Flags {
54        /**
55         * Indicates that the clip region was modified. When this
56         * snapshot is restored so must the clip.
57         */
58        kFlagClipSet = 0x1,
59        /**
60         * Indicates that this snapshot was created when saving
61         * a new layer.
62         */
63        kFlagIsLayer = 0x2,
64        /**
65         * Indicates that this snapshot is a special type of layer
66         * backed by an FBO. This flag only makes sense when the
67         * flag kFlagIsLayer is also set.
68         */
69        kFlagIsFboLayer = 0x4,
70        /**
71         * Indicates that this snapshot has changed the ortho matrix.
72         */
73        kFlagDirtyOrtho = 0x8,
74        /**
75         * Indicates that this snapshot or an ancestor snapshot is
76         * an FBO layer.
77         */
78        kFlagFboTarget = 0x10
79    };
80
81    /**
82     * Modifies the current clip with the new clip rectangle and
83     * the specified operation. The specified rectangle is transformed
84     * by this snapshot's trasnformation.
85     */
86    bool clip(float left, float top, float right, float bottom,
87            SkRegion::Op op = SkRegion::kIntersect_Op);
88
89    /**
90     * Modifies the current clip with the new clip rectangle and
91     * the specified operation. The specified rectangle is considered
92     * already transformed.
93     */
94    bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op);
95
96    /**
97     * Sets the current clip.
98     */
99    void setClip(float left, float top, float right, float bottom);
100
101    /**
102     * Returns the current clip in local coordinates. The clip rect is
103     * transformed by the inverse transform matrix.
104     */
105    const Rect& getLocalClip();
106
107    /**
108     * Resets the clip to the specified rect.
109     */
110    void resetClip(float left, float top, float right, float bottom);
111
112    /**
113     * Resets the current transform to a pure 3D translation.
114     */
115    void resetTransform(float x, float y, float z);
116
117    /**
118     * Indicates whether this snapshot should be ignored. A snapshot
119     * is typicalled ignored if its layer is invisible or empty.
120     */
121    bool isIgnored() const;
122
123    /**
124     * Indicates whether the current transform has perspective components.
125     */
126    bool hasPerspectiveTransform() const;
127
128    /**
129     * Dirty flags.
130     */
131    int flags;
132
133    /**
134     * Previous snapshot.
135     */
136    sp<Snapshot> previous;
137
138    /**
139     * Only set when the flag kFlagIsLayer is set.
140     *
141     * This snapshot does not own the layer, this pointer must not be freed.
142     */
143    Layer* layer;
144
145    /**
146     * Target FBO used for rendering. Set to 0 when rendering directly
147     * into the framebuffer.
148     */
149    GLuint fbo;
150
151    /**
152     * Indicates that this snapshot is invisible and nothing should be drawn
153     * inside it. This flag is set only when the layer clips drawing to its
154     * bounds and is passed to subsequent snapshots.
155     */
156    bool invisible;
157
158    /**
159     * If set to true, the layer will not be composited. This is similar to
160     * invisible but this flag is not passed to subsequent snapshots.
161     */
162    bool empty;
163
164    /**
165     * Current viewport.
166     */
167    Rect viewport;
168
169    /**
170     * Height of the framebuffer the snapshot is rendering into.
171     */
172    int height;
173
174    /**
175     * Contains the previous ortho matrix.
176     */
177    mat4 orthoMatrix;
178
179    /**
180     * Local transformation. Holds the current translation, scale and
181     * rotation values.
182     *
183     * This is a reference to a matrix owned by this snapshot or another
184     *  snapshot. This pointer must not be freed. See ::mTransformRoot.
185     */
186    mat4* transform;
187
188    /**
189     * Current clip rect. The clip is stored in canvas-space coordinates,
190     * (screen-space coordinates in the regular case.)
191     *
192     * This is a reference to a rect owned by this snapshot or another
193     * snapshot. This pointer must not be freed. See ::mClipRectRoot.
194     */
195    Rect* clipRect;
196
197    /**
198     * Current clip region. The clip is stored in canvas-space coordinates,
199     * (screen-space coordinates in the regular case.)
200     *
201     * This is a reference to a region owned by this snapshot or another
202     * snapshot. This pointer must not be freed. See ::mClipRegionRoot.
203     *
204     * This field is used only if STENCIL_BUFFER_SIZE is > 0.
205     */
206    SkRegion* clipRegion;
207
208    /**
209     * The ancestor layer's dirty region.
210     *
211     * This is a reference to a region owned by a layer. This pointer must
212     * not be freed.
213     */
214    Region* region;
215
216    /**
217     * Current alpha value. This value is 1 by default, but may be set by a DisplayList which
218     * has translucent rendering in a non-overlapping View. This value will be used by
219     * the renderer to set the alpha in the current color being used for ensuing drawing
220     * operations. The value is inherited by child snapshots because the same value should
221     * be applied to descendents of the current DisplayList (for example, a TextView contains
222     * the base alpha value which should be applied to the child DisplayLists used for drawing
223     * the actual text).
224     */
225    float alpha;
226
227private:
228    void ensureClipRegion();
229    void copyClipRectFromRegion();
230
231    bool clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op);
232
233    mat4 mTransformRoot;
234    Rect mClipRectRoot;
235    Rect mLocalClip;
236
237#if STENCIL_BUFFER_SIZE
238    SkRegion mClipRegionRoot;
239#endif
240
241}; // class Snapshot
242
243}; // namespace uirenderer
244}; // namespace android
245
246#endif // ANDROID_HWUI_SNAPSHOT_H
247