CanvasState.cpp revision a2a70723b8cbda4354d23f901f995623e819012c
114e513058ed4168c94e015638d16f5f87fd8063aChris Craik/*
214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Copyright (C) 2014 The Android Open Source Project
314e513058ed4168c94e015638d16f5f87fd8063aChris Craik *
414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Licensed under the Apache License, Version 2.0 (the "License");
514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * you may not use this file except in compliance with the License.
614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * You may obtain a copy of the License at
714e513058ed4168c94e015638d16f5f87fd8063aChris Craik *
814e513058ed4168c94e015638d16f5f87fd8063aChris Craik *      http://www.apache.org/licenses/LICENSE-2.0
914e513058ed4168c94e015638d16f5f87fd8063aChris Craik *
1014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Unless required by applicable law or agreed to in writing, software
1114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * distributed under the License is distributed on an "AS IS" BASIS,
1214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * See the License for the specific language governing permissions and
1414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * limitations under the License.
1514e513058ed4168c94e015638d16f5f87fd8063aChris Craik */
1614e513058ed4168c94e015638d16f5f87fd8063aChris Craik
1714e513058ed4168c94e015638d16f5f87fd8063aChris Craik#include <SkCanvas.h>
1814e513058ed4168c94e015638d16f5f87fd8063aChris Craik
19984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include "CanvasState.h"
20af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik#include "utils/MathUtils.h"
21af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik
2214e513058ed4168c94e015638d16f5f87fd8063aChris Craiknamespace android {
2314e513058ed4168c94e015638d16f5f87fd8063aChris Craiknamespace uirenderer {
2414e513058ed4168c94e015638d16f5f87fd8063aChris Craik
25984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
26984162fb7e4010b6e2908352dbff17ed47eecf06Tom HudsonCanvasState::CanvasState(CanvasStateClient& renderer)
27058fc640017c90120c599d378a4cbc55668b05b7Chris Craik        : mDirtyClip(false)
28058fc640017c90120c599d378a4cbc55668b05b7Chris Craik        , mWidth(-1)
29058fc640017c90120c599d378a4cbc55668b05b7Chris Craik        , mHeight(-1)
30058fc640017c90120c599d378a4cbc55668b05b7Chris Craik        , mSaveCount(1)
31984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson        , mCanvas(renderer)
32d9ee550888011a64fa3f35e666360ec8278597d8John Reck        , mSnapshot(&mFirstSnapshot) {
33d9ee550888011a64fa3f35e666360ec8278597d8John Reck}
34d9ee550888011a64fa3f35e666360ec8278597d8John Reck
35d9ee550888011a64fa3f35e666360ec8278597d8John ReckCanvasState::~CanvasState() {
36d9ee550888011a64fa3f35e666360ec8278597d8John Reck    // First call freeSnapshot on all but mFirstSnapshot
37d9ee550888011a64fa3f35e666360ec8278597d8John Reck    // to invoke all the dtors
38d9ee550888011a64fa3f35e666360ec8278597d8John Reck    freeAllSnapshots();
39984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
40d9ee550888011a64fa3f35e666360ec8278597d8John Reck    // Now actually release the memory
41d9ee550888011a64fa3f35e666360ec8278597d8John Reck    while (mSnapshotPool) {
42d9ee550888011a64fa3f35e666360ec8278597d8John Reck        void* temp = mSnapshotPool;
43d9ee550888011a64fa3f35e666360ec8278597d8John Reck        mSnapshotPool = mSnapshotPool->previous;
44d9ee550888011a64fa3f35e666360ec8278597d8John Reck        free(temp);
45d9ee550888011a64fa3f35e666360ec8278597d8John Reck    }
4614e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
4714e513058ed4168c94e015638d16f5f87fd8063aChris Craik
4864e445bf74bee2098781d608cedfd723d8cc88d3Chris Craikvoid CanvasState::initializeSaveStack(
4964e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik        int viewportWidth, int viewportHeight,
5064e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik        float clipLeft, float clipTop,
5169e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik        float clipRight, float clipBottom, const Vector3& lightCenter) {
5264e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik    if (mWidth != viewportWidth || mHeight != viewportHeight) {
5364e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik        mWidth = viewportWidth;
5464e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik        mHeight = viewportHeight;
55d9ee550888011a64fa3f35e666360ec8278597d8John Reck        mFirstSnapshot.initializeViewport(viewportWidth, viewportHeight);
5664e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik        mCanvas.onViewportInitialized();
5764e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik    }
5864e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik
59d9ee550888011a64fa3f35e666360ec8278597d8John Reck    freeAllSnapshots();
60d9ee550888011a64fa3f35e666360ec8278597d8John Reck    mSnapshot = allocSnapshot(&mFirstSnapshot,
6114e513058ed4168c94e015638d16f5f87fd8063aChris Craik            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
6214e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom);
636b109c74982033d4a220cd10a0eab8b024b351c9Chris Craik    mSnapshot->fbo = mCanvas.getTargetFbo();
6469e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik    mSnapshot->setRelativeLightCenter(lightCenter);
6514e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSaveCount = 1;
6614e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
6714e513058ed4168c94e015638d16f5f87fd8063aChris Craik
68d9ee550888011a64fa3f35e666360ec8278597d8John ReckSnapshot* CanvasState::allocSnapshot(Snapshot* previous, int savecount) {
69d9ee550888011a64fa3f35e666360ec8278597d8John Reck    void* memory;
70d9ee550888011a64fa3f35e666360ec8278597d8John Reck    if (mSnapshotPool) {
71d9ee550888011a64fa3f35e666360ec8278597d8John Reck        memory = mSnapshotPool;
72d9ee550888011a64fa3f35e666360ec8278597d8John Reck        mSnapshotPool = mSnapshotPool->previous;
73d9ee550888011a64fa3f35e666360ec8278597d8John Reck        mSnapshotPoolCount--;
74d9ee550888011a64fa3f35e666360ec8278597d8John Reck    } else {
75d9ee550888011a64fa3f35e666360ec8278597d8John Reck        memory = malloc(sizeof(Snapshot));
76d9ee550888011a64fa3f35e666360ec8278597d8John Reck    }
77d9ee550888011a64fa3f35e666360ec8278597d8John Reck    return new (memory) Snapshot(previous, savecount);
78d9ee550888011a64fa3f35e666360ec8278597d8John Reck}
79d9ee550888011a64fa3f35e666360ec8278597d8John Reck
80d9ee550888011a64fa3f35e666360ec8278597d8John Reckvoid CanvasState::freeSnapshot(Snapshot* snapshot) {
81d9ee550888011a64fa3f35e666360ec8278597d8John Reck    snapshot->~Snapshot();
82d9ee550888011a64fa3f35e666360ec8278597d8John Reck    // Arbitrary number, just don't let this grown unbounded
83d9ee550888011a64fa3f35e666360ec8278597d8John Reck    if (mSnapshotPoolCount > 10) {
84d9ee550888011a64fa3f35e666360ec8278597d8John Reck        free((void*) snapshot);
85d9ee550888011a64fa3f35e666360ec8278597d8John Reck    } else {
86d9ee550888011a64fa3f35e666360ec8278597d8John Reck        snapshot->previous = mSnapshotPool;
87d9ee550888011a64fa3f35e666360ec8278597d8John Reck        mSnapshotPool = snapshot;
88d9ee550888011a64fa3f35e666360ec8278597d8John Reck        mSnapshotPoolCount++;
89d9ee550888011a64fa3f35e666360ec8278597d8John Reck    }
90d9ee550888011a64fa3f35e666360ec8278597d8John Reck}
91d9ee550888011a64fa3f35e666360ec8278597d8John Reck
92d9ee550888011a64fa3f35e666360ec8278597d8John Reckvoid CanvasState::freeAllSnapshots() {
93d9ee550888011a64fa3f35e666360ec8278597d8John Reck    while (mSnapshot != &mFirstSnapshot) {
94d9ee550888011a64fa3f35e666360ec8278597d8John Reck        Snapshot* temp = mSnapshot;
95d9ee550888011a64fa3f35e666360ec8278597d8John Reck        mSnapshot = mSnapshot->previous;
96d9ee550888011a64fa3f35e666360ec8278597d8John Reck        freeSnapshot(temp);
97d9ee550888011a64fa3f35e666360ec8278597d8John Reck    }
98d9ee550888011a64fa3f35e666360ec8278597d8John Reck}
99d9ee550888011a64fa3f35e666360ec8278597d8John Reck
10014e513058ed4168c94e015638d16f5f87fd8063aChris Craik///////////////////////////////////////////////////////////////////////////////
10114e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Save (layer)
10214e513058ed4168c94e015638d16f5f87fd8063aChris Craik///////////////////////////////////////////////////////////////////////////////
10314e513058ed4168c94e015638d16f5f87fd8063aChris Craik
10414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/**
105984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Guaranteed to save without side-effects
10614e513058ed4168c94e015638d16f5f87fd8063aChris Craik *
107984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * This approach, here and in restoreSnapshot(), allows subclasses to directly manipulate the save
10814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * stack, and ensures restoreToCount() doesn't call back into subclass overrides.
10914e513058ed4168c94e015638d16f5f87fd8063aChris Craik */
110984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonint CanvasState::saveSnapshot(int flags) {
111d9ee550888011a64fa3f35e666360ec8278597d8John Reck    mSnapshot = allocSnapshot(mSnapshot, flags);
11214e513058ed4168c94e015638d16f5f87fd8063aChris Craik    return mSaveCount++;
11314e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
11414e513058ed4168c94e015638d16f5f87fd8063aChris Craik
115984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonint CanvasState::save(int flags) {
11614e513058ed4168c94e015638d16f5f87fd8063aChris Craik    return saveSnapshot(flags);
11714e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
11814e513058ed4168c94e015638d16f5f87fd8063aChris Craik
11914e513058ed4168c94e015638d16f5f87fd8063aChris Craik/**
120984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Guaranteed to restore without side-effects.
12114e513058ed4168c94e015638d16f5f87fd8063aChris Craik */
122984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restoreSnapshot() {
123d9ee550888011a64fa3f35e666360ec8278597d8John Reck    Snapshot* toRemove = mSnapshot;
124d9ee550888011a64fa3f35e666360ec8278597d8John Reck    Snapshot* toRestore = mSnapshot->previous;
12514e513058ed4168c94e015638d16f5f87fd8063aChris Craik
12614e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSaveCount--;
12714e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSnapshot = toRestore;
12814e513058ed4168c94e015638d16f5f87fd8063aChris Craik
12914e513058ed4168c94e015638d16f5f87fd8063aChris Craik    // subclass handles restore implementation
130984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    mCanvas.onSnapshotRestored(*toRemove, *toRestore);
131d9ee550888011a64fa3f35e666360ec8278597d8John Reck
132d9ee550888011a64fa3f35e666360ec8278597d8John Reck    freeSnapshot(toRemove);
13314e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
13414e513058ed4168c94e015638d16f5f87fd8063aChris Craik
135984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restore() {
13614e513058ed4168c94e015638d16f5f87fd8063aChris Craik    if (mSaveCount > 1) {
13714e513058ed4168c94e015638d16f5f87fd8063aChris Craik        restoreSnapshot();
13814e513058ed4168c94e015638d16f5f87fd8063aChris Craik    }
13914e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
14014e513058ed4168c94e015638d16f5f87fd8063aChris Craik
141984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restoreToCount(int saveCount) {
14214e513058ed4168c94e015638d16f5f87fd8063aChris Craik    if (saveCount < 1) saveCount = 1;
14314e513058ed4168c94e015638d16f5f87fd8063aChris Craik
14414e513058ed4168c94e015638d16f5f87fd8063aChris Craik    while (mSaveCount > saveCount) {
14514e513058ed4168c94e015638d16f5f87fd8063aChris Craik        restoreSnapshot();
14614e513058ed4168c94e015638d16f5f87fd8063aChris Craik    }
14714e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
14814e513058ed4168c94e015638d16f5f87fd8063aChris Craik
14914e513058ed4168c94e015638d16f5f87fd8063aChris Craik///////////////////////////////////////////////////////////////////////////////
15014e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Matrix
15114e513058ed4168c94e015638d16f5f87fd8063aChris Craik///////////////////////////////////////////////////////////////////////////////
15214e513058ed4168c94e015638d16f5f87fd8063aChris Craik
153984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::getMatrix(SkMatrix* matrix) const {
15414e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSnapshot->transform->copyTo(*matrix);
15514e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
15614e513058ed4168c94e015638d16f5f87fd8063aChris Craik
157984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::translate(float dx, float dy, float dz) {
15814e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSnapshot->transform->translate(dx, dy, dz);
15914e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
16014e513058ed4168c94e015638d16f5f87fd8063aChris Craik
161984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::rotate(float degrees) {
16214e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f);
16314e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
16414e513058ed4168c94e015638d16f5f87fd8063aChris Craik
165984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::scale(float sx, float sy) {
16614e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSnapshot->transform->scale(sx, sy, 1.0f);
16714e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
16814e513058ed4168c94e015638d16f5f87fd8063aChris Craik
169984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::skew(float sx, float sy) {
17014e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSnapshot->transform->skew(sx, sy);
17114e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
17214e513058ed4168c94e015638d16f5f87fd8063aChris Craik
173984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setMatrix(const SkMatrix& matrix) {
174139088228faa7f3c446af7387e017933998a5570Derek Sollenberger    mSnapshot->transform->load(matrix);
17514e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
17614e513058ed4168c94e015638d16f5f87fd8063aChris Craik
177984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setMatrix(const Matrix4& matrix) {
1787c85c54499994c687a833644f7f213e747fadb98Chris Craik    *(mSnapshot->transform) = matrix;
17914e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
18014e513058ed4168c94e015638d16f5f87fd8063aChris Craik
181984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::concatMatrix(const SkMatrix& matrix) {
182139088228faa7f3c446af7387e017933998a5570Derek Sollenberger    mat4 transform(matrix);
18314e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSnapshot->transform->multiply(transform);
18414e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
18514e513058ed4168c94e015638d16f5f87fd8063aChris Craik
186984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::concatMatrix(const Matrix4& matrix) {
18714e513058ed4168c94e015638d16f5f87fd8063aChris Craik    mSnapshot->transform->multiply(matrix);
18814e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
18914e513058ed4168c94e015638d16f5f87fd8063aChris Craik
19014e513058ed4168c94e015638d16f5f87fd8063aChris Craik///////////////////////////////////////////////////////////////////////////////
19114e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Clip
19214e513058ed4168c94e015638d16f5f87fd8063aChris Craik///////////////////////////////////////////////////////////////////////////////
19314e513058ed4168c94e015638d16f5f87fd8063aChris Craik
194984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
195a2a70723b8cbda4354d23f901f995623e819012cChris Craik    mSnapshot->clip(Rect(left, top, right, bottom), op);
1964d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik    mDirtyClip = true;
197487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    return !mSnapshot->clipIsEmpty();
198d6b65f67717025b1162f86f04e2caa5723566cacChris Craik}
199d6b65f67717025b1162f86f04e2caa5723566cacChris Craik
200984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) {
2014d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik    mSnapshot->clipPath(*path, op);
2024d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik    mDirtyClip = true;
203487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    return !mSnapshot->clipIsEmpty();
204d6b65f67717025b1162f86f04e2caa5723566cacChris Craik}
205d6b65f67717025b1162f86f04e2caa5723566cacChris Craik
206984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) {
2074d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik    mSnapshot->clipRegionTransformed(*region, op);
2084d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik    mDirtyClip = true;
209487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    return !mSnapshot->clipIsEmpty();
210d6b65f67717025b1162f86f04e2caa5723566cacChris Craik}
21114e513058ed4168c94e015638d16f5f87fd8063aChris Craik
212984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) {
213af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    Rect bounds;
214af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    float radius;
215af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported
216af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik
21779d26c72aa6f898125df2386054f6a293da4122aChris Craik    bool outlineIsRounded = MathUtils::isPositive(radius);
21879d26c72aa6f898125df2386054f6a293da4122aChris Craik    if (!outlineIsRounded || currentTransform()->isSimple()) {
219af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik        // TODO: consider storing this rect separately, so that this can't be replaced with clip ops
220af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik        clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op);
221af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    }
22279d26c72aa6f898125df2386054f6a293da4122aChris Craik    if (outlineIsRounded) {
223e83cbd451868a734bfac07ccd680d5617080b579Chris Craik        setClippingRoundRect(allocator, bounds, radius, false);
22479d26c72aa6f898125df2386054f6a293da4122aChris Craik    }
225deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik}
226deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
227984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setClippingRoundRect(LinearAllocator& allocator,
228e83cbd451868a734bfac07ccd680d5617080b579Chris Craik        const Rect& rect, float radius, bool highPriority) {
229e83cbd451868a734bfac07ccd680d5617080b579Chris Craik    mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority);
230af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik}
231af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik
232fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craikvoid CanvasState::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) {
233fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik    mSnapshot->setProjectionPathMask(allocator, path);
234fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik}
235af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik
23614e513058ed4168c94e015638d16f5f87fd8063aChris Craik///////////////////////////////////////////////////////////////////////////////
23714e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Quick Rejection
23814e513058ed4168c94e015638d16f5f87fd8063aChris Craik///////////////////////////////////////////////////////////////////////////////
23914e513058ed4168c94e015638d16f5f87fd8063aChris Craik
24014e513058ed4168c94e015638d16f5f87fd8063aChris Craik/**
24114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Calculates whether content drawn within the passed bounds would be outside of, or intersect with
24214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * the clipRect. Does not modify the scissor.
24314e513058ed4168c94e015638d16f5f87fd8063aChris Craik *
24414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param clipRequired if not null, will be set to true if element intersects clip
24514e513058ed4168c94e015638d16f5f87fd8063aChris Craik *         (and wasn't rejected)
24614e513058ed4168c94e015638d16f5f87fd8063aChris Craik *
24714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param snapOut if set, the geometry will be treated as having an AA ramp.
24814e513058ed4168c94e015638d16f5f87fd8063aChris Craik *         See Rect::snapGeometryToPixelBoundaries()
24914e513058ed4168c94e015638d16f5f87fd8063aChris Craik */
250984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::calculateQuickRejectForScissor(float left, float top,
251deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        float right, float bottom,
252deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        bool* clipRequired, bool* roundRectClipRequired,
253deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        bool snapOut) const {
25414e513058ed4168c94e015638d16f5f87fd8063aChris Craik    if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
25514e513058ed4168c94e015638d16f5f87fd8063aChris Craik        return true;
25614e513058ed4168c94e015638d16f5f87fd8063aChris Craik    }
25714e513058ed4168c94e015638d16f5f87fd8063aChris Craik
25814e513058ed4168c94e015638d16f5f87fd8063aChris Craik    Rect r(left, top, right, bottom);
259d6b65f67717025b1162f86f04e2caa5723566cacChris Craik    currentTransform()->mapRect(r);
26014e513058ed4168c94e015638d16f5f87fd8063aChris Craik    r.snapGeometryToPixelBoundaries(snapOut);
26114e513058ed4168c94e015638d16f5f87fd8063aChris Craik
2626fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik    Rect clipRect(currentRenderTargetClip());
26314e513058ed4168c94e015638d16f5f87fd8063aChris Craik    clipRect.snapToPixelBoundaries();
26414e513058ed4168c94e015638d16f5f87fd8063aChris Craik
26514e513058ed4168c94e015638d16f5f87fd8063aChris Craik    if (!clipRect.intersects(r)) return true;
26614e513058ed4168c94e015638d16f5f87fd8063aChris Craik
26714e513058ed4168c94e015638d16f5f87fd8063aChris Craik    // clip is required if geometry intersects clip rect
268deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    if (clipRequired) {
269deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        *clipRequired = !clipRect.contains(r);
270deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    }
271deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
272deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    // round rect clip is required if RR clip exists, and geometry intersects its corners
273deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    if (roundRectClipRequired) {
274d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        *roundRectClipRequired = mSnapshot->roundRectClipState != nullptr
275deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik                && mSnapshot->roundRectClipState->areaRequiresRoundRectClip(r);
276deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    }
27714e513058ed4168c94e015638d16f5f87fd8063aChris Craik    return false;
27814e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
27914e513058ed4168c94e015638d16f5f87fd8063aChris Craik
280984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::quickRejectConservative(float left, float top,
28114e513058ed4168c94e015638d16f5f87fd8063aChris Craik        float right, float bottom) const {
28214e513058ed4168c94e015638d16f5f87fd8063aChris Craik    if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
28314e513058ed4168c94e015638d16f5f87fd8063aChris Craik        return true;
28414e513058ed4168c94e015638d16f5f87fd8063aChris Craik    }
28514e513058ed4168c94e015638d16f5f87fd8063aChris Craik
28614e513058ed4168c94e015638d16f5f87fd8063aChris Craik    Rect r(left, top, right, bottom);
287d6b65f67717025b1162f86f04e2caa5723566cacChris Craik    currentTransform()->mapRect(r);
28814e513058ed4168c94e015638d16f5f87fd8063aChris Craik    r.roundOut(); // rounded out to be conservative
28914e513058ed4168c94e015638d16f5f87fd8063aChris Craik
2906fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik    Rect clipRect(currentRenderTargetClip());
29114e513058ed4168c94e015638d16f5f87fd8063aChris Craik    clipRect.snapToPixelBoundaries();
29214e513058ed4168c94e015638d16f5f87fd8063aChris Craik
29314e513058ed4168c94e015638d16f5f87fd8063aChris Craik    if (!clipRect.intersects(r)) return true;
29414e513058ed4168c94e015638d16f5f87fd8063aChris Craik
29514e513058ed4168c94e015638d16f5f87fd8063aChris Craik    return false;
29614e513058ed4168c94e015638d16f5f87fd8063aChris Craik}
29714e513058ed4168c94e015638d16f5f87fd8063aChris Craik
298984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} // namespace uirenderer
299984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} // namespace android
300