Snapshot.h revision 487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8
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(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 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 */ 75class Snapshot: public LightRefBase<Snapshot> { 76public: 77 78 Snapshot(); 79 Snapshot(const sp<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 * Indicates that this snapshot or an ancestor snapshot is 106 * an FBO layer. 107 */ 108 kFlagFboTarget = 0x8, 109 }; 110 111 /** 112 * Modifies the current clip with the new clip rectangle and 113 * the specified operation. The specified rectangle is transformed 114 * by this snapshot's trasnformation. 115 */ 116 bool clip(float left, float top, float right, float bottom, 117 SkRegion::Op op = SkRegion::kIntersect_Op); 118 119 /** 120 * Modifies the current clip with the new clip rectangle and 121 * the specified operation. The specified rectangle is considered 122 * already transformed. 123 */ 124 bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op); 125 126 /** 127 * Modifies the current clip with the specified region and operation. 128 * The specified region is considered already transformed. 129 */ 130 bool clipRegionTransformed(const SkRegion& region, SkRegion::Op op); 131 132 /** 133 * Modifies the current clip with the specified path and operation. 134 */ 135 bool clipPath(const SkPath& path, SkRegion::Op op); 136 137 /** 138 * Sets the current clip. 139 */ 140 void setClip(float left, float top, float right, float bottom); 141 142 /** 143 * Returns the current clip in local coordinates. The clip rect is 144 * transformed by the inverse transform matrix. 145 */ 146 ANDROID_API const Rect& getLocalClip(); 147 148 /** 149 * Returns the current clip in render target coordinates. 150 */ 151 const Rect& getRenderTargetClip() { return mClipArea->getClipRect(); } 152 153 /* 154 * Accessor functions so that the clip area can stay private 155 */ 156 bool clipIsEmpty() const { return mClipArea->isEmpty(); } 157 const Rect& getClipRect() const { return mClipArea->getClipRect(); } 158 const SkRegion& getClipRegion() const { return mClipArea->getClipRegion(); } 159 bool clipIsSimple() const { return mClipArea->isSimple(); } 160 const ClipArea& getClipArea() const { return *mClipArea; } 161 162 /** 163 * Resets the clip to the specified rect. 164 */ 165 void resetClip(float left, float top, float right, float bottom); 166 167 /** 168 * Resets the current transform to a pure 3D translation. 169 */ 170 void resetTransform(float x, float y, float z); 171 172 void initializeViewport(int width, int height) { 173 mViewportData.initialize(width, height); 174 mClipAreaRoot.setViewportDimensions(width, height); 175 } 176 177 int getViewportWidth() const { return mViewportData.mWidth; } 178 int getViewportHeight() const { return mViewportData.mHeight; } 179 const Matrix4& getOrthoMatrix() const { return mViewportData.mOrthoMatrix; } 180 181 const Vector3& getRelativeLightCenter() const { return mRelativeLightCenter; } 182 void setRelativeLightCenter(const Vector3& lightCenter) { mRelativeLightCenter = lightCenter; } 183 184 /** 185 * Sets (and replaces) the current clipping outline 186 * 187 * If the current round rect clip is high priority, the incoming clip is ignored. 188 */ 189 void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, 190 float radius, bool highPriority); 191 192 /** 193 * Indicates whether this snapshot should be ignored. A snapshot 194 * is typically ignored if its layer is invisible or empty. 195 */ 196 bool isIgnored() const; 197 198 /** 199 * Indicates whether the current transform has perspective components. 200 */ 201 bool hasPerspectiveTransform() const; 202 203 /** 204 * Dirty flags. 205 */ 206 int flags; 207 208 /** 209 * Previous snapshot. 210 */ 211 sp<Snapshot> previous; 212 213 /** 214 * A pointer to the currently active layer. 215 * 216 * This snapshot does not own the layer, this pointer must not be freed. 217 */ 218 Layer* layer; 219 220 /** 221 * Target FBO used for rendering. Set to 0 when rendering directly 222 * into the framebuffer. 223 */ 224 GLuint fbo; 225 226 /** 227 * Indicates that this snapshot is invisible and nothing should be drawn 228 * inside it. This flag is set only when the layer clips drawing to its 229 * bounds and is passed to subsequent snapshots. 230 */ 231 bool invisible; 232 233 /** 234 * If set to true, the layer will not be composited. This is similar to 235 * invisible but this flag is not passed to subsequent snapshots. 236 */ 237 bool empty; 238 239 /** 240 * Local transformation. Holds the current translation, scale and 241 * rotation values. 242 * 243 * This is a reference to a matrix owned by this snapshot or another 244 * snapshot. This pointer must not be freed. See ::mTransformRoot. 245 */ 246 mat4* transform; 247 248 /** 249 * The ancestor layer's dirty region. 250 * 251 * This is a reference to a region owned by a layer. This pointer must 252 * not be freed. 253 */ 254 Region* region; 255 256 /** 257 * Current alpha value. This value is 1 by default, but may be set by a DisplayList which 258 * has translucent rendering in a non-overlapping View. This value will be used by 259 * the renderer to set the alpha in the current color being used for ensuing drawing 260 * operations. The value is inherited by child snapshots because the same value should 261 * be applied to descendants of the current DisplayList (for example, a TextView contains 262 * the base alpha value which should be applied to the child DisplayLists used for drawing 263 * the actual text). 264 */ 265 float alpha; 266 267 /** 268 * Current clipping round rect. 269 * 270 * Points to data not owned by the snapshot, and may only be replaced by subsequent RR clips, 271 * never modified. 272 */ 273 const RoundRectClipState* roundRectClipState; 274 275 void dump() const; 276 277private: 278 struct ViewportData { 279 ViewportData() : mWidth(0), mHeight(0) {} 280 void initialize(int width, int height) { 281 mWidth = width; 282 mHeight = height; 283 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 284 } 285 286 /* 287 * Width and height of current viewport. 288 * 289 * The viewport is always defined to be (0, 0, width, height). 290 */ 291 int mWidth; 292 int mHeight; 293 /** 294 * Contains the current orthographic, projection matrix. 295 */ 296 mat4 mOrthoMatrix; 297 }; 298 299 mat4 mTransformRoot; 300 301 ClipArea mClipAreaRoot; 302 ClipArea* mClipArea; 303 Rect mLocalClip; 304 305 ViewportData mViewportData; 306 Vector3 mRelativeLightCenter; 307 308}; // class Snapshot 309 310}; // namespace uirenderer 311}; // namespace android 312 313#endif // ANDROID_HWUI_SNAPSHOT_H 314