Snapshot.h revision 7df9ff2a08fd4bbd9b2e734a357cffcf64675df9
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 "ClipArea.h" 30#include "Layer.h" 31#include "Matrix.h" 32#include "Outline.h" 33#include "Rect.h" 34#include "utils/Macros.h" 35 36namespace android { 37namespace 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 */ 45class RoundRectClipState { 46public: 47 /** static void* operator new(size_t size); PURPOSELY OMITTED, allocator only **/ 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]) 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 66class ProjectionPathMask { 67public: 68 /** static void* operator new(size_t size); PURPOSELY OMITTED, allocator only **/ 69 static void* operator new(size_t size, LinearAllocator& allocator) { 70 return allocator.alloc<ProjectionPathMask>(size); 71 } 72 73 const SkPath* projectionMask; 74 Matrix4 projectionMaskTransform; 75}; 76 77/** 78 * A snapshot holds information about the current state of the rendering 79 * surface. A snapshot is usually created whenever the user calls save() 80 * and discarded when the user calls restore(). Once a snapshot is created, 81 * it can hold information for deferred rendering. 82 * 83 * Each snapshot has a link to a previous snapshot, indicating the previous 84 * state of the renderer. 85 */ 86class Snapshot { 87public: 88 89 Snapshot(); 90 Snapshot(Snapshot* s, int saveFlags); 91 92 /** 93 * Various flags set on ::flags. 94 */ 95 enum Flags { 96 /** 97 * Indicates that the clip region was modified. When this 98 * snapshot is restored so must the clip. 99 */ 100 kFlagClipSet = 0x1, 101 /** 102 * Indicates that this snapshot was created when saving 103 * a new layer. 104 */ 105 kFlagIsLayer = 0x2, 106 /** 107 * Indicates that this snapshot is a special type of layer 108 * backed by an FBO. This flag only makes sense when the 109 * flag kFlagIsLayer is also set. 110 * 111 * Viewport has been modified to fit the new Fbo, and must be 112 * restored when this snapshot is restored. 113 */ 114 kFlagIsFboLayer = 0x4, 115 /** 116 * Indicates that this snapshot or an ancestor snapshot is 117 * an FBO layer. 118 */ 119 kFlagFboTarget = 0x8, // TODO: remove for HWUI_NEW_OPS 120 }; 121 122 /** 123 * Modifies the current clip with the new clip rectangle and 124 * the specified operation. The specified rectangle is transformed 125 * by this snapshot's trasnformation. 126 */ 127 void clip(const Rect& localClip, SkRegion::Op op); 128 129 /** 130 * Modifies the current clip with the new clip rectangle and 131 * the specified operation. The specified rectangle is considered 132 * already transformed. 133 */ 134 void clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op); 135 136 /** 137 * Modifies the current clip with the specified region and operation. 138 * The specified region is considered already transformed. 139 */ 140 void clipRegionTransformed(const SkRegion& region, SkRegion::Op op); 141 142 /** 143 * Modifies the current clip with the specified path and operation. 144 */ 145 void clipPath(const SkPath& path, SkRegion::Op op); 146 147 /** 148 * Sets the current clip. 149 */ 150 void setClip(float left, float top, float right, float bottom); 151 152 /** 153 * Returns the current clip in local coordinates. The clip rect is 154 * transformed by the inverse transform matrix. 155 */ 156 ANDROID_API const Rect& getLocalClip(); 157 158 /** 159 * Returns the current clip in render target coordinates. 160 */ 161 const Rect& getRenderTargetClip() const { return mClipArea->getClipRect(); } 162 163 /* 164 * Accessor functions so that the clip area can stay private 165 */ 166 bool clipIsEmpty() const { return mClipArea->isEmpty(); } 167 const SkRegion& getClipRegion() const { return mClipArea->getClipRegion(); } 168 bool clipIsSimple() const { return mClipArea->isSimple(); } 169 const ClipArea& getClipArea() const { return *mClipArea; } 170 ClipArea& mutateClipArea() { return *mClipArea; } 171 172 /** 173 * Resets the clip to the specified rect. 174 */ 175 void resetClip(float left, float top, float right, float bottom); 176 177 /** 178 * Resets the current transform to a pure 3D translation. 179 */ 180 void resetTransform(float x, float y, float z); 181 182 void initializeViewport(int width, int height) { 183 mViewportData.initialize(width, height); 184 mClipAreaRoot.setViewportDimensions(width, height); 185 } 186 187 int getViewportWidth() const { return mViewportData.mWidth; } 188 int getViewportHeight() const { return mViewportData.mHeight; } 189 const Matrix4& getOrthoMatrix() const { return mViewportData.mOrthoMatrix; } 190 191 const Vector3& getRelativeLightCenter() const { return mRelativeLightCenter; } 192 void setRelativeLightCenter(const Vector3& lightCenter) { mRelativeLightCenter = lightCenter; } 193 194 /** 195 * Sets (and replaces) the current clipping outline 196 * 197 * If the current round rect clip is high priority, the incoming clip is ignored. 198 */ 199 void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, 200 float radius, bool highPriority); 201 202 /** 203 * Sets (and replaces) the current projection mask 204 */ 205 void setProjectionPathMask(LinearAllocator& allocator, const SkPath* path); 206 207 /** 208 * Indicates whether this snapshot should be ignored. A snapshot 209 * is typically ignored if its layer is invisible or empty. 210 */ 211 bool isIgnored() const; 212 213 /** 214 * Indicates whether the current transform has perspective components. 215 */ 216 bool hasPerspectiveTransform() const; 217 218 /** 219 * Fills outTransform with the current, total transform to screen space, 220 * across layer boundaries. 221 */ 222 void buildScreenSpaceTransform(Matrix4* outTransform) const; 223 224 /** 225 * Dirty flags. 226 */ 227 int flags; 228 229 /** 230 * Previous snapshot. 231 */ 232 Snapshot* previous; 233 234 /** 235 * A pointer to the currently active layer. 236 * 237 * This snapshot does not own the layer, this pointer must not be freed. 238 */ 239 Layer* layer; 240 241 /** 242 * Target FBO used for rendering. Set to 0 when rendering directly 243 * into the framebuffer. 244 */ 245 GLuint fbo; 246 247 /** 248 * Indicates that this snapshot is invisible and nothing should be drawn 249 * inside it. This flag is set only when the layer clips drawing to its 250 * bounds and is passed to subsequent snapshots. 251 */ 252 bool invisible; 253 254 /** 255 * If set to true, the layer will not be composited. This is similar to 256 * invisible but this flag is not passed to subsequent snapshots. 257 */ 258 bool empty; 259 260 /** 261 * Local transformation. Holds the current translation, scale and 262 * rotation values. 263 * 264 * This is a reference to a matrix owned by this snapshot or another 265 * snapshot. This pointer must not be freed. See ::mTransformRoot. 266 */ 267 mat4* transform; 268 269 /** 270 * The ancestor layer's dirty region. 271 * 272 * This is a reference to a region owned by a layer. This pointer must 273 * not be freed. 274 */ 275 Region* region; 276 277 /** 278 * Current alpha value. This value is 1 by default, but may be set by a DisplayList which 279 * has translucent rendering in a non-overlapping View. This value will be used by 280 * the renderer to set the alpha in the current color being used for ensuing drawing 281 * operations. The value is inherited by child snapshots because the same value should 282 * be applied to descendants of the current DisplayList (for example, a TextView contains 283 * the base alpha value which should be applied to the child DisplayLists used for drawing 284 * the actual text). 285 */ 286 float alpha; 287 288 /** 289 * Current clipping round rect. 290 * 291 * Points to data not owned by the snapshot, and may only be replaced by subsequent RR clips, 292 * never modified. 293 */ 294 const RoundRectClipState* roundRectClipState; 295 296 /** 297 * Current projection masking path - used exclusively to mask tessellated circles. 298 */ 299 const ProjectionPathMask* projectionPathMask; 300 301 void dump() const; 302 303private: 304 struct ViewportData { 305 ViewportData() : mWidth(0), mHeight(0) {} 306 void initialize(int width, int height) { 307 mWidth = width; 308 mHeight = height; 309 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 310 } 311 312 /* 313 * Width and height of current viewport. 314 * 315 * The viewport is always defined to be (0, 0, width, height). 316 */ 317 int mWidth; 318 int mHeight; 319 /** 320 * Contains the current orthographic, projection matrix. 321 */ 322 mat4 mOrthoMatrix; 323 }; 324 325 mat4 mTransformRoot; 326 327 ClipArea mClipAreaRoot; 328 ClipArea* mClipArea; 329 Rect mLocalClip; 330 331 ViewportData mViewportData; 332 Vector3 mRelativeLightCenter; 333 334}; // class Snapshot 335 336}; // namespace uirenderer 337}; // namespace android 338 339#endif // ANDROID_HWUI_SNAPSHOT_H 340