Snapshot.h revision deeda3d337aed1eee218b89a7aba5992ced371f0
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/LinearAllocator.h>
24#include <utils/RefBase.h>
25#include <ui/Region.h>
26
27#include <SkRegion.h>
28
29#include "Layer.h"
30#include "Matrix.h"
31#include "Outline.h"
32#include "Rect.h"
33#include "utils/Macros.h"
34
35namespace android {
36namespace uirenderer {
37
38/**
39 * Temporary structure holding information for a single outline clip.
40 *
41 * These structures are treated as immutable once created, and only exist for a single frame, which
42 * is why they may only be allocated with a LinearAllocator.
43 */
44class RoundRectClipState {
45public:
46    /** static void* operator new(size_t size); PURPOSELY OMITTED, allocator only **/
47    static void* operator new(size_t size, LinearAllocator& allocator) {
48        return allocator.alloc(size);
49    }
50
51    bool areaRequiresRoundRectClip(const Rect& rect) const {
52        return rect.intersects(dangerRects[0])
53                || rect.intersects(dangerRects[1])
54                || rect.intersects(dangerRects[2])
55                || rect.intersects(dangerRects[3]);
56    }
57
58    Matrix4 matrix;
59    Rect dangerRects[4];
60    Rect outlineInnerRect;
61    float outlineRadius;
62};
63
64/**
65 * A snapshot holds information about the current state of the rendering
66 * surface. A snapshot is usually created whenever the user calls save()
67 * and discarded when the user calls restore(). Once a snapshot is created,
68 * it can hold information for deferred rendering.
69 *
70 * Each snapshot has a link to a previous snapshot, indicating the previous
71 * state of the renderer.
72 */
73class Snapshot: public LightRefBase<Snapshot> {
74public:
75
76    Snapshot();
77    Snapshot(const sp<Snapshot>& s, int saveFlags);
78
79    /**
80     * Various flags set on ::flags.
81     */
82    enum Flags {
83        /**
84         * Indicates that the clip region was modified. When this
85         * snapshot is restored so must the clip.
86         */
87        kFlagClipSet = 0x1,
88        /**
89         * Indicates that this snapshot was created when saving
90         * a new layer.
91         */
92        kFlagIsLayer = 0x2,
93        /**
94         * Indicates that this snapshot is a special type of layer
95         * backed by an FBO. This flag only makes sense when the
96         * flag kFlagIsLayer is also set.
97         *
98         * Viewport has been modified to fit the new Fbo, and must be
99         * restored when this snapshot is restored.
100         */
101        kFlagIsFboLayer = 0x4,
102        /**
103         * Indicates that this snapshot or an ancestor snapshot is
104         * an FBO layer.
105         */
106        kFlagFboTarget = 0x8,
107    };
108
109    /**
110     * Modifies the current clip with the new clip rectangle and
111     * the specified operation. The specified rectangle is transformed
112     * by this snapshot's trasnformation.
113     */
114    bool clip(float left, float top, float right, float bottom,
115            SkRegion::Op op = SkRegion::kIntersect_Op);
116
117    /**
118     * Modifies the current clip with the new clip rectangle and
119     * the specified operation. The specified rectangle is considered
120     * already transformed.
121     */
122    bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op);
123
124    /**
125     * Modifies the current clip with the specified region and operation.
126     * The specified region is considered already transformed.
127     */
128    bool clipRegionTransformed(const SkRegion& region, SkRegion::Op op);
129
130    /**
131     * Sets the current clip.
132     */
133    void setClip(float left, float top, float right, float bottom);
134
135    /**
136     * Returns the current clip in local coordinates. The clip rect is
137     * transformed by the inverse transform matrix.
138     */
139    const Rect& getLocalClip();
140
141    /**
142     * Returns the current clip in render target coordinates.
143     */
144    const Rect& getRenderTargetClip() { return *clipRect; }
145
146    /**
147     * Resets the clip to the specified rect.
148     */
149    void resetClip(float left, float top, float right, float bottom);
150
151    /**
152     * Resets the current transform to a pure 3D translation.
153     */
154    void resetTransform(float x, float y, float z);
155
156    void initializeViewport(int width, int height) {
157        mViewportData.initialize(width, height);
158    }
159
160    int getViewportWidth() const { return mViewportData.mWidth; }
161    int getViewportHeight() const { return mViewportData.mHeight; }
162    const Matrix4& getOrthoMatrix() const { return mViewportData.mOrthoMatrix; }
163
164    /**
165     * Sets (and replaces) the current clipping outline
166     */
167    void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
168
169    /**
170     * Indicates whether this snapshot should be ignored. A snapshot
171     * is typicalled ignored if its layer is invisible or empty.
172     */
173    bool isIgnored() const;
174
175    /**
176     * Indicates whether the current transform has perspective components.
177     */
178    bool hasPerspectiveTransform() const;
179
180    /**
181     * Dirty flags.
182     */
183    int flags;
184
185    /**
186     * Previous snapshot.
187     */
188    sp<Snapshot> previous;
189
190    /**
191     * A pointer to the currently active layer.
192     *
193     * This snapshot does not own the layer, this pointer must not be freed.
194     */
195    Layer* layer;
196
197    /**
198     * Target FBO used for rendering. Set to 0 when rendering directly
199     * into the framebuffer.
200     */
201    GLuint fbo;
202
203    /**
204     * Indicates that this snapshot is invisible and nothing should be drawn
205     * inside it. This flag is set only when the layer clips drawing to its
206     * bounds and is passed to subsequent snapshots.
207     */
208    bool invisible;
209
210    /**
211     * If set to true, the layer will not be composited. This is similar to
212     * invisible but this flag is not passed to subsequent snapshots.
213     */
214    bool empty;
215
216    /**
217     * Local transformation. Holds the current translation, scale and
218     * rotation values.
219     *
220     * This is a reference to a matrix owned by this snapshot or another
221     *  snapshot. This pointer must not be freed. See ::mTransformRoot.
222     */
223    mat4* transform;
224
225    /**
226     * Current clip rect. The clip is stored in canvas-space coordinates,
227     * (screen-space coordinates in the regular case.)
228     *
229     * This is a reference to a rect owned by this snapshot or another
230     * snapshot. This pointer must not be freed. See ::mClipRectRoot.
231     */
232    Rect* clipRect;
233
234    /**
235     * Current clip region. The clip is stored in canvas-space coordinates,
236     * (screen-space coordinates in the regular case.)
237     *
238     * This is a reference to a region owned by this snapshot or another
239     * snapshot. This pointer must not be freed. See ::mClipRegionRoot.
240     */
241    SkRegion* clipRegion;
242
243    /**
244     * The ancestor layer's dirty region.
245     *
246     * This is a reference to a region owned by a layer. This pointer must
247     * not be freed.
248     */
249    Region* region;
250
251    /**
252     * Current alpha value. This value is 1 by default, but may be set by a DisplayList which
253     * has translucent rendering in a non-overlapping View. This value will be used by
254     * the renderer to set the alpha in the current color being used for ensuing drawing
255     * operations. The value is inherited by child snapshots because the same value should
256     * be applied to descendents of the current DisplayList (for example, a TextView contains
257     * the base alpha value which should be applied to the child DisplayLists used for drawing
258     * the actual text).
259     */
260    float alpha;
261
262    /**
263     * Current clipping round rect.
264     *
265     * Points to data not owned by the snapshot, and may only be replaced by subsequent RR clips,
266     * never modified.
267     */
268    const RoundRectClipState* roundRectClipState;
269
270    void dump() const;
271
272private:
273    struct ViewportData {
274        ViewportData() : mWidth(0), mHeight() {}
275        void initialize(int width, int height) {
276            mWidth = width;
277            mHeight = height;
278            mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
279        }
280
281        /*
282         * Width and height of current viewport.
283         *
284         * The viewport is always defined to be (0, 0, width, height).
285         */
286        int mWidth;
287        int mHeight;
288        /**
289         * Contains the current orthographic, projection matrix.
290         */
291        mat4 mOrthoMatrix;
292    };
293
294    void ensureClipRegion();
295    void copyClipRectFromRegion();
296
297    bool clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op);
298
299    mat4 mTransformRoot;
300    Rect mClipRectRoot;
301    Rect mLocalClip; // don't use directly, call getLocalClip() which initializes this
302
303    SkRegion mClipRegionRoot;
304    ViewportData mViewportData;
305
306}; // class Snapshot
307
308}; // namespace uirenderer
309}; // namespace android
310
311#endif // ANDROID_HWUI_SNAPSHOT_H
312