Snapshot.h revision eb99356a0548684a501766e6a524529ab93304c8
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_UI_SNAPSHOT_H 18#define ANDROID_UI_SNAPSHOT_H 19 20#include <GLES2/gl2.h> 21#include <GLES2/gl2ext.h> 22 23#include <utils/RefBase.h> 24 25#include <SkCanvas.h> 26#include <SkRegion.h> 27 28#include "Layer.h" 29#include "Matrix.h" 30#include "Rect.h" 31 32namespace android { 33namespace uirenderer { 34 35/** 36 * A snapshot holds information about the current state of the rendering 37 * surface. A snapshot is usually created whenever the user calls save() 38 * and discarded when the user calls restore(). Once a snapshot is created, 39 * it can hold information for deferred rendering. 40 * 41 * Each snapshot has a link to a previous snapshot, indicating the previous 42 * state of the renderer. 43 */ 44class Snapshot: public LightRefBase<Snapshot> { 45public: 46 Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0) { 47 transform = &mTransformRoot; 48 clipRect = &mClipRectRoot; 49 } 50 51 /** 52 * Copies the specified snapshot/ The specified snapshot is stored as 53 * the previous snapshot. 54 */ 55 Snapshot(const sp<Snapshot>& s, int saveFlags): 56 flags(0), previous(s), layer(NULL), 57 fbo(s->fbo), viewport(s->viewport), height(s->height) { 58 if (saveFlags & SkCanvas::kMatrix_SaveFlag) { 59 mTransformRoot.load(*s->transform); 60 transform = &mTransformRoot; 61 } else { 62 transform = s->transform; 63 } 64 65 if (saveFlags & SkCanvas::kClip_SaveFlag) { 66 mClipRectRoot.set(*s->clipRect); 67 clipRect = &mClipRectRoot; 68 } else { 69 clipRect = s->clipRect; 70 } 71 72 if ((s->flags & Snapshot::kFlagClipSet) && 73 !(s->flags & Snapshot::kFlagDirtyLocalClip)) { 74 mLocalClip.set(s->mLocalClip); 75 } else { 76 flags |= Snapshot::kFlagDirtyLocalClip; 77 } 78 } 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 kFlagIsFboLayer = 0x4, 100 /** 101 * Indicates that the local clip should be recomputed. 102 */ 103 kFlagDirtyLocalClip = 0x8, 104 /** 105 * Indicates that this snapshot has changed the ortho matrix. 106 */ 107 kFlagDirtyOrtho = 0x10, 108 }; 109 110 /** 111 * Modifies the current clip with the new clip rectangle and 112 * the specified operation. The specified rectangle is transformed 113 * by this snapshot's trasnformation. 114 */ 115 bool clip(float left, float top, float right, float bottom, 116 SkRegion::Op op = SkRegion::kIntersect_Op) { 117 Rect r(left, top, right, bottom); 118 transform->mapRect(r); 119 return clipTransformed(r, op); 120 } 121 122 /** 123 * Modifies the current clip with the new clip rectangle and 124 * the specified operation. The specified rectangle is considered 125 * already transformed. 126 */ 127 bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op) { 128 bool clipped = false; 129 130 // NOTE: The unimplemented operations require support for regions 131 // Supporting regions would require using a stencil buffer instead 132 // of the scissor. The stencil buffer itself is not too expensive 133 // (memory cost excluded) but on fillrate limited devices, managing 134 // the stencil might have a negative impact on the framerate. 135 switch (op) { 136 case SkRegion::kDifference_Op: 137 break; 138 case SkRegion::kIntersect_Op: 139 clipped = clipRect->intersect(r); 140 break; 141 case SkRegion::kUnion_Op: 142 clipped = clipRect->unionWith(r); 143 break; 144 case SkRegion::kXOR_Op: 145 break; 146 case SkRegion::kReverseDifference_Op: 147 break; 148 case SkRegion::kReplace_Op: 149 clipRect->set(r); 150 clipped = true; 151 break; 152 } 153 154 if (clipped) { 155 clipRect->snapToPixelBoundaries(); 156 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 157 } 158 159 return clipped; 160 } 161 162 /** 163 * Sets the current clip. 164 */ 165 void setClip(float left, float top, float right, float bottom) { 166 clipRect->set(left, top, right, bottom); 167 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 168 } 169 170 const Rect& getLocalClip() { 171 if (flags & Snapshot::kFlagDirtyLocalClip) { 172 mat4 inverse; 173 inverse.loadInverse(*transform); 174 175 mLocalClip.set(*clipRect); 176 inverse.mapRect(mLocalClip); 177 178 flags &= ~Snapshot::kFlagDirtyLocalClip; 179 } 180 return mLocalClip; 181 } 182 183 void resetTransform(float x, float y, float z) { 184 transform = &mTransformRoot; 185 transform->loadTranslate(x, y, z); 186 } 187 188 void resetClip(float left, float top, float right, float bottom) { 189 clipRect = &mClipRectRoot; 190 clipRect->set(left, top, right, bottom); 191 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 192 } 193 194 /** 195 * Dirty flags. 196 */ 197 int flags; 198 199 /** 200 * Previous snapshot. 201 */ 202 sp<Snapshot> previous; 203 204 /** 205 * Only set when the flag kFlagIsLayer is set. 206 */ 207 Layer* layer; 208 209 /** 210 * Only set when the flag kFlagIsFboLayer is set. 211 */ 212 GLuint fbo; 213 214 /** 215 * Current viewport. 216 */ 217 Rect viewport; 218 219 /** 220 * Height of the framebuffer the snapshot is rendering into. 221 */ 222 int height; 223 224 /** 225 * Contains the previous ortho matrix. 226 */ 227 mat4 orthoMatrix; 228 229 /** 230 * Local transformation. Holds the current translation, scale and 231 * rotation values. 232 */ 233 mat4* transform; 234 235 /** 236 * Current clip region. The clip is stored in canvas-space coordinates, 237 * (screen-space coordinates in the regular case.) 238 */ 239 Rect* clipRect; 240 241private: 242 mat4 mTransformRoot; 243 Rect mClipRectRoot; 244 Rect mLocalClip; 245 246}; // class Snapshot 247 248}; // namespace uirenderer 249}; // namespace android 250 251#endif // ANDROID_UI_SNAPSHOT_H 252