Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Enumerations | Functions
ShadowTest.cpp File Reference
#include "include/core/SkCanvas.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint.h"
#include "include/core/SkPoint3.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/core/SkVertices.h"
#include "include/private/base/SkTo.h"
#include "include/utils/SkShadowUtils.h"
#include "src/core/SkDrawShadowInfo.h"
#include "src/core/SkVerticesPriv.h"
#include "src/utils/SkShadowTessellator.h"
#include "tests/Test.h"

Go to the source code of this file.

Enumerations

enum  ExpectVerts { kDont_ExpectVerts , kDo_ExpectVerts }
 

Functions

void check_result (skiatest::Reporter *reporter, sk_sp< SkVertices > verts, ExpectVerts expectVerts, bool expectSuccess)
 
void tessellate_shadow (skiatest::Reporter *reporter, const SkPath &path, const SkMatrix &ctm, const SkPoint3 &heightParams, ExpectVerts expectVerts, bool expectSuccess)
 
 DEF_TEST (ShadowUtils, reporter)
 
void check_xformed_bounds (skiatest::Reporter *reporter, const SkPath &path, const SkMatrix &ctm)
 
void check_bounds (skiatest::Reporter *reporter, const SkPath &path)
 
 DEF_TEST (ShadowBounds, reporter)
 

Enumeration Type Documentation

◆ ExpectVerts

Enumerator
kDont_ExpectVerts 
kDo_ExpectVerts 

Definition at line 28 of file ShadowTest.cpp.

28 {
31};
@ kDont_ExpectVerts
@ kDo_ExpectVerts

Function Documentation

◆ check_bounds()

void check_bounds ( skiatest::Reporter reporter,
const SkPath path 
)

Definition at line 183 of file ShadowTest.cpp.

183 {
184 const bool fixed_shadows_in_perspective = false; // skbug.com/9698
185
186 SkMatrix ctm;
187 ctm.setTranslate(100, 100);
188 check_xformed_bounds(reporter, path, ctm);
189 ctm.postScale(2, 2);
190 check_xformed_bounds(reporter, path, ctm);
191 ctm.preRotate(45);
192 check_xformed_bounds(reporter, path, ctm);
193 ctm.preSkew(40, -20);
194 check_xformed_bounds(reporter, path, ctm);
195 if (fixed_shadows_in_perspective) {
196 ctm[SkMatrix::kMPersp0] = 0.0001f;
197 ctm[SkMatrix::kMPersp1] = 12.f;
198 check_xformed_bounds(reporter, path, ctm);
199 ctm[SkMatrix::kMPersp0] = 0.0001f;
200 ctm[SkMatrix::kMPersp1] = -12.f;
201 check_xformed_bounds(reporter, path, ctm);
202 ctm[SkMatrix::kMPersp0] = 12.f;
203 ctm[SkMatrix::kMPersp1] = 0.0001f;
204 check_xformed_bounds(reporter, path, ctm);
205 }
206}
reporter
void check_xformed_bounds(skiatest::Reporter *reporter, const SkPath &path, const SkMatrix &ctm)
SkMatrix & preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:512
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:360
static constexpr int kMPersp1
input y perspective factor
Definition SkMatrix.h:360
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
Definition SkMatrix.cpp:254
static constexpr int kMPersp0
input x perspective factor
Definition SkMatrix.h:359
SkMatrix & preRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:462

◆ check_result()

void check_result ( skiatest::Reporter reporter,
sk_sp< SkVertices verts,
ExpectVerts  expectVerts,
bool  expectSuccess 
)

Definition at line 33 of file ShadowTest.cpp.

34 {
35 if (expectSuccess != SkToBool(verts)) {
36 ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
37 expectSuccess ? "succeed" : "fail");
38 }
39 if (SkToBool(verts)) {
40 if (kDont_ExpectVerts == expectVerts && verts->priv().vertexCount()) {
41 ERRORF(reporter, "Expected shadow tessellation to generate no vertices but it did.");
42 } else if (kDo_ExpectVerts == expectVerts && !verts->priv().vertexCount()) {
43 ERRORF(reporter, "Expected shadow tessellation to generate vertices but it didn't.");
44 }
45 }
46}
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
#define ERRORF(r,...)
Definition Test.h:293
int vertexCount() const
SkVerticesPriv priv()

◆ check_xformed_bounds()

void check_xformed_bounds ( skiatest::Reporter reporter,
const SkPath path,
const SkMatrix ctm 
)

Definition at line 136 of file ShadowTest.cpp.

136 {
137 SkDrawShadowRec rec = {
138 SkPoint3::Make(0, 0, 4),
139 SkPoint3::Make(100, 0, 600),
140 800.f,
141 0x08000000,
142 0x40000000,
143 0
144 };
145 // point light
147 SkDrawShadowMetrics::GetLocalBounds(path, rec, ctm, &bounds);
148 ctm.mapRect(&bounds);
149
150 auto verts = SkShadowTessellator::MakeAmbient(path, ctm, rec.fZPlaneParams, true);
151 if (verts) {
152 REPORTER_ASSERT(reporter, bounds.contains(verts->bounds()));
153 }
154
155 SkPoint mapXY = ctm.mapXY(rec.fLightPos.fX, rec.fLightPos.fY);
156 SkPoint3 devLightPos = SkPoint3::Make(mapXY.fX, mapXY.fY, rec.fLightPos.fZ);
157 verts = SkShadowTessellator::MakeSpot(path, ctm, rec.fZPlaneParams, devLightPos,
158 rec.fLightRadius, false, false);
159 if (verts) {
160 REPORTER_ASSERT(reporter, bounds.contains(verts->bounds()));
161 }
162
163 // directional light
165 rec.fLightRadius = 2.0f;
166 SkDrawShadowMetrics::GetLocalBounds(path, rec, ctm, &bounds);
167 ctm.mapRect(&bounds);
168
169 verts = SkShadowTessellator::MakeAmbient(path, ctm, rec.fZPlaneParams, true);
170 if (verts) {
171 REPORTER_ASSERT(reporter, bounds.contains(verts->bounds()));
172 }
173
174 devLightPos = rec.fLightPos;
175 devLightPos.normalize();
176 verts = SkShadowTessellator::MakeSpot(path, ctm, rec.fZPlaneParams, devLightPos,
177 rec.fLightRadius, false, true);
178 if (verts) {
179 REPORTER_ASSERT(reporter, bounds.contains(verts->bounds()));
180 }
181}
@ kDirectionalLight_ShadowFlag
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
void mapXY(SkScalar x, SkScalar y, SkPoint *result) const
Definition SkMatrix.cpp:777
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
void GetLocalBounds(const SkPath &path, const SkDrawShadowRec &rec, const SkMatrix &ctm, SkRect *bounds)
Optional< SkRect > bounds
Definition SkRecords.h:189
sk_sp< SkVertices > MakeAmbient(const SkPath &path, const SkMatrix &ctm, const SkPoint3 &zPlane, bool transparent)
sk_sp< SkVertices > MakeSpot(const SkPath &path, const SkMatrix &ctm, const SkPoint3 &zPlane, const SkPoint3 &lightPos, SkScalar lightRadius, bool transparent, bool directional)
SkScalar fX
Definition SkPoint3.h:16
static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z)
Definition SkPoint3.h:18
SkScalar fZ
Definition SkPoint3.h:16
bool normalize()
Definition SkPoint3.cpp:49
SkScalar fY
Definition SkPoint3.h:16
float fX
x-axis value
float fY
y-axis value

◆ DEF_TEST() [1/2]

DEF_TEST ( ShadowBounds  ,
reporter   
)

Definition at line 208 of file ShadowTest.cpp.

208 {
209 SkPath path;
210 path.addRRect(SkRRect::MakeRectXY(SkRect::MakeLTRB(-50, -20, 40, 30), 4, 4));
211 check_bounds(reporter, path);
212
213 path.reset();
214 path.addOval(SkRect::MakeLTRB(300, 300, 900, 900));
215 check_bounds(reporter, path);
216
217 path.reset();
218 path.cubicTo(100, 50, 20, 100, 0, 0);
219 check_bounds(reporter, path);
220}
void check_bounds(skiatest::Reporter *reporter, const SkPath &path)
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition SkRRect.h:180
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition SkRect.h:646

◆ DEF_TEST() [2/2]

DEF_TEST ( ShadowUtils  ,
reporter   
)

Definition at line 71 of file ShadowTest.cpp.

71 {
72 SkCanvas canvas(100, 100);
73
75 path.cubicTo(100, 50, 20, 100, 0, 0);
76 tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 4}, kDo_ExpectVerts, true);
77 // super high path
78 tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 4.0e+37f},
79 kDo_ExpectVerts, true);
80
81 // This line segment has no area and no shadow.
82 path.reset();
83 path.lineTo(10.f, 10.f);
84 tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 4}, kDont_ExpectVerts, true);
85
86 // A series of collinear line segments
87 path.reset();
88 for (int i = 0; i < 10; ++i) {
89 path.lineTo((SkScalar)i, (SkScalar)i);
90 }
91 tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 4}, kDont_ExpectVerts, true);
92
93 // ugly degenerate path
94 path.reset();
95 path.moveTo(-134217728, 2.22265153e+21f);
96 path.cubicTo(-2.33326106e+21f, 7.36298265e-41f, 3.72237738e-22f, 5.99502692e-36f,
97 1.13631943e+22f, 2.0890786e+33f);
98 path.cubicTo(1.03397626e-25f, 5.99502692e-36f, 9.18354962e-41f, 0, 4.6142745e-37f, -213558848);
99 path.lineTo(-134217728, 2.2226515e+21f);
100 tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 9}, kDont_ExpectVerts, true);
101
102 // simple concave path (star of David)
103 path.reset();
104 path.moveTo(0.0f, -50.0f);
105 path.lineTo(14.43f, -25.0f);
106 path.lineTo(43.30f, -25.0f);
107 path.lineTo(28.86f, 0.0f);
108 path.lineTo(43.30f, 25.0f);
109 path.lineTo(14.43f, 25.0f);
110 path.lineTo(0.0f, 50.0f);
111 path.lineTo(-14.43f, 25.0f);
112 path.lineTo(-43.30f, 25.0f);
113 path.lineTo(-28.86f, 0.0f);
114 path.lineTo(-43.30f, -25.0f);
115 path.lineTo(-14.43f, -25.0f);
116// uncomment when transparent concave shadows are working
117// tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 9}, kDo_ExpectVerts, true);
118
119 // complex concave path (bowtie)
120 path.reset();
121 path.moveTo(-50, -50);
122 path.lineTo(-50, 50);
123 path.lineTo(50, -50);
124 path.lineTo(50, 50);
125 path.lineTo(-50, -50);
126 tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 9}, kDont_ExpectVerts, false);
127
128 // multiple contour path
129 path.close();
130 path.moveTo(0, 0);
131 path.lineTo(1, 0);
132 path.lineTo(0, 1);
133 tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 9}, kDont_ExpectVerts, false);
134}
void tessellate_shadow(skiatest::Reporter *reporter, const SkPath &path, const SkMatrix &ctm, const SkPoint3 &heightParams, ExpectVerts expectVerts, bool expectSuccess)
float SkScalar
Definition extension.cpp:12

◆ tessellate_shadow()

void tessellate_shadow ( skiatest::Reporter reporter,
const SkPath path,
const SkMatrix ctm,
const SkPoint3 heightParams,
ExpectVerts  expectVerts,
bool  expectSuccess 
)

Definition at line 48 of file ShadowTest.cpp.

49 {
50
51 auto verts = SkShadowTessellator::MakeAmbient(path, ctm, heightParams, true);
52 check_result(reporter, verts, expectVerts, expectSuccess);
53
54 verts = SkShadowTessellator::MakeAmbient(path, ctm, heightParams, false);
55 check_result(reporter, verts, expectVerts, expectSuccess);
56
57 verts = SkShadowTessellator::MakeSpot(path, ctm, heightParams, {0, 0, 128}, 128.f, true, false);
58 check_result(reporter, verts, expectVerts, expectSuccess);
59
60 verts = SkShadowTessellator::MakeSpot(path, ctm, heightParams, {0, 0, 128}, 128.f, false,
61 false);
62 check_result(reporter, verts, expectVerts, expectSuccess);
63
64 verts = SkShadowTessellator::MakeSpot(path, ctm, heightParams, {0, 0, 128}, 128.f, true, true);
65 check_result(reporter, verts, expectVerts, expectSuccess);
66
67 verts = SkShadowTessellator::MakeSpot(path, ctm, heightParams, {0, 0, 128}, 128.f, false, true);
68 check_result(reporter, verts, expectVerts, expectSuccess);
69}
void check_result(skiatest::Reporter *reporter, sk_sp< SkVertices > verts, ExpectVerts expectVerts, bool expectSuccess)