Snapshot.h revision 8aef54fa17f2a3753d9a8f2027629bc480088f69
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(): invisible(false), 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 height(s->height), 57 invisible(s->invisible), 58 flags(0), 59 previous(s), 60 layer(NULL), 61 fbo(s->fbo), 62 viewport(s->viewport) { 63 if (saveFlags & SkCanvas::kMatrix_SaveFlag) { 64 mTransformRoot.load(*s->transform); 65 transform = &mTransformRoot; 66 } else { 67 transform = s->transform; 68 } 69 70 if (saveFlags & SkCanvas::kClip_SaveFlag) { 71 mClipRectRoot.set(*s->clipRect); 72 clipRect = &mClipRectRoot; 73 } else { 74 clipRect = s->clipRect; 75 } 76 77 if ((s->flags & Snapshot::kFlagClipSet) && 78 !(s->flags & Snapshot::kFlagDirtyLocalClip)) { 79 mLocalClip.set(s->mLocalClip); 80 } else { 81 flags |= Snapshot::kFlagDirtyLocalClip; 82 } 83 } 84 85 /** 86 * Various flags set on #flags. 87 */ 88 enum Flags { 89 /** 90 * Indicates that the clip region was modified. When this 91 * snapshot is restored so must the clip. 92 */ 93 kFlagClipSet = 0x1, 94 /** 95 * Indicates that this snapshot was created when saving 96 * a new layer. 97 */ 98 kFlagIsLayer = 0x2, 99 /** 100 * Indicates that this snapshot has changed the ortho matrix. 101 */ 102 kFlagDirtyOrtho = 0x4, 103 /** 104 * Indicates that the local clip should be recomputed. 105 */ 106 kFlagDirtyLocalClip = 0x8, 107 }; 108 109 /** 110 * Intersects the current clip with the new clip rectangle. 111 */ 112 bool clip(float left, float top, float right, float bottom, SkRegion::Op op) { 113 bool clipped = false; 114 115 Rect r(left, top, right, bottom); 116 transform->mapRect(r); 117 118 switch (op) { 119 case SkRegion::kDifference_Op: 120 break; 121 case SkRegion::kIntersect_Op: 122 clipped = clipRect->intersect(r); 123 break; 124 case SkRegion::kUnion_Op: 125 clipped = clipRect->unionWith(r); 126 break; 127 case SkRegion::kXOR_Op: 128 break; 129 case SkRegion::kReverseDifference_Op: 130 break; 131 case SkRegion::kReplace_Op: 132 clipRect->set(r); 133 clipped = true; 134 break; 135 } 136 137 if (clipped) { 138 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 139 } 140 141 return clipped; 142 } 143 144 /** 145 * Sets the current clip. 146 */ 147 void setClip(float left, float top, float right, float bottom) { 148 clipRect->set(left, top, right, bottom); 149 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 150 } 151 152 const Rect& getLocalClip() { 153 if (flags & Snapshot::kFlagDirtyLocalClip) { 154 mat4 inverse; 155 inverse.loadInverse(*transform); 156 157 mLocalClip.set(*clipRect); 158 inverse.mapRect(mLocalClip); 159 160 flags &= ~Snapshot::kFlagDirtyLocalClip; 161 } 162 return mLocalClip; 163 } 164 165 // TODO: Temporary 166 void resetTransform(float x, float y, float z) { 167 transform = &mTransformRoot; 168 transform->loadTranslate(x, y, z); 169 } 170 171 // TODO: Temporary 172 void resetClip(float left, float top, float right, float bottom) { 173 clipRect = &mClipRectRoot; 174 clipRect->set(left, top, right, bottom); 175 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 176 } 177 178 /** 179 * Height of the framebuffer the snapshot is rendering into. 180 */ 181 int height; 182 183 /** 184 * If true, the layer won't be rendered. 185 */ 186 bool invisible; 187 188 /** 189 * Dirty flags. 190 */ 191 int flags; 192 193 /** 194 * Previous snapshot. 195 */ 196 sp<Snapshot> previous; 197 198 /** 199 * Only set when the flag kFlagIsLayer is set. 200 */ 201 Layer* layer; 202 GLuint fbo; 203 204 /** 205 * Current viewport. 206 */ 207 Rect viewport; 208 209 /** 210 * Contains the previous ortho matrix. 211 */ 212 mat4 orthoMatrix; 213 214 /** 215 * Local transformation. Holds the current translation, scale and 216 * rotation values. 217 */ 218 mat4* transform; 219 220 /** 221 * Current clip region. The clip is stored in canvas-space coordinates, 222 * (screen-space coordinates in the regular case.) 223 */ 224 Rect* clipRect; 225 226private: 227 mat4 mTransformRoot; 228 Rect mClipRectRoot; 229 Rect mLocalClip; 230 231}; // class Snapshot 232 233}; // namespace uirenderer 234}; // namespace android 235 236#endif // ANDROID_UI_SNAPSHOT_H 237