Snapshot.h revision 69e5adffb19135d51bde8e458f4907d7265f3e23
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 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 */ 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 const Vector3& getRelativeLightCenter() const { return mRelativeLightCenter; } 165 void setRelativeLightCenter(const Vector3& lightCenter) { mRelativeLightCenter = lightCenter; } 166 167 /** 168 * Sets (and replaces) the current clipping outline 169 */ 170 void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius); 171 172 /** 173 * Indicates whether this snapshot should be ignored. A snapshot 174 * is typicalled ignored if its layer is invisible or empty. 175 */ 176 bool isIgnored() const; 177 178 /** 179 * Indicates whether the current transform has perspective components. 180 */ 181 bool hasPerspectiveTransform() const; 182 183 /** 184 * Dirty flags. 185 */ 186 int flags; 187 188 /** 189 * Previous snapshot. 190 */ 191 sp<Snapshot> previous; 192 193 /** 194 * A pointer to the currently active layer. 195 * 196 * This snapshot does not own the layer, this pointer must not be freed. 197 */ 198 Layer* layer; 199 200 /** 201 * Target FBO used for rendering. Set to 0 when rendering directly 202 * into the framebuffer. 203 */ 204 GLuint fbo; 205 206 /** 207 * Indicates that this snapshot is invisible and nothing should be drawn 208 * inside it. This flag is set only when the layer clips drawing to its 209 * bounds and is passed to subsequent snapshots. 210 */ 211 bool invisible; 212 213 /** 214 * If set to true, the layer will not be composited. This is similar to 215 * invisible but this flag is not passed to subsequent snapshots. 216 */ 217 bool empty; 218 219 /** 220 * Local transformation. Holds the current translation, scale and 221 * rotation values. 222 * 223 * This is a reference to a matrix owned by this snapshot or another 224 * snapshot. This pointer must not be freed. See ::mTransformRoot. 225 */ 226 mat4* transform; 227 228 /** 229 * Current clip rect. The clip is stored in canvas-space coordinates, 230 * (screen-space coordinates in the regular case.) 231 * 232 * This is a reference to a rect owned by this snapshot or another 233 * snapshot. This pointer must not be freed. See ::mClipRectRoot. 234 */ 235 Rect* clipRect; 236 237 /** 238 * Current clip region. The clip is stored in canvas-space coordinates, 239 * (screen-space coordinates in the regular case.) 240 * 241 * This is a reference to a region owned by this snapshot or another 242 * snapshot. This pointer must not be freed. See ::mClipRegionRoot. 243 */ 244 SkRegion* clipRegion; 245 246 /** 247 * The ancestor layer's dirty region. 248 * 249 * This is a reference to a region owned by a layer. This pointer must 250 * not be freed. 251 */ 252 Region* region; 253 254 /** 255 * Current alpha value. This value is 1 by default, but may be set by a DisplayList which 256 * has translucent rendering in a non-overlapping View. This value will be used by 257 * the renderer to set the alpha in the current color being used for ensuing drawing 258 * operations. The value is inherited by child snapshots because the same value should 259 * be applied to descendents of the current DisplayList (for example, a TextView contains 260 * the base alpha value which should be applied to the child DisplayLists used for drawing 261 * the actual text). 262 */ 263 float alpha; 264 265 /** 266 * Current clipping round rect. 267 * 268 * Points to data not owned by the snapshot, and may only be replaced by subsequent RR clips, 269 * never modified. 270 */ 271 const RoundRectClipState* roundRectClipState; 272 273 void dump() const; 274 275private: 276 struct ViewportData { 277 ViewportData() : mWidth(0), mHeight(0) {} 278 void initialize(int width, int height) { 279 mWidth = width; 280 mHeight = height; 281 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 282 } 283 284 /* 285 * Width and height of current viewport. 286 * 287 * The viewport is always defined to be (0, 0, width, height). 288 */ 289 int mWidth; 290 int mHeight; 291 /** 292 * Contains the current orthographic, projection matrix. 293 */ 294 mat4 mOrthoMatrix; 295 }; 296 297 void ensureClipRegion(); 298 void copyClipRectFromRegion(); 299 300 bool clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op); 301 302 mat4 mTransformRoot; 303 Rect mClipRectRoot; 304 Rect mLocalClip; // don't use directly, call getLocalClip() which initializes this 305 306 SkRegion mClipRegionRoot; 307 ViewportData mViewportData; 308 Vector3 mRelativeLightCenter; 309 310}; // class Snapshot 311 312}; // namespace uirenderer 313}; // namespace android 314 315#endif // ANDROID_HWUI_SNAPSHOT_H 316