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