Snapshot.h revision 6e49c9f007c879f05b035c40c0ba543c00f9d0d0
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#pragma once 18 19#include <GLES2/gl2.h> 20#include <GLES2/gl2ext.h> 21 22#include <utils/LinearAllocator.h> 23#include <utils/RefBase.h> 24#include <ui/Region.h> 25 26#include <SkClipOp.h> 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) = delete; 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 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 { 76public: 77 78 Snapshot(); 79 Snapshot(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 106 /** 107 * Modifies the current clip with the new clip rectangle and 108 * the specified operation. The specified rectangle is transformed 109 * by this snapshot's trasnformation. 110 */ 111 void clip(const Rect& localClip, SkClipOp op); 112 113 /** 114 * Modifies the current clip with the new clip rectangle and 115 * the specified operation. The specified rectangle is considered 116 * already transformed. 117 */ 118 void clipTransformed(const Rect& r, SkClipOp op = kIntersect_SkClipOp); 119 120 /** 121 * Modifies the current clip with the specified region and operation. 122 * The specified region is considered already transformed. 123 */ 124 void clipRegionTransformed(const SkRegion& region, SkClipOp op); 125 126 /** 127 * Modifies the current clip with the specified path and operation. 128 */ 129 void clipPath(const SkPath& path, SkClipOp 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 */ 145 const Rect& getRenderTargetClip() const { return mClipArea->getClipRect(); } 146 147 /* 148 * Accessor functions so that the clip area can stay private 149 */ 150 bool clipIsEmpty() const { return mClipArea->isEmpty(); } 151 const SkRegion& getClipRegion() const { return mClipArea->getClipRegion(); } 152 bool clipIsSimple() const { return mClipArea->isSimple(); } 153 const ClipArea& getClipArea() const { return *mClipArea; } 154 ClipArea& mutateClipArea() { return *mClipArea; } 155 156 WARN_UNUSED_RESULT const ClipBase* serializeIntersectedClip(LinearAllocator& allocator, 157 const ClipBase* recordedClip, const Matrix4& recordedClipTransform); 158 void applyClip(const ClipBase* clip, const Matrix4& transform); 159 160 /** 161 * Resets the clip to the specified rect. 162 */ 163 void resetClip(float left, float top, float right, float bottom); 164 165 void initializeViewport(int width, int height) { 166 mViewportData.initialize(width, height); 167 mClipAreaRoot.setViewportDimensions(width, height); 168 } 169 170 int getViewportWidth() const { return mViewportData.mWidth; } 171 int getViewportHeight() const { return mViewportData.mHeight; } 172 const Matrix4& getOrthoMatrix() const { return mViewportData.mOrthoMatrix; } 173 174 const Vector3& getRelativeLightCenter() const { return mRelativeLightCenter; } 175 void setRelativeLightCenter(const Vector3& lightCenter) { mRelativeLightCenter = lightCenter; } 176 177 /** 178 * Sets (and replaces) the current clipping outline 179 * 180 * If the current round rect clip is high priority, the incoming clip is ignored. 181 */ 182 void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, 183 float radius, bool highPriority); 184 185 /** 186 * Sets (and replaces) the current projection mask 187 */ 188 void setProjectionPathMask(const SkPath* path); 189 190 /** 191 * Indicates whether the current transform has perspective components. 192 */ 193 bool hasPerspectiveTransform() const; 194 195 /** 196 * Dirty flags. 197 */ 198 int flags; 199 200 /** 201 * Previous snapshot. 202 */ 203 Snapshot* previous; 204 205 /** 206 * A pointer to the currently active layer. 207 * 208 * This snapshot does not own the layer, this pointer must not be freed. 209 */ 210 Layer* layer; 211 212 /** 213 * Target FBO used for rendering. Set to 0 when rendering directly 214 * into the framebuffer. 215 */ 216 GLuint fbo; 217 218 /** 219 * Local transformation. Holds the current translation, scale and 220 * rotation values. 221 * 222 * This is a reference to a matrix owned by this snapshot or another 223 * snapshot. This pointer must not be freed. See ::mTransformRoot. 224 */ 225 mat4* transform; 226 227 /** 228 * Current alpha value. This value is 1 by default, but may be set by a DisplayList which 229 * has translucent rendering in a non-overlapping View. This value will be used by 230 * the renderer to set the alpha in the current color being used for ensuing drawing 231 * operations. The value is inherited by child snapshots because the same value should 232 * be applied to descendants of the current DisplayList (for example, a TextView contains 233 * the base alpha value which should be applied to the child DisplayLists used for drawing 234 * the actual text). 235 */ 236 float alpha; 237 238 /** 239 * Current clipping round rect. 240 * 241 * Points to data not owned by the snapshot, and may only be replaced by subsequent RR clips, 242 * never modified. 243 */ 244 const RoundRectClipState* roundRectClipState; 245 246 /** 247 * Current projection masking path - used exclusively to mask projected, tessellated circles. 248 */ 249 const SkPath* projectionPathMask; 250 251 void dump() const; 252 253private: 254 struct ViewportData { 255 ViewportData() : mWidth(0), mHeight(0) {} 256 void initialize(int width, int height) { 257 mWidth = width; 258 mHeight = height; 259 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 260 } 261 262 /* 263 * Width and height of current viewport. 264 * 265 * The viewport is always defined to be (0, 0, width, height). 266 */ 267 int mWidth; 268 int mHeight; 269 /** 270 * Contains the current orthographic, projection matrix. 271 */ 272 mat4 mOrthoMatrix; 273 }; 274 275 mat4 mTransformRoot; 276 277 ClipArea mClipAreaRoot; 278 ClipArea* mClipArea; 279 Rect mLocalClip; 280 281 ViewportData mViewportData; 282 Vector3 mRelativeLightCenter; 283 284}; // class Snapshot 285 286}; // namespace uirenderer 287}; // namespace android 288