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