Snapshot.h revision d2a1ff003b9b1212c9ab4b5f679b5b097720a359
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), invisible(false) { 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), fbo(s->fbo), 57 invisible(s->invisible), 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 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 156 } 157 158 return clipped; 159 } 160 161 /** 162 * Sets the current clip. 163 */ 164 void setClip(float left, float top, float right, float bottom) { 165 clipRect->set(left, top, right, bottom); 166 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 167 } 168 169 const Rect& getLocalClip() { 170 if (flags & Snapshot::kFlagDirtyLocalClip) { 171 mat4 inverse; 172 inverse.loadInverse(*transform); 173 174 mLocalClip.set(*clipRect); 175 inverse.mapRect(mLocalClip); 176 177 flags &= ~Snapshot::kFlagDirtyLocalClip; 178 } 179 return mLocalClip; 180 } 181 182 void resetTransform(float x, float y, float z) { 183 transform = &mTransformRoot; 184 transform->loadTranslate(x, y, z); 185 } 186 187 void resetClip(float left, float top, float right, float bottom) { 188 clipRect = &mClipRectRoot; 189 clipRect->set(left, top, right, bottom); 190 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 191 } 192 193 /** 194 * Dirty flags. 195 */ 196 int flags; 197 198 /** 199 * Previous snapshot. 200 */ 201 sp<Snapshot> previous; 202 203 /** 204 * Only set when the flag kFlagIsLayer is set. 205 */ 206 Layer* layer; 207 208 /** 209 * Only set when the flag kFlagIsFboLayer is set. 210 */ 211 GLuint fbo; 212 213 /** 214 * Indicates that this snapshot is invisible and nothing should be drawn 215 * inside it. 216 */ 217 bool invisible; 218 219 /** 220 * Current viewport. 221 */ 222 Rect viewport; 223 224 /** 225 * Height of the framebuffer the snapshot is rendering into. 226 */ 227 int height; 228 229 /** 230 * Contains the previous ortho matrix. 231 */ 232 mat4 orthoMatrix; 233 234 /** 235 * Local transformation. Holds the current translation, scale and 236 * rotation values. 237 */ 238 mat4* transform; 239 240 /** 241 * Current clip region. The clip is stored in canvas-space coordinates, 242 * (screen-space coordinates in the regular case.) 243 */ 244 Rect* clipRect; 245 246private: 247 mat4 mTransformRoot; 248 Rect mClipRectRoot; 249 Rect mLocalClip; 250 251}; // class Snapshot 252 253}; // namespace uirenderer 254}; // namespace android 255 256#endif // ANDROID_UI_SNAPSHOT_H 257