1b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/*
2b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Copyright (C) 2015 The Android Open Source Project
3b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *
4b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Licensed under the Apache License, Version 2.0 (the "License");
5b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * you may not use this file except in compliance with the License.
6b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * You may obtain a copy of the License at
7b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *
8b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *      http://www.apache.org/licenses/LICENSE-2.0
9b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *
10b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Unless required by applicable law or agreed to in writing, software
11b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * distributed under the License is distributed on an "AS IS" BASIS,
12b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * See the License for the specific language governing permissions and
14b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * limitations under the License.
15b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */
16b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
17b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <gtest/gtest.h>
18b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
19b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <BakedOpState.h>
20e4db79de127cfe961195f52907af8451026eaa20Chris Craik#include <ClipArea.h>
21b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include <RecordedOp.h>
228160f20b0aca8c6595d4b385d673f59b6bcd16a4Chris Craik#include <tests/common/TestUtils.h>
23b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
24b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace android {
25b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace uirenderer {
26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
27386aa031793bb037ec43b6cdbd8908c343cc86cbChris CraikTEST(ResolvedRenderState, construct) {
28e4db79de127cfe961195f52907af8451026eaa20Chris Craik    LinearAllocator allocator;
29b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    Matrix4 translate10x20;
30b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    translate10x20.loadTranslate(10, 20, 0);
31b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
32b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    SkPaint paint;
33e4db79de127cfe961195f52907af8451026eaa20Chris Craik    ClipRect clip(Rect(100, 200));
34e4db79de127cfe961195f52907af8451026eaa20Chris Craik    RectOp recordedOp(Rect(30, 40, 100, 200), translate10x20, &clip, &paint);
35b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    {
36b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        // recorded with transform, no parent transform
37386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        auto parentSnapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 200));
3849b403dc9c47ada51c8e5b883347682a868515f8Chris Craik        ResolvedRenderState state(allocator, *parentSnapshot, recordedOp, false, false);
39b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        EXPECT_MATRIX_APPROX_EQ(state.transform, translate10x20);
40e4db79de127cfe961195f52907af8451026eaa20Chris Craik        EXPECT_EQ(Rect(100, 200), state.clipRect());
41386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_EQ(Rect(40, 60, 100, 200), state.clippedBounds); // translated and also clipped
42386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_EQ(OpClipSideFlags::Right | OpClipSideFlags::Bottom, state.clipSideFlags);
43b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    }
44b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    {
45b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        // recorded with transform and parent transform
46386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        auto parentSnapshot = TestUtils::makeSnapshot(translate10x20, Rect(100, 200));
4749b403dc9c47ada51c8e5b883347682a868515f8Chris Craik        ResolvedRenderState state(allocator, *parentSnapshot, recordedOp, false, false);
48b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
49b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Matrix4 expectedTranslate;
50b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        expectedTranslate.loadTranslate(20, 40, 0);
51386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_MATRIX_APPROX_EQ(expectedTranslate, state.transform);
52b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
53b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        // intersection of parent & transformed child clip
54e4db79de127cfe961195f52907af8451026eaa20Chris Craik        EXPECT_EQ(Rect(10, 20, 100, 200), state.clipRect());
55b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
56b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        // translated and also clipped
57386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_EQ(Rect(50, 80, 100, 200), state.clippedBounds);
58386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_EQ(OpClipSideFlags::Right | OpClipSideFlags::Bottom, state.clipSideFlags);
59386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    }
60386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik}
61386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
62d7448e65e243754f31890baef29dff187dc2e5e5Chris CraikTEST(ResolvedRenderState, computeLocalSpaceClip) {
63e4db79de127cfe961195f52907af8451026eaa20Chris Craik    LinearAllocator allocator;
64d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    Matrix4 translate10x20;
65d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    translate10x20.loadTranslate(10, 20, 0);
66d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik
67d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    SkPaint paint;
68e4db79de127cfe961195f52907af8451026eaa20Chris Craik    ClipRect clip(Rect(100, 200));
69e4db79de127cfe961195f52907af8451026eaa20Chris Craik    RectOp recordedOp(Rect(1000, 1000), translate10x20, &clip, &paint);
70d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    {
71d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        // recorded with transform, no parent transform
72d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        auto parentSnapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 200));
7349b403dc9c47ada51c8e5b883347682a868515f8Chris Craik        ResolvedRenderState state(allocator, *parentSnapshot, recordedOp, false, false);
74d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        EXPECT_EQ(Rect(-10, -20, 90, 180), state.computeLocalSpaceClip())
75d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik            << "Local clip rect should be 100x200, offset by -10,-20";
76d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    }
77d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    {
78d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        // recorded with transform + parent transform
79d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        auto parentSnapshot = TestUtils::makeSnapshot(translate10x20, Rect(100, 200));
8049b403dc9c47ada51c8e5b883347682a868515f8Chris Craik        ResolvedRenderState state(allocator, *parentSnapshot, recordedOp, false, false);
81d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        EXPECT_EQ(Rect(-10, -20, 80, 160), state.computeLocalSpaceClip())
82d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik            << "Local clip rect should be 90x190, offset by -10,-20";
83d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    }
84d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik}
85d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik
86386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craikconst float HAIRLINE = 0.0f;
87386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
88386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik// Note: bounds will be conservative, but not precise for non-hairline
89386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik// - use approx bounds checks for these
90386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craikconst float SEMI_HAIRLINE = 0.3f;
91386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
92386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craikstruct StrokeTestCase {
93386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    float scale;
94386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    float strokeWidth;
95386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    const std::function<void(const ResolvedRenderState&)> validator;
96386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik};
97386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
98386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craikconst static StrokeTestCase sStrokeTestCases[] = {
99386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
100386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        1, HAIRLINE, [](const ResolvedRenderState& state) {
101386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_EQ(Rect(49.5f, 49.5f, 150.5f, 150.5f), state.clippedBounds);
102386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        }
103386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    },
104386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
105386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        1, SEMI_HAIRLINE, [](const ResolvedRenderState& state) {
106386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_TRUE(state.clippedBounds.contains(49.5f, 49.5f, 150.5f, 150.5f));
107386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_TRUE(Rect(49, 49, 151, 151).contains(state.clippedBounds));
108386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        }
109386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    },
110386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
111386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        1, 20, [](const ResolvedRenderState& state) {
112386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_EQ(Rect(40, 40, 160, 160), state.clippedBounds);
113386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        }
114386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    },
115386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
116386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    // 3x3 scale:
117386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
118386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        3, HAIRLINE, [](const ResolvedRenderState& state) {
119386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_EQ(Rect(149.5f, 149.5f, 200, 200), state.clippedBounds);
120386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_EQ(OpClipSideFlags::Right | OpClipSideFlags::Bottom, state.clipSideFlags);
121386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        }
122386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    },
123386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
124386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        3, SEMI_HAIRLINE, [](const ResolvedRenderState& state) {
125386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_TRUE(state.clippedBounds.contains(149.5f, 149.5f, 200, 200));
126386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_TRUE(Rect(149, 149, 200, 200).contains(state.clippedBounds));
127386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        }
128386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    },
129386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
130386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        3, 20, [](const ResolvedRenderState& state) {
131386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_TRUE(state.clippedBounds.contains(120, 120, 200, 200));
132386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_TRUE(Rect(119, 119, 200, 200).contains(state.clippedBounds));
133386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        }
134386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    },
135386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
136386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    // 0.5f x 0.5f scale
137386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
138386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        0.5f, HAIRLINE, [](const ResolvedRenderState& state) {
139386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_EQ(Rect(24.5f, 24.5f, 75.5f, 75.5f), state.clippedBounds);
140386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        }
141386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    },
142386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
143386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        0.5f, SEMI_HAIRLINE, [](const ResolvedRenderState& state) {
144386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_TRUE(state.clippedBounds.contains(24.5f, 24.5f, 75.5f, 75.5f));
145386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_TRUE(Rect(24, 24, 76, 76).contains(state.clippedBounds));
146386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        }
147386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    },
148386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
149386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        0.5f, 20, [](const ResolvedRenderState& state) {
150386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_TRUE(state.clippedBounds.contains(19.5f, 19.5f, 80.5f, 80.5f));
151386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            EXPECT_TRUE(Rect(19, 19, 81, 81).contains(state.clippedBounds));
152386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        }
153386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    }
154386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik};
155386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
156386aa031793bb037ec43b6cdbd8908c343cc86cbChris CraikTEST(ResolvedRenderState, construct_expandForStroke) {
157e4db79de127cfe961195f52907af8451026eaa20Chris Craik    LinearAllocator allocator;
158386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    // Loop over table of test cases and verify different combinations of stroke width and transform
159386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    for (auto&& testCase : sStrokeTestCases) {
160386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        SkPaint strokedPaint;
161386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        strokedPaint.setAntiAlias(true);
162386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        strokedPaint.setStyle(SkPaint::kStroke_Style);
163386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        strokedPaint.setStrokeWidth(testCase.strokeWidth);
164386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
165e4db79de127cfe961195f52907af8451026eaa20Chris Craik        ClipRect clip(Rect(200, 200));
166386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        RectOp recordedOp(Rect(50, 50, 150, 150),
167e4db79de127cfe961195f52907af8451026eaa20Chris Craik                Matrix4::identity(), &clip, &strokedPaint);
168386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
169386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        Matrix4 snapshotMatrix;
170386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        snapshotMatrix.loadScale(testCase.scale, testCase.scale, 1);
171386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        auto parentSnapshot = TestUtils::makeSnapshot(snapshotMatrix, Rect(200, 200));
172386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
17349b403dc9c47ada51c8e5b883347682a868515f8Chris Craik        ResolvedRenderState state(allocator, *parentSnapshot, recordedOp, true, false);
174386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        testCase.validator(state);
175b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    }
176b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
177b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
178386aa031793bb037ec43b6cdbd8908c343cc86cbChris CraikTEST(BakedOpState, tryConstruct) {
179b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    Matrix4 translate100x0;
180b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    translate100x0.loadTranslate(100, 0, 0);
181b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
182b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    SkPaint paint;
183e4db79de127cfe961195f52907af8451026eaa20Chris Craik    ClipRect clip(Rect(100, 200));
184b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
18515f046866cb650d78f55d03327cfa4a474fc9471Chris Craik    LinearAllocator allocator;
18615f046866cb650d78f55d03327cfa4a474fc9471Chris Craik    RectOp successOp(Rect(30, 40, 100, 200), Matrix4::identity(), &clip, &paint);
18715f046866cb650d78f55d03327cfa4a474fc9471Chris Craik    auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 200));
18815f046866cb650d78f55d03327cfa4a474fc9471Chris Craik    EXPECT_NE(nullptr, BakedOpState::tryConstruct(allocator, *snapshot, successOp))
18915f046866cb650d78f55d03327cfa4a474fc9471Chris Craik            << "successOp NOT rejected by clip, so should be constructed";
19015f046866cb650d78f55d03327cfa4a474fc9471Chris Craik    size_t successAllocSize = allocator.usedSize();
19115f046866cb650d78f55d03327cfa4a474fc9471Chris Craik    EXPECT_LE(64u, successAllocSize) << "relatively large alloc for non-rejected op";
19215f046866cb650d78f55d03327cfa4a474fc9471Chris Craik
19315f046866cb650d78f55d03327cfa4a474fc9471Chris Craik    RectOp rejectOp(Rect(30, 40, 100, 200), translate100x0, &clip, &paint);
19415f046866cb650d78f55d03327cfa4a474fc9471Chris Craik    EXPECT_EQ(nullptr, BakedOpState::tryConstruct(allocator, *snapshot, rejectOp))
19515f046866cb650d78f55d03327cfa4a474fc9471Chris Craik            << "rejectOp rejected by clip, so should not be constructed";
19615f046866cb650d78f55d03327cfa4a474fc9471Chris Craik
19715f046866cb650d78f55d03327cfa4a474fc9471Chris Craik    // NOTE: this relies on the clip having already been serialized by the op above
19815f046866cb650d78f55d03327cfa4a474fc9471Chris Craik    EXPECT_EQ(successAllocSize, allocator.usedSize()) << "no extra allocation used for rejected op";
199b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
200b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
201386aa031793bb037ec43b6cdbd8908c343cc86cbChris CraikTEST(BakedOpState, tryShadowOpConstruct) {
202420d655950447f508bbc88e072337d6539f1c5d1Chris Craik    Matrix4 translate10x20;
203420d655950447f508bbc88e072337d6539f1c5d1Chris Craik    translate10x20.loadTranslate(10, 20, 0);
204420d655950447f508bbc88e072337d6539f1c5d1Chris Craik
205d3daa3198e2212c985c634821682d5819346b653Chris Craik    LinearAllocator allocator;
206d3daa3198e2212c985c634821682d5819346b653Chris Craik    {
207420d655950447f508bbc88e072337d6539f1c5d1Chris Craik        auto snapshot = TestUtils::makeSnapshot(translate10x20, Rect()); // Note: empty clip
208386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        BakedOpState* bakedState = BakedOpState::tryShadowOpConstruct(allocator, *snapshot, (ShadowOp*)0x1234);
209d3daa3198e2212c985c634821682d5819346b653Chris Craik
21015f046866cb650d78f55d03327cfa4a474fc9471Chris Craik        EXPECT_EQ(nullptr, bakedState) << "op should be rejected by clip, so not constructed";
21115f046866cb650d78f55d03327cfa4a474fc9471Chris Craik        EXPECT_EQ(0u, allocator.usedSize()) << "no serialization, even for clip,"
21215f046866cb650d78f55d03327cfa4a474fc9471Chris Craik                "since op is quick rejected based on snapshot clip";
213d3daa3198e2212c985c634821682d5819346b653Chris Craik    }
214d3daa3198e2212c985c634821682d5819346b653Chris Craik    {
215420d655950447f508bbc88e072337d6539f1c5d1Chris Craik        auto snapshot = TestUtils::makeSnapshot(translate10x20, Rect(100, 200));
216386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        BakedOpState* bakedState = BakedOpState::tryShadowOpConstruct(allocator, *snapshot, (ShadowOp*)0x1234);
217d3daa3198e2212c985c634821682d5819346b653Chris Craik
21815f046866cb650d78f55d03327cfa4a474fc9471Chris Craik        ASSERT_NE(nullptr, bakedState) << "NOT rejected by clip, so op should be constructed";
21915f046866cb650d78f55d03327cfa4a474fc9471Chris Craik        EXPECT_LE(64u, allocator.usedSize()) << "relatively large alloc for non-rejected op";
220420d655950447f508bbc88e072337d6539f1c5d1Chris Craik
221420d655950447f508bbc88e072337d6539f1c5d1Chris Craik        EXPECT_MATRIX_APPROX_EQ(translate10x20, bakedState->computedState.transform);
222420d655950447f508bbc88e072337d6539f1c5d1Chris Craik        EXPECT_EQ(Rect(100, 200), bakedState->computedState.clippedBounds);
223d3daa3198e2212c985c634821682d5819346b653Chris Craik    }
224d3daa3198e2212c985c634821682d5819346b653Chris Craik}
225d3daa3198e2212c985c634821682d5819346b653Chris Craik
226386aa031793bb037ec43b6cdbd8908c343cc86cbChris CraikTEST(BakedOpState, tryStrokeableOpConstruct) {
227386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    LinearAllocator allocator;
228386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
229386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        // check regular rejection
230386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        SkPaint paint;
231386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        paint.setStyle(SkPaint::kStrokeAndFill_Style);
232386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        paint.setStrokeWidth(0.0f);
233e4db79de127cfe961195f52907af8451026eaa20Chris Craik        ClipRect clip(Rect(100, 200));
234e4db79de127cfe961195f52907af8451026eaa20Chris Craik        RectOp rejectOp(Rect(100, 200), Matrix4::identity(), &clip, &paint);
235386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect()); // Note: empty clip
236386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        auto bakedState = BakedOpState::tryStrokeableOpConstruct(allocator, *snapshot, rejectOp,
23749b403dc9c47ada51c8e5b883347682a868515f8Chris Craik                BakedOpState::StrokeBehavior::StyleDefined, false);
238386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
239386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_EQ(nullptr, bakedState);
240386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_GT(8u, allocator.usedSize()); // no significant allocation space used for rejected op
241386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    }
242386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
243386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        // check simple unscaled expansion
244386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        SkPaint paint;
245386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        paint.setStyle(SkPaint::kStrokeAndFill_Style);
246386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        paint.setStrokeWidth(10.0f);
247e4db79de127cfe961195f52907af8451026eaa20Chris Craik        ClipRect clip(Rect(200, 200));
248e4db79de127cfe961195f52907af8451026eaa20Chris Craik        RectOp rejectOp(Rect(50, 50, 150, 150), Matrix4::identity(), &clip, &paint);
249386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(200, 200));
250386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        auto bakedState = BakedOpState::tryStrokeableOpConstruct(allocator, *snapshot, rejectOp,
25149b403dc9c47ada51c8e5b883347682a868515f8Chris Craik                BakedOpState::StrokeBehavior::StyleDefined, false);
252386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
253386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        ASSERT_NE(nullptr, bakedState);
254386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_EQ(Rect(45, 45, 155, 155), bakedState->computedState.clippedBounds);
255386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_EQ(0, bakedState->computedState.clipSideFlags);
256386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    }
257386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    {
258386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        // check simple unscaled expansion, and fill style with stroke forced
259386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        SkPaint paint;
260386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        paint.setStyle(SkPaint::kFill_Style);
261386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        paint.setStrokeWidth(10.0f);
262e4db79de127cfe961195f52907af8451026eaa20Chris Craik        ClipRect clip(Rect(200, 200));
263e4db79de127cfe961195f52907af8451026eaa20Chris Craik        RectOp rejectOp(Rect(50, 50, 150, 150), Matrix4::identity(), &clip, &paint);
264386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(200, 200));
265386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        auto bakedState = BakedOpState::tryStrokeableOpConstruct(allocator, *snapshot, rejectOp,
26649b403dc9c47ada51c8e5b883347682a868515f8Chris Craik                BakedOpState::StrokeBehavior::Forced, false);
267386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
268386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        ASSERT_NE(nullptr, bakedState);
269386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_EQ(Rect(45, 45, 155, 155), bakedState->computedState.clippedBounds);
270386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        EXPECT_EQ(0, bakedState->computedState.clipSideFlags);
271386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    }
272b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
273386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
274386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik} // namespace uirenderer
275386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik} // namespace android
276