Snapshot.cpp revision a3dc55f83ab583e0a66b893c71b849afa046770a
1ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/*
2ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Copyright (C) 2012 The Android Open Source Project
3ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy *
4ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * you may not use this file except in compliance with the License.
6ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * You may obtain a copy of the License at
7ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy *
8ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy *
10ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Unless required by applicable law or agreed to in writing, software
11ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * See the License for the specific language governing permissions and
14ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * limitations under the License.
15ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy */
16ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
17ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy#include "Snapshot.h"
18ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
19ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy#include <SkCanvas.h>
20ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
21ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guynamespace android {
22ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guynamespace uirenderer {
23ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
24ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
25ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Constructors
26ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
27ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
28ada4d53d50dc869b8278573ad640dc44118d3bcfRomain GuySnapshot::Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0),
29db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase        invisible(false), empty(false), alpha(1.0f) {
30ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
31ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    transform = &mTransformRoot;
32ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    clipRect = &mClipRectRoot;
33ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    region = NULL;
34967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    clipRegion = NULL;
35ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
36ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
37ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/**
38ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Copies the specified snapshot/ The specified snapshot is stored as
39ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * the previous snapshot.
40ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy */
41ada4d53d50dc869b8278573ad640dc44118d3bcfRomain GuySnapshot::Snapshot(const sp<Snapshot>& s, int saveFlags):
42ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        flags(0), previous(s), layer(NULL), fbo(s->fbo),
43ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        invisible(s->invisible), empty(false),
44db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase        viewport(s->viewport), height(s->height), alpha(s->alpha) {
45ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
4621c9c8551d9ab36629cabc01f228d3a302e0c673Romain Guy    clipRegion = NULL;
4721c9c8551d9ab36629cabc01f228d3a302e0c673Romain Guy
48ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
49ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        mTransformRoot.load(*s->transform);
50ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        transform = &mTransformRoot;
51ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    } else {
52ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        transform = s->transform;
53ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    }
54ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
55ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    if (saveFlags & SkCanvas::kClip_SaveFlag) {
56ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        mClipRectRoot.set(*s->clipRect);
57ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        clipRect = &mClipRectRoot;
58967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if STENCIL_BUFFER_SIZE
59967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        if (s->clipRegion) {
600baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy            mClipRegionRoot.op(*s->clipRegion, SkRegion::kUnion_Op);
61967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy            clipRegion = &mClipRegionRoot;
62967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
63967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#endif
64ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    } else {
65ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        clipRect = s->clipRect;
66967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if STENCIL_BUFFER_SIZE
67967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        clipRegion = s->clipRegion;
68967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#endif
69ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    }
70ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
71ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    if (s->flags & Snapshot::kFlagFboTarget) {
72ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        flags |= Snapshot::kFlagFboTarget;
73ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        region = s->region;
74ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    } else {
75ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        region = NULL;
76ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    }
77ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
78ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
79ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
80ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Clipping
81ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
82ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
83967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guyvoid Snapshot::ensureClipRegion() {
84967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if STENCIL_BUFFER_SIZE
85967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    if (!clipRegion) {
86967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        clipRegion = &mClipRegionRoot;
870baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        clipRegion->setRect(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
88967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    }
89967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#endif
90967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy}
91967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
92967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guyvoid Snapshot::copyClipRectFromRegion() {
93967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if STENCIL_BUFFER_SIZE
94967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    if (!clipRegion->isEmpty()) {
950baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        const SkIRect& bounds = clipRegion->getBounds();
960baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        clipRect->set(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
97967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
98967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        if (clipRegion->isRect()) {
990baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy            clipRegion->setEmpty();
100967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy            clipRegion = NULL;
101967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
102967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    } else {
103967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        clipRect->setEmpty();
104967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        clipRegion = NULL;
105967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    }
106967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#endif
107967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy}
108967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
1090baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guybool Snapshot::clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op) {
110967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if STENCIL_BUFFER_SIZE
1110baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    SkIRect tmp;
1120baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    tmp.set(left, top, right, bottom);
1130baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    clipRegion->op(tmp, op);
114967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    copyClipRectFromRegion();
115967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    return true;
116967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#else
117967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    return false;
118967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#endif
119967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy}
120967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
121ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
122ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    Rect r(left, top, right, bottom);
123ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    transform->mapRect(r);
124ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    return clipTransformed(r, op);
125ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
126ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
127ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {
128ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    bool clipped = false;
129ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
130ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    switch (op) {
131967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        case SkRegion::kIntersect_Op: {
132967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy            if (CC_UNLIKELY(clipRegion)) {
1330baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy                clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kIntersect_Op);
134967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy            } else {
135967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                clipped = clipRect->intersect(r);
136967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                if (!clipped) {
137967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                    clipRect->setEmpty();
138967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                    clipped = true;
139967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                }
140ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy            }
141ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy            break;
142967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
143967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        case SkRegion::kUnion_Op: {
144967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy            if (CC_UNLIKELY(clipRegion)) {
1450baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy                clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kUnion_Op);
146967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy            } else {
147967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                clipped = clipRect->unionWith(r);
148967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy            }
149ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy            break;
150967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
151967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        case SkRegion::kReplace_Op: {
152967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy            setClip(r.left, r.top, r.right, r.bottom);
153ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy            clipped = true;
154ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy            break;
155967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
1560baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        default: {
1570baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy            ensureClipRegion();
1580baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy            clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, op);
1590baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy            break;
1600baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        }
161ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    }
162ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
163ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    if (clipped) {
164ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        flags |= Snapshot::kFlagClipSet;
165ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    }
166ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
167ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    return clipped;
168ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
169ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
170ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::setClip(float left, float top, float right, float bottom) {
171ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    clipRect->set(left, top, right, bottom);
17221c9c8551d9ab36629cabc01f228d3a302e0c673Romain Guy#if STENCIL_BUFFER_SIZE
173967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    if (clipRegion) {
1740baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        clipRegion->setEmpty();
175967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        clipRegion = NULL;
176967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    }
17721c9c8551d9ab36629cabc01f228d3a302e0c673Romain Guy#endif
178ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    flags |= Snapshot::kFlagClipSet;
179ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
180ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
181a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guybool Snapshot::hasPerspectiveTransform() const {
182a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy    return transform->isPerspective();
183a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy}
184a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy
185ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyconst Rect& Snapshot::getLocalClip() {
186ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    mat4 inverse;
187ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    inverse.loadInverse(*transform);
188ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
189ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    mLocalClip.set(*clipRect);
190ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    inverse.mapRect(mLocalClip);
191ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
192ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    return mLocalClip;
193ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
194ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
195ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::resetClip(float left, float top, float right, float bottom) {
196ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    clipRect = &mClipRectRoot;
197967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    setClip(left, top, right, bottom);
198ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
199ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
200ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
201ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Transforms
202ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
203ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
204ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::resetTransform(float x, float y, float z) {
205ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    transform = &mTransformRoot;
206ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    transform->loadTranslate(x, y, z);
207ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
208ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
209ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
210ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Queries
211ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
212ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
213ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::isIgnored() const {
214ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    return invisible || empty;
215ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
216ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
217ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}; // namespace uirenderer
218ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}; // namespace android
219