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