Snapshot.h revision 959c91f7f7b4f921d341264f5b4ef54e702a0df0
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 <SkRegion.h> 26 27#include "Layer.h" 28#include "Matrix.h" 29#include "Rect.h" 30 31namespace android { 32namespace uirenderer { 33 34/** 35 * A snapshot holds information about the current state of the rendering 36 * surface. A snapshot is usually created whenever the user calls save() 37 * and discarded when the user calls restore(). Once a snapshot is created, 38 * it can hold information for deferred rendering. 39 * 40 * Each snapshot has a link to a previous snapshot, indicating the previous 41 * state of the renderer. 42 */ 43class Snapshot: public LightRefBase<Snapshot> { 44public: 45 Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0) { } 46 47 /** 48 * Copies the specified snapshot. Only the transform and clip rectangle 49 * are copied. The layer information is set to 0 and the transform is 50 * assumed to be dirty. The specified snapshot is stored as the previous 51 * snapshot. 52 */ 53 Snapshot(const sp<Snapshot>& s): 54 height(s->height), 55 transform(s->transform), 56 clipRect(s->clipRect), 57 flags(0), 58 previous(s), 59 layer(NULL), 60 fbo(s->fbo) { 61 if ((s->flags & Snapshot::kFlagClipSet) && 62 !(s->flags & Snapshot::kFlagDirtyLocalClip)) { 63 localClip.set(s->localClip); 64 } else { 65 flags |= Snapshot::kFlagDirtyLocalClip; 66 } 67 } 68 69 /** 70 * Various flags set on #flags. 71 */ 72 enum Flags { 73 /** 74 * Indicates that the clip region was modified. When this 75 * snapshot is restored so must the clip. 76 */ 77 kFlagClipSet = 0x1, 78 /** 79 * Indicates that this snapshot was created when saving 80 * a new layer. 81 */ 82 kFlagIsLayer = 0x2, 83 /** 84 * Indicates that this snapshot has changed the ortho matrix. 85 */ 86 kFlagDirtyOrtho = 0x4, 87 /** 88 * Indicates that the local clip should be recomputed. 89 */ 90 kFlagDirtyLocalClip = 0x8, 91 }; 92 93 /** 94 * Intersects the current clip with the new clip rectangle. 95 */ 96 bool clip(float left, float top, float right, float bottom, SkRegion::Op op) { 97 bool clipped = false; 98 99 SkRect sr; 100 sr.set(left, top, right, bottom); 101 102 SkMatrix m; 103 transform.copyTo(m); 104 m.mapRect(&sr); 105 106 Rect r(sr.fLeft, sr.fTop, sr.fRight, sr.fBottom); 107 switch (op) { 108 case SkRegion::kDifference_Op: 109 break; 110 case SkRegion::kIntersect_Op: 111 clipped = clipRect.intersect(r); 112 break; 113 case SkRegion::kUnion_Op: 114 clipped = clipRect.unionWith(r); 115 break; 116 case SkRegion::kXOR_Op: 117 break; 118 case SkRegion::kReverseDifference_Op: 119 break; 120 case SkRegion::kReplace_Op: 121 clipRect.set(r); 122 clipped = true; 123 break; 124 } 125 126 if (clipped) { 127 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 128 } 129 130 return clipped; 131 } 132 133 /** 134 * Sets the current clip. 135 */ 136 void setClip(float left, float top, float right, float bottom) { 137 clipRect.set(left, top, right, bottom); 138 flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; 139 } 140 141 const Rect& getLocalClip() { 142 if (flags & Snapshot::kFlagDirtyLocalClip) { 143 mat4 inverse; 144 inverse.loadInverse(transform); 145 146 SkRect sr; 147 sr.set(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); 148 149 SkMatrix m; 150 inverse.copyTo(m); 151 m.mapRect(&sr); 152 153 localClip.set(sr.fLeft, sr.fTop, sr.fRight, sr.fBottom); 154 155 flags &= ~Snapshot::kFlagDirtyLocalClip; 156 } 157 return localClip; 158 } 159 160 /** 161 * Height of the framebuffer the snapshot is rendering into. 162 */ 163 int height; 164 165 /** 166 * Local transformation. Holds the current translation, scale and 167 * rotation values. 168 */ 169 mat4 transform; 170 171 /** 172 * Current clip region. The clip is stored in canvas-space coordinates, 173 * (screen-space coordinates in the regular case.) 174 */ 175 Rect clipRect; 176 177 /** 178 * Dirty flags. 179 */ 180 int flags; 181 182 /** 183 * Previous snapshot. 184 */ 185 sp<Snapshot> previous; 186 187 /** 188 * Only set when the flag kFlagIsLayer is set. 189 */ 190 Layer* layer; 191 GLuint fbo; 192 193 /** 194 * Contains the previous ortho matrix. 195 */ 196 mat4 orthoMatrix; 197 198private: 199 Rect localClip; 200 201}; // class Snapshot 202 203}; // namespace uirenderer 204}; // namespace android 205 206#endif // ANDROID_UI_SNAPSHOT_H 207