Snapshot.h revision 5e00c7ce063116c11315639f0035aca8ad73e8cc
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 <SkRegion.h> 27 28#include "ClipArea.h" 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) = delete; 47 static void* operator new(size_t size, LinearAllocator& allocator) { 48 return allocator.alloc<RoundRectClipState>(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 bool highPriority; 59 Matrix4 matrix; 60 Rect dangerRects[4]; 61 Rect innerRect; 62 float radius; 63}; 64 65/** 66 * A snapshot holds information about the current state of the rendering 67 * surface. A snapshot is usually created whenever the user calls save() 68 * and discarded when the user calls restore(). Once a snapshot is created, 69 * it can hold information for deferred rendering. 70 * 71 * Each snapshot has a link to a previous snapshot, indicating the previous 72 * state of the renderer. 73 */ 74class Snapshot { 75public: 76 77 Snapshot(); 78 Snapshot(Snapshot* s, int saveFlags); 79 80 /** 81 * Various flags set on ::flags. 82 */ 83 enum Flags { 84 /** 85 * Indicates that the clip region was modified. When this 86 * snapshot is restored so must the clip. 87 */ 88 kFlagClipSet = 0x1, 89 /** 90 * Indicates that this snapshot was created when saving 91 * a new layer. 92 */ 93 kFlagIsLayer = 0x2, 94 /** 95 * Indicates that this snapshot is a special type of layer 96 * backed by an FBO. This flag only makes sense when the 97 * flag kFlagIsLayer is also set. 98 * 99 * Viewport has been modified to fit the new Fbo, and must be 100 * restored when this snapshot is restored. 101 */ 102 kFlagIsFboLayer = 0x4, 103 }; 104 105 /** 106 * Modifies the current clip with the new clip rectangle and 107 * the specified operation. The specified rectangle is transformed 108 * by this snapshot's trasnformation. 109 */ 110 void clip(const Rect& localClip, SkRegion::Op op); 111 112 /** 113 * Modifies the current clip with the new clip rectangle and 114 * the specified operation. The specified rectangle is considered 115 * already transformed. 116 */ 117 void clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op); 118 119 /** 120 * Modifies the current clip with the specified region and operation. 121 * The specified region is considered already transformed. 122 */ 123 void clipRegionTransformed(const SkRegion& region, SkRegion::Op op); 124 125 /** 126 * Modifies the current clip with the specified path and operation. 127 */ 128 void clipPath(const SkPath& path, 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() const { return mClipArea->getClipRect(); } 145 146 /* 147 * Accessor functions so that the clip area can stay private 148 */ 149 bool clipIsEmpty() const { return mClipArea->isEmpty(); } 150 const SkRegion& getClipRegion() const { return mClipArea->getClipRegion(); } 151 bool clipIsSimple() const { return mClipArea->isSimple(); } 152 const ClipArea& getClipArea() const { return *mClipArea; } 153 ClipArea& mutateClipArea() { return *mClipArea; } 154 155 WARN_UNUSED_RESULT const ClipBase* serializeIntersectedClip(LinearAllocator& allocator, 156 const ClipBase* recordedClip, const Matrix4& recordedClipTransform); 157 void applyClip(const ClipBase* clip, const Matrix4& transform); 158 159 /** 160 * Resets the clip to the specified rect. 161 */ 162 void resetClip(float left, float top, float right, float bottom); 163 164 void initializeViewport(int width, int height) { 165 mViewportData.initialize(width, height); 166 mClipAreaRoot.setViewportDimensions(width, height); 167 } 168 169 int getViewportWidth() const { return mViewportData.mWidth; } 170 int getViewportHeight() const { return mViewportData.mHeight; } 171 const Matrix4& getOrthoMatrix() const { return mViewportData.mOrthoMatrix; } 172 173 const Vector3& getRelativeLightCenter() const { return mRelativeLightCenter; } 174 void setRelativeLightCenter(const Vector3& lightCenter) { mRelativeLightCenter = lightCenter; } 175 176 /** 177 * Sets (and replaces) the current clipping outline 178 * 179 * If the current round rect clip is high priority, the incoming clip is ignored. 180 */ 181 void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, 182 float radius, bool highPriority); 183 184 /** 185 * Sets (and replaces) the current projection mask 186 */ 187 void setProjectionPathMask(const SkPath* path); 188 189 /** 190 * Indicates whether the current transform has perspective components. 191 */ 192 bool hasPerspectiveTransform() const; 193 194 /** 195 * Dirty flags. 196 */ 197 int flags; 198 199 /** 200 * Previous snapshot. 201 */ 202 Snapshot* previous; 203 204 /** 205 * A pointer to the currently active layer. 206 * 207 * This snapshot does not own the layer, this pointer must not be freed. 208 */ 209 Layer* layer; 210 211 /** 212 * Target FBO used for rendering. Set to 0 when rendering directly 213 * into the framebuffer. 214 */ 215 GLuint fbo; 216 217 /** 218 * Local transformation. Holds the current translation, scale and 219 * rotation values. 220 * 221 * This is a reference to a matrix owned by this snapshot or another 222 * snapshot. This pointer must not be freed. See ::mTransformRoot. 223 */ 224 mat4* transform; 225 226 /** 227 * Current alpha value. This value is 1 by default, but may be set by a DisplayList which 228 * has translucent rendering in a non-overlapping View. This value will be used by 229 * the renderer to set the alpha in the current color being used for ensuing drawing 230 * operations. The value is inherited by child snapshots because the same value should 231 * be applied to descendants of the current DisplayList (for example, a TextView contains 232 * the base alpha value which should be applied to the child DisplayLists used for drawing 233 * the actual text). 234 */ 235 float alpha; 236 237 /** 238 * Current clipping round rect. 239 * 240 * Points to data not owned by the snapshot, and may only be replaced by subsequent RR clips, 241 * never modified. 242 */ 243 const RoundRectClipState* roundRectClipState; 244 245 /** 246 * Current projection masking path - used exclusively to mask projected, tessellated circles. 247 */ 248 const SkPath* projectionPathMask; 249 250 void dump() const; 251 252private: 253 struct ViewportData { 254 ViewportData() : mWidth(0), mHeight(0) {} 255 void initialize(int width, int height) { 256 mWidth = width; 257 mHeight = height; 258 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 259 } 260 261 /* 262 * Width and height of current viewport. 263 * 264 * The viewport is always defined to be (0, 0, width, height). 265 */ 266 int mWidth; 267 int mHeight; 268 /** 269 * Contains the current orthographic, projection matrix. 270 */ 271 mat4 mOrthoMatrix; 272 }; 273 274 mat4 mTransformRoot; 275 276 ClipArea mClipAreaRoot; 277 ClipArea* mClipArea; 278 Rect mLocalClip; 279 280 ViewportData mViewportData; 281 Vector3 mRelativeLightCenter; 282 283}; // class Snapshot 284 285}; // namespace uirenderer 286}; // namespace android 287