Snapshot.h revision ddc52285ca6fd147f442a21e90e0e4702a10d304
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     * Modifies the current clip with the specified region and operation.
98     * The specified region is considered already transformed.
99     */
100    bool clipRegionTransformed(const SkRegion& region, SkRegion::Op op);
101
102    /**
103     * Sets the current clip.
104     */
105    void setClip(float left, float top, float right, float bottom);
106
107    /**
108     * Returns the current clip in local coordinates. The clip rect is
109     * transformed by the inverse transform matrix.
110     */
111    const Rect& getLocalClip();
112
113    /**
114     * Returns the current clip in render target coordinates.
115     */
116    const Rect& getRenderTargetClip() { return *clipRect; }
117
118    /**
119     * Resets the clip to the specified rect.
120     */
121    void resetClip(float left, float top, float right, float bottom);
122
123    /**
124     * Resets the current transform to a pure 3D translation.
125     */
126    void resetTransform(float x, float y, float z);
127
128    /**
129     * Indicates whether this snapshot should be ignored. A snapshot
130     * is typicalled ignored if its layer is invisible or empty.
131     */
132    bool isIgnored() const;
133
134    /**
135     * Indicates whether the current transform has perspective components.
136     */
137    bool hasPerspectiveTransform() const;
138
139    /**
140     * Dirty flags.
141     */
142    int flags;
143
144    /**
145     * Previous snapshot.
146     */
147    sp<Snapshot> previous;
148
149    /**
150     * A pointer to the currently active layer.
151     *
152     * This snapshot does not own the layer, this pointer must not be freed.
153     */
154    Layer* layer;
155
156    /**
157     * Target FBO used for rendering. Set to 0 when rendering directly
158     * into the framebuffer.
159     */
160    GLuint fbo;
161
162    /**
163     * Indicates that this snapshot is invisible and nothing should be drawn
164     * inside it. This flag is set only when the layer clips drawing to its
165     * bounds and is passed to subsequent snapshots.
166     */
167    bool invisible;
168
169    /**
170     * If set to true, the layer will not be composited. This is similar to
171     * invisible but this flag is not passed to subsequent snapshots.
172     */
173    bool empty;
174
175    /**
176     * Current viewport.
177     */
178    Rect viewport;
179
180    /**
181     * Height of the framebuffer the snapshot is rendering into.
182     */
183    int height;
184
185    /**
186     * Contains the previous ortho matrix.
187     */
188    mat4 orthoMatrix;
189
190    /**
191     * Local transformation. Holds the current translation, scale and
192     * rotation values.
193     *
194     * This is a reference to a matrix owned by this snapshot or another
195     *  snapshot. This pointer must not be freed. See ::mTransformRoot.
196     */
197    mat4* transform;
198
199    /**
200     * Current clip rect. The clip is stored in canvas-space coordinates,
201     * (screen-space coordinates in the regular case.)
202     *
203     * This is a reference to a rect owned by this snapshot or another
204     * snapshot. This pointer must not be freed. See ::mClipRectRoot.
205     */
206    Rect* clipRect;
207
208    /**
209     * Current clip region. The clip is stored in canvas-space coordinates,
210     * (screen-space coordinates in the regular case.)
211     *
212     * This is a reference to a region owned by this snapshot or another
213     * snapshot. This pointer must not be freed. See ::mClipRegionRoot.
214     */
215    SkRegion* clipRegion;
216
217    /**
218     * The ancestor layer's dirty region.
219     *
220     * This is a reference to a region owned by a layer. This pointer must
221     * not be freed.
222     */
223    Region* region;
224
225    /**
226     * Current alpha value. This value is 1 by default, but may be set by a DisplayList which
227     * has translucent rendering in a non-overlapping View. This value will be used by
228     * the renderer to set the alpha in the current color being used for ensuing drawing
229     * operations. The value is inherited by child snapshots because the same value should
230     * be applied to descendents of the current DisplayList (for example, a TextView contains
231     * the base alpha value which should be applied to the child DisplayLists used for drawing
232     * the actual text).
233     */
234    float alpha;
235
236    void dump() const;
237
238private:
239    void ensureClipRegion();
240    void copyClipRectFromRegion();
241
242    bool clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op);
243
244    mat4 mTransformRoot;
245    Rect mClipRectRoot;
246    Rect mLocalClip; // don't use directly, call getLocalClip() which initializes this
247
248    SkRegion mClipRegionRoot;
249
250}; // class Snapshot
251
252}; // namespace uirenderer
253}; // namespace android
254
255#endif // ANDROID_HWUI_SNAPSHOT_H
256