blob: fbc84554dcdfcfa1320c3456993771c512ad1af5 [file] [log] [blame]
Romain Guyada4d532012-02-02 17:31:16 -08001/*
2 * Copyright (C) 2012 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#include "Snapshot.h"
18
19#include <SkCanvas.h>
20
21namespace android {
22namespace uirenderer {
23
24///////////////////////////////////////////////////////////////////////////////
25// Constructors
26///////////////////////////////////////////////////////////////////////////////
27
28Snapshot::Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0),
Chet Haasedb8c9a62012-03-21 18:54:18 -070029 invisible(false), empty(false), alpha(1.0f) {
Romain Guyada4d532012-02-02 17:31:16 -080030
31 transform = &mTransformRoot;
32 clipRect = &mClipRectRoot;
33 region = NULL;
Romain Guy967e2bf2012-02-07 17:04:34 -080034 clipRegion = NULL;
Romain Guyada4d532012-02-02 17:31:16 -080035}
36
37/**
38 * Copies the specified snapshot/ The specified snapshot is stored as
39 * the previous snapshot.
40 */
41Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags):
42 flags(0), previous(s), layer(NULL), fbo(s->fbo),
43 invisible(s->invisible), empty(false),
Chet Haasedb8c9a62012-03-21 18:54:18 -070044 viewport(s->viewport), height(s->height), alpha(s->alpha) {
Romain Guyada4d532012-02-02 17:31:16 -080045
Romain Guy21c9c852012-02-07 18:22:07 -080046 clipRegion = NULL;
47
Romain Guyada4d532012-02-02 17:31:16 -080048 if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
49 mTransformRoot.load(*s->transform);
50 transform = &mTransformRoot;
51 } else {
52 transform = s->transform;
53 }
54
55 if (saveFlags & SkCanvas::kClip_SaveFlag) {
56 mClipRectRoot.set(*s->clipRect);
57 clipRect = &mClipRectRoot;
Romain Guy967e2bf2012-02-07 17:04:34 -080058#if STENCIL_BUFFER_SIZE
59 if (s->clipRegion) {
Romain Guy0baaac52012-08-31 20:31:01 -070060 mClipRegionRoot.op(*s->clipRegion, SkRegion::kUnion_Op);
Romain Guy967e2bf2012-02-07 17:04:34 -080061 clipRegion = &mClipRegionRoot;
Romain Guy967e2bf2012-02-07 17:04:34 -080062 }
Romain Guy967e2bf2012-02-07 17:04:34 -080063#endif
Romain Guyada4d532012-02-02 17:31:16 -080064 } else {
65 clipRect = s->clipRect;
Romain Guy967e2bf2012-02-07 17:04:34 -080066#if STENCIL_BUFFER_SIZE
67 clipRegion = s->clipRegion;
68#endif
Romain Guyada4d532012-02-02 17:31:16 -080069 }
70
71 if (s->flags & Snapshot::kFlagFboTarget) {
72 flags |= Snapshot::kFlagFboTarget;
73 region = s->region;
74 } else {
75 region = NULL;
76 }
77}
78
79///////////////////////////////////////////////////////////////////////////////
80// Clipping
81///////////////////////////////////////////////////////////////////////////////
82
Romain Guy967e2bf2012-02-07 17:04:34 -080083void Snapshot::ensureClipRegion() {
84#if STENCIL_BUFFER_SIZE
85 if (!clipRegion) {
86 clipRegion = &mClipRegionRoot;
Romain Guy0baaac52012-08-31 20:31:01 -070087 clipRegion->setRect(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
Romain Guy967e2bf2012-02-07 17:04:34 -080088 }
89#endif
90}
91
92void Snapshot::copyClipRectFromRegion() {
93#if STENCIL_BUFFER_SIZE
94 if (!clipRegion->isEmpty()) {
Romain Guy0baaac52012-08-31 20:31:01 -070095 const SkIRect& bounds = clipRegion->getBounds();
96 clipRect->set(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
Romain Guy967e2bf2012-02-07 17:04:34 -080097
98 if (clipRegion->isRect()) {
Romain Guy0baaac52012-08-31 20:31:01 -070099 clipRegion->setEmpty();
Romain Guy967e2bf2012-02-07 17:04:34 -0800100 clipRegion = NULL;
101 }
102 } else {
103 clipRect->setEmpty();
104 clipRegion = NULL;
105 }
106#endif
107}
108
Romain Guy0baaac52012-08-31 20:31:01 -0700109bool Snapshot::clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op) {
Romain Guy967e2bf2012-02-07 17:04:34 -0800110#if STENCIL_BUFFER_SIZE
Romain Guy0baaac52012-08-31 20:31:01 -0700111 SkIRect tmp;
112 tmp.set(left, top, right, bottom);
113 clipRegion->op(tmp, op);
Romain Guy967e2bf2012-02-07 17:04:34 -0800114 copyClipRectFromRegion();
115 return true;
116#else
117 return false;
118#endif
119}
120
Romain Guyada4d532012-02-02 17:31:16 -0800121bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
122 Rect r(left, top, right, bottom);
123 transform->mapRect(r);
124 return clipTransformed(r, op);
125}
126
127bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {
128 bool clipped = false;
129
Romain Guyada4d532012-02-02 17:31:16 -0800130 switch (op) {
Romain Guy967e2bf2012-02-07 17:04:34 -0800131 case SkRegion::kIntersect_Op: {
132 if (CC_UNLIKELY(clipRegion)) {
Romain Guy0baaac52012-08-31 20:31:01 -0700133 clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kIntersect_Op);
Romain Guy967e2bf2012-02-07 17:04:34 -0800134 } else {
135 clipped = clipRect->intersect(r);
136 if (!clipped) {
137 clipRect->setEmpty();
138 clipped = true;
139 }
Romain Guyada4d532012-02-02 17:31:16 -0800140 }
141 break;
Romain Guy967e2bf2012-02-07 17:04:34 -0800142 }
143 case SkRegion::kUnion_Op: {
144 if (CC_UNLIKELY(clipRegion)) {
Romain Guy0baaac52012-08-31 20:31:01 -0700145 clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kUnion_Op);
Romain Guy967e2bf2012-02-07 17:04:34 -0800146 } else {
147 clipped = clipRect->unionWith(r);
148 }
Romain Guyada4d532012-02-02 17:31:16 -0800149 break;
Romain Guy967e2bf2012-02-07 17:04:34 -0800150 }
Romain Guy967e2bf2012-02-07 17:04:34 -0800151 case SkRegion::kReplace_Op: {
152 setClip(r.left, r.top, r.right, r.bottom);
Romain Guyada4d532012-02-02 17:31:16 -0800153 clipped = true;
154 break;
Romain Guy967e2bf2012-02-07 17:04:34 -0800155 }
Romain Guy0baaac52012-08-31 20:31:01 -0700156 default: {
157 ensureClipRegion();
158 clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, op);
159 break;
160 }
Romain Guyada4d532012-02-02 17:31:16 -0800161 }
162
163 if (clipped) {
164 flags |= Snapshot::kFlagClipSet;
165 }
166
167 return clipped;
168}
169
170void Snapshot::setClip(float left, float top, float right, float bottom) {
171 clipRect->set(left, top, right, bottom);
Romain Guy21c9c852012-02-07 18:22:07 -0800172#if STENCIL_BUFFER_SIZE
Romain Guy967e2bf2012-02-07 17:04:34 -0800173 if (clipRegion) {
Romain Guy0baaac52012-08-31 20:31:01 -0700174 clipRegion->setEmpty();
Romain Guy967e2bf2012-02-07 17:04:34 -0800175 clipRegion = NULL;
176 }
Romain Guy21c9c852012-02-07 18:22:07 -0800177#endif
Romain Guyada4d532012-02-02 17:31:16 -0800178 flags |= Snapshot::kFlagClipSet;
179}
180
Romain Guya3dc55f2012-09-28 13:55:44 -0700181bool Snapshot::hasPerspectiveTransform() const {
182 return transform->isPerspective();
183}
184
Romain Guyada4d532012-02-02 17:31:16 -0800185const Rect& Snapshot::getLocalClip() {
186 mat4 inverse;
187 inverse.loadInverse(*transform);
188
189 mLocalClip.set(*clipRect);
190 inverse.mapRect(mLocalClip);
191
192 return mLocalClip;
193}
194
195void Snapshot::resetClip(float left, float top, float right, float bottom) {
196 clipRect = &mClipRectRoot;
Romain Guy967e2bf2012-02-07 17:04:34 -0800197 setClip(left, top, right, bottom);
Romain Guyada4d532012-02-02 17:31:16 -0800198}
199
200///////////////////////////////////////////////////////////////////////////////
201// Transforms
202///////////////////////////////////////////////////////////////////////////////
203
204void Snapshot::resetTransform(float x, float y, float z) {
205 transform = &mTransformRoot;
206 transform->loadTranslate(x, y, z);
207}
208
209///////////////////////////////////////////////////////////////////////////////
210// Queries
211///////////////////////////////////////////////////////////////////////////////
212
213bool Snapshot::isIgnored() const {
214 return invisible || empty;
215}
216
217}; // namespace uirenderer
218}; // namespace android