Snapshot.cpp revision e83cbd451868a734bfac07ccd680d5617080b579
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
175f803623559aab395a29d575c37c4e39c23a4b4eChris Craik#define LOG_TAG "OpenGLRenderer"
185f803623559aab395a29d575c37c4e39c23a4b4eChris Craik
19ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy#include "Snapshot.h"
20ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
21ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy#include <SkCanvas.h>
22ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
23ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guynamespace android {
24ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guynamespace uirenderer {
25ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
26ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
27ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Constructors
28ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
29ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
30e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris CraikSnapshot::Snapshot()
31e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        : flags(0)
32e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        , previous(NULL)
33e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        , layer(NULL)
34e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        , fbo(0)
35e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        , invisible(false)
36e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        , empty(false)
37deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        , alpha(1.0f)
38deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        , roundRectClipState(NULL) {
39ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    transform = &mTransformRoot;
40ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    clipRect = &mClipRectRoot;
41ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    region = NULL;
428ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    clipRegion = &mClipRegionRoot;
43ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
44ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
45ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/**
46ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Copies the specified snapshot/ The specified snapshot is stored as
47ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * the previous snapshot.
48ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy */
49e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris CraikSnapshot::Snapshot(const sp<Snapshot>& s, int saveFlags)
50e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        : flags(0)
51e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        , previous(s)
52e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        , layer(s->layer)
53e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        , fbo(s->fbo)
54e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        , invisible(s->invisible)
55e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik        , empty(false)
56a64a2bef1048db5a742843f1e3bea9e80d0defc5Chris Craik        , alpha(s->alpha)
57deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        , roundRectClipState(s->roundRectClipState)
5869e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik        , mViewportData(s->mViewportData)
5969e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik        , mRelativeLightCenter(s->mRelativeLightCenter) {
60ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
61ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        mTransformRoot.load(*s->transform);
62ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        transform = &mTransformRoot;
63ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    } else {
64ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        transform = s->transform;
65ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    }
66ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
67ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    if (saveFlags & SkCanvas::kClip_SaveFlag) {
68ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        mClipRectRoot.set(*s->clipRect);
69ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        clipRect = &mClipRectRoot;
708ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        if (!s->clipRegion->isEmpty()) {
710baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy            mClipRegionRoot.op(*s->clipRegion, SkRegion::kUnion_Op);
72967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
738ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy        clipRegion = &mClipRegionRoot;
74ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    } else {
75ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        clipRect = s->clipRect;
76967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        clipRegion = s->clipRegion;
77ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    }
78ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
79ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    if (s->flags & Snapshot::kFlagFboTarget) {
80ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        flags |= Snapshot::kFlagFboTarget;
81ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        region = s->region;
82ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    } else {
83ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        region = NULL;
84ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    }
85ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
86ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
87ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
88ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Clipping
89ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
90ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
91967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guyvoid Snapshot::ensureClipRegion() {
928ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    if (clipRegion->isEmpty()) {
930baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        clipRegion->setRect(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
94967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    }
95967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy}
96967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
97967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guyvoid Snapshot::copyClipRectFromRegion() {
98967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    if (!clipRegion->isEmpty()) {
990baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        const SkIRect& bounds = clipRegion->getBounds();
1000baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        clipRect->set(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
101967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
102967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        if (clipRegion->isRect()) {
1030baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy            clipRegion->setEmpty();
104967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
105967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    } else {
106967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        clipRect->setEmpty();
107967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    }
108967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy}
109967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
1100baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guybool Snapshot::clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op) {
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;
1168ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy}
1178ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy
1188ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guybool Snapshot::clipRegionTransformed(const SkRegion& region, SkRegion::Op op) {
1198ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    ensureClipRegion();
1208ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    clipRegion->op(region, op);
1218ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    copyClipRectFromRegion();
1228ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    flags |= Snapshot::kFlagClipSet;
1238ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    return true;
124967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy}
125967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy
126ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
127ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    Rect r(left, top, right, bottom);
128ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    transform->mapRect(r);
129ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    return clipTransformed(r, op);
130ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
131ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
132ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {
133ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    bool clipped = false;
134ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
135ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    switch (op) {
136967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        case SkRegion::kIntersect_Op: {
1378ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy            if (CC_UNLIKELY(!clipRegion->isEmpty())) {
138735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy                ensureClipRegion();
1390baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy                clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kIntersect_Op);
140967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy            } else {
141967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                clipped = clipRect->intersect(r);
142967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                if (!clipped) {
143967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                    clipRect->setEmpty();
144967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                    clipped = true;
145967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy                }
146ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy            }
147ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy            break;
148967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
149967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        case SkRegion::kReplace_Op: {
150967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy            setClip(r.left, r.top, r.right, r.bottom);
151ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy            clipped = true;
152ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy            break;
153967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy        }
1540baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        default: {
1550baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy            ensureClipRegion();
1560baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy            clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, op);
1570baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy            break;
1580baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        }
159ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    }
160ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
161ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    if (clipped) {
162ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy        flags |= Snapshot::kFlagClipSet;
163ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    }
164ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
165ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    return clipped;
166ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
167ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
168ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::setClip(float left, float top, float right, float bottom) {
169ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    clipRect->set(left, top, right, bottom);
1708ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy    if (!clipRegion->isEmpty()) {
1710baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        clipRegion->setEmpty();
172967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    }
173ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    flags |= Snapshot::kFlagClipSet;
174ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
175ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
176a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guybool Snapshot::hasPerspectiveTransform() const {
177a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy    return transform->isPerspective();
178a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy}
179a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy
180ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyconst Rect& Snapshot::getLocalClip() {
181ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    mat4 inverse;
182ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    inverse.loadInverse(*transform);
183ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
184ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    mLocalClip.set(*clipRect);
185ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    inverse.mapRect(mLocalClip);
186ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
187ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    return mLocalClip;
188ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
189ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
190ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::resetClip(float left, float top, float right, float bottom) {
1913bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    // TODO: This is incorrect, when we start rendering into a new layer,
1923bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    // we may have to modify the previous snapshot's clip rect and clip
1933bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    // region if the previous restore() call did not restore the clip
194ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    clipRect = &mClipRectRoot;
1953c099c42fd7ead1429076055990ae39b72c904f4Romain Guy    clipRegion = &mClipRegionRoot;
196967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy    setClip(left, top, right, bottom);
197ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
198ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
199ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
200ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Transforms
201ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
202ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
203ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::resetTransform(float x, float y, float z) {
20469e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik    // before resetting, map current light pos with inverse of current transform
20569e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik    Vector3 center = mRelativeLightCenter;
20669e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik    mat4 inverse;
20769e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik    inverse.loadInverse(*transform);
20869e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik    inverse.mapPoint3d(center);
20969e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik    mRelativeLightCenter = center;
21069e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik
211ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    transform = &mTransformRoot;
212ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    transform->loadTranslate(x, y, z);
213ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
214ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
215ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
216af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik// Clipping round rect
217deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik///////////////////////////////////////////////////////////////////////////////
218deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
219e83cbd451868a734bfac07ccd680d5617080b579Chris Craikvoid Snapshot::setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds,
220e83cbd451868a734bfac07ccd680d5617080b579Chris Craik        float radius, bool highPriority) {
221af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    if (bounds.isEmpty()) {
222af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik        clipRect->setEmpty();
223af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik        return;
224af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    }
225deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
226e83cbd451868a734bfac07ccd680d5617080b579Chris Craik    if (roundRectClipState && roundRectClipState->highPriority) {
227e83cbd451868a734bfac07ccd680d5617080b579Chris Craik        // ignore, don't replace, already have a high priority clip
228e83cbd451868a734bfac07ccd680d5617080b579Chris Craik        return;
229e83cbd451868a734bfac07ccd680d5617080b579Chris Craik    }
230e83cbd451868a734bfac07ccd680d5617080b579Chris Craik
231deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    RoundRectClipState* state = new (allocator) RoundRectClipState;
232deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
233e83cbd451868a734bfac07ccd680d5617080b579Chris Craik    state->highPriority = highPriority;
234e83cbd451868a734bfac07ccd680d5617080b579Chris Craik
235deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    // store the inverse drawing matrix
236af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    Matrix4 roundRectDrawingMatrix;
237af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    roundRectDrawingMatrix.load(getOrthoMatrix());
238af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    roundRectDrawingMatrix.multiply(*transform);
239af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    state->matrix.loadInverse(roundRectDrawingMatrix);
240deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
241deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    // compute area under rounded corners - only draws overlapping these rects need to be clipped
242deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    for (int i = 0 ; i < 4; i++) {
243deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        state->dangerRects[i] = bounds;
244deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    }
245deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    state->dangerRects[0].bottom = state->dangerRects[1].bottom = bounds.top + radius;
246deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    state->dangerRects[0].right = state->dangerRects[2].right = bounds.left + radius;
247deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    state->dangerRects[1].left = state->dangerRects[3].left = bounds.right - radius;
248deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    state->dangerRects[2].top = state->dangerRects[3].top = bounds.bottom - radius;
249deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    for (int i = 0; i < 4; i++) {
250deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        transform->mapRect(state->dangerRects[i]);
251deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
252deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        // round danger rects out as though they are AA geometry (since they essentially are)
253deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        state->dangerRects[i].snapGeometryToPixelBoundaries(true);
254deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    }
255deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
256deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    // store RR area
257af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    state->innerRect = bounds;
258af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    state->innerRect.inset(radius);
259af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    state->radius = radius;
260deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
261deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    // store as immutable so, for this frame, pointer uniquely identifies this bundle of shader info
262deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    roundRectClipState = state;
263deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik}
264deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
265deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik///////////////////////////////////////////////////////////////////////////////
266ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Queries
267ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy///////////////////////////////////////////////////////////////////////////////
268ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
269ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::isIgnored() const {
270ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy    return invisible || empty;
271ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}
272ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy
2735f803623559aab395a29d575c37c4e39c23a4b4eChris Craikvoid Snapshot::dump() const {
2745f803623559aab395a29d575c37c4e39c23a4b4eChris Craik    ALOGD("Snapshot %p, flags %x, prev %p, height %d, ignored %d, hasComplexClip %d",
275a64a2bef1048db5a742843f1e3bea9e80d0defc5Chris Craik            this, flags, previous.get(), getViewportHeight(), isIgnored(), clipRegion && !clipRegion->isEmpty());
2765f803623559aab395a29d575c37c4e39c23a4b4eChris Craik    ALOGD("  ClipRect (at %p) %.1f %.1f %.1f %.1f",
2775f803623559aab395a29d575c37c4e39c23a4b4eChris Craik            clipRect, clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
2785f803623559aab395a29d575c37c4e39c23a4b4eChris Craik    ALOGD("  Transform (at %p):", transform);
2795f803623559aab395a29d575c37c4e39c23a4b4eChris Craik    transform->dump();
2805f803623559aab395a29d575c37c4e39c23a4b4eChris Craik}
2815f803623559aab395a29d575c37c4e39c23a4b4eChris Craik
282ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}; // namespace uirenderer
283ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}; // namespace android
284