• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma once
18 
19 #include <GLES2/gl2.h>
20 #include <GLES2/gl2ext.h>
21 
22 #include <utils/LinearAllocator.h>
23 #include <utils/RefBase.h>
24 #include <ui/Region.h>
25 
26 #include <SkClipOp.h>
27 #include <SkRegion.h>
28 
29 #include "ClipArea.h"
30 #include "Layer.h"
31 #include "Matrix.h"
32 #include "Outline.h"
33 #include "Rect.h"
34 #include "utils/Macros.h"
35 
36 namespace android {
37 namespace uirenderer {
38 
39 /**
40  * Temporary structure holding information for a single outline clip.
41  *
42  * These structures are treated as immutable once created, and only exist for a single frame, which
43  * is why they may only be allocated with a LinearAllocator.
44  */
45 class RoundRectClipState {
46 public:
47     static void* operator new(size_t size) = delete;
new(size_t size,LinearAllocator & allocator)48     static void* operator new(size_t size, LinearAllocator& allocator) {
49         return allocator.alloc<RoundRectClipState>(size);
50     }
51 
areaRequiresRoundRectClip(const Rect & rect)52     bool areaRequiresRoundRectClip(const Rect& rect) const {
53         return rect.intersects(dangerRects[0])
54                 || rect.intersects(dangerRects[1])
55                 || rect.intersects(dangerRects[2])
56                 || rect.intersects(dangerRects[3]);
57     }
58 
59     bool highPriority;
60     Matrix4 matrix;
61     Rect dangerRects[4];
62     Rect innerRect;
63     float radius;
64 };
65 
66 /**
67  * A snapshot holds information about the current state of the rendering
68  * surface. A snapshot is usually created whenever the user calls save()
69  * and discarded when the user calls restore(). Once a snapshot is created,
70  * it can hold information for deferred rendering.
71  *
72  * Each snapshot has a link to a previous snapshot, indicating the previous
73  * state of the renderer.
74  */
75 class Snapshot {
76 public:
77 
78     Snapshot();
79     Snapshot(Snapshot* s, int saveFlags);
80 
81     /**
82      * Various flags set on ::flags.
83      */
84     enum Flags {
85         /**
86          * Indicates that the clip region was modified. When this
87          * snapshot is restored so must the clip.
88          */
89         kFlagClipSet = 0x1,
90         /**
91          * Indicates that this snapshot was created when saving
92          * a new layer.
93          */
94         kFlagIsLayer = 0x2,
95         /**
96          * Indicates that this snapshot is a special type of layer
97          * backed by an FBO. This flag only makes sense when the
98          * flag kFlagIsLayer is also set.
99          *
100          * Viewport has been modified to fit the new Fbo, and must be
101          * restored when this snapshot is restored.
102          */
103         kFlagIsFboLayer = 0x4,
104     };
105 
106     /**
107      * Modifies the current clip with the new clip rectangle and
108      * the specified operation. The specified rectangle is transformed
109      * by this snapshot's trasnformation.
110      */
111     void clip(const Rect& localClip, SkClipOp op);
112 
113     /**
114      * Modifies the current clip with the new clip rectangle and
115      * the specified operation. The specified rectangle is considered
116      * already transformed.
117      */
118     void clipTransformed(const Rect& r, SkClipOp op = SkClipOp::kIntersect);
119 
120     /**
121      * Modifies the current clip with the specified path and operation.
122      */
123     void clipPath(const SkPath& path, SkClipOp op);
124 
125     /**
126      * Sets the current clip.
127      */
128     void setClip(float left, float top, float right, float bottom);
129 
130     /**
131      * Returns the current clip in local coordinates. The clip rect is
132      * transformed by the inverse transform matrix.
133      */
134     ANDROID_API const Rect& getLocalClip();
135 
136     /**
137      * Returns the current clip in render target coordinates.
138      */
getRenderTargetClip()139     const Rect& getRenderTargetClip() const { return mClipArea->getClipRect(); }
140 
141     /*
142      * Accessor functions so that the clip area can stay private
143      */
clipIsEmpty()144     bool clipIsEmpty() const { return mClipArea->isEmpty(); }
getClipRegion()145     const SkRegion& getClipRegion() const { return mClipArea->getClipRegion(); }
clipIsSimple()146     bool clipIsSimple() const { return mClipArea->isSimple(); }
getClipArea()147     const ClipArea& getClipArea() const { return *mClipArea; }
mutateClipArea()148     ClipArea& mutateClipArea() { return *mClipArea; }
149 
150     WARN_UNUSED_RESULT const ClipBase* serializeIntersectedClip(LinearAllocator& allocator,
151             const ClipBase* recordedClip, const Matrix4& recordedClipTransform);
152     void applyClip(const ClipBase* clip, const Matrix4& transform);
153 
154     /**
155      * Resets the clip to the specified rect.
156      */
157     void resetClip(float left, float top, float right, float bottom);
158 
initializeViewport(int width,int height)159     void initializeViewport(int width, int height) {
160         mViewportData.initialize(width, height);
161         mClipAreaRoot.setViewportDimensions(width, height);
162     }
163 
getViewportWidth()164     int getViewportWidth() const { return mViewportData.mWidth; }
getViewportHeight()165     int getViewportHeight() const { return mViewportData.mHeight; }
getOrthoMatrix()166     const Matrix4& getOrthoMatrix() const { return mViewportData.mOrthoMatrix; }
167 
getRelativeLightCenter()168     const Vector3& getRelativeLightCenter() const { return mRelativeLightCenter; }
setRelativeLightCenter(const Vector3 & lightCenter)169     void setRelativeLightCenter(const Vector3& lightCenter) { mRelativeLightCenter = lightCenter; }
170 
171     /**
172      * Sets (and replaces) the current clipping outline
173      *
174      * If the current round rect clip is high priority, the incoming clip is ignored.
175      */
176     void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds,
177             float radius, bool highPriority);
178 
179     /**
180      * Sets (and replaces) the current projection mask
181      */
182     void setProjectionPathMask(const SkPath* path);
183 
184     /**
185      * Indicates whether the current transform has perspective components.
186      */
187     bool hasPerspectiveTransform() const;
188 
189     /**
190      * Dirty flags.
191      */
192     int flags;
193 
194     /**
195      * Previous snapshot.
196      */
197     Snapshot* previous;
198 
199     /**
200      * A pointer to the currently active layer.
201      *
202      * This snapshot does not own the layer, this pointer must not be freed.
203      */
204     Layer* layer;
205 
206     /**
207      * Target FBO used for rendering. Set to 0 when rendering directly
208      * into the framebuffer.
209      */
210     GLuint fbo;
211 
212     /**
213      * Local transformation. Holds the current translation, scale and
214      * rotation values.
215      *
216      * This is a reference to a matrix owned by this snapshot or another
217      *  snapshot. This pointer must not be freed. See ::mTransformRoot.
218      */
219     mat4* transform;
220 
221     /**
222      * Current alpha value. This value is 1 by default, but may be set by a DisplayList which
223      * has translucent rendering in a non-overlapping View. This value will be used by
224      * the renderer to set the alpha in the current color being used for ensuing drawing
225      * operations. The value is inherited by child snapshots because the same value should
226      * be applied to descendants of the current DisplayList (for example, a TextView contains
227      * the base alpha value which should be applied to the child DisplayLists used for drawing
228      * the actual text).
229      */
230     float alpha;
231 
232     /**
233      * Current clipping round rect.
234      *
235      * Points to data not owned by the snapshot, and may only be replaced by subsequent RR clips,
236      * never modified.
237      */
238     const RoundRectClipState* roundRectClipState;
239 
240     /**
241      * Current projection masking path - used exclusively to mask projected, tessellated circles.
242      */
243     const SkPath* projectionPathMask;
244 
245     void dump() const;
246 
247 private:
248     struct ViewportData {
ViewportDataViewportData249         ViewportData() : mWidth(0), mHeight(0) {}
initializeViewportData250         void initialize(int width, int height) {
251             mWidth = width;
252             mHeight = height;
253             mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
254         }
255 
256         /*
257          * Width and height of current viewport.
258          *
259          * The viewport is always defined to be (0, 0, width, height).
260          */
261         int mWidth;
262         int mHeight;
263         /**
264          * Contains the current orthographic, projection matrix.
265          */
266         mat4 mOrthoMatrix;
267     };
268 
269     mat4 mTransformRoot;
270 
271     ClipArea mClipAreaRoot;
272     ClipArea* mClipArea;
273     Rect mLocalClip;
274 
275     ViewportData mViewportData;
276     Vector3 mRelativeLightCenter;
277 
278 }; // class Snapshot
279 
280 }; // namespace uirenderer
281 }; // namespace android
282