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