Flutter Engine
The Flutter Engine
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
Definition: ShadowTest.cpp:29
@ kDo_ExpectVerts
Definition: ShadowTest.cpp:30

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);
189 ctm.postScale(2, 2);
191 ctm.preRotate(45);
193 ctm.preSkew(40, -20);
195 if (fixed_shadows_in_perspective) {
196 ctm[SkMatrix::kMPersp0] = 0.0001f;
197 ctm[SkMatrix::kMPersp1] = 12.f;
199 ctm[SkMatrix::kMPersp0] = 0.0001f;
200 ctm[SkMatrix::kMPersp1] = -12.f;
202 ctm[SkMatrix::kMPersp0] = 12.f;
203 ctm[SkMatrix::kMPersp1] = 0.0001f;
205 }
206}
reporter
Definition: FontMgrTest.cpp:39
void check_xformed_bounds(skiatest::Reporter *reporter, const SkPath &path, const SkMatrix &ctm)
Definition: ShadowTest.cpp:136
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
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

◆ 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
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;
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
Definition: SkShadowUtils.h:31
#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
Definition: SkMatrix.cpp:1141
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)
SkPoint3 fZPlaneParams
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
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165

◆ 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));
212
213 path.reset();
214 path.addOval(SkRect::MakeLTRB(300, 300, 900, 900));
216
217 path.reset();
218 path.cubicTo(100, 50, 20, 100, 0, 0);
220}
void check_bounds(skiatest::Reporter *reporter, const SkPath &path)
Definition: ShadowTest.cpp:183
Definition: SkPath.h:59
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.h:180
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)
Definition: ShadowTest.cpp:48
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)
Definition: ShadowTest.cpp:33