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