28#include <initializer_list>
69 static constexpr size_t kMax = 10;
71 result.appendf(
"Attributes (count=%zu, stride=%zu):\n", attributes.
size(), stride);
73 const auto&
a = attributes[
i];
76 if (kMax < attributes.
size()) {
80 result.appendf(
"Varyings (count=%zu):\n", varyings.
size());
82 const auto& v = varyings[
i];
85 if (kMax < varyings.
size()) {
89 result.appendf(
"\n--VS--\n%s\n------\n", vs.
c_str());
90 result.appendf(
"\n--FS--\n%s\n------\n", fs.
c_str());
100 const char* expectedErrorSubstring =
nullptr) {
104 "Expected to fail but succeeded:\n%s",
108 if (expectedErrorSubstring && !
error.contains(expectedErrorSubstring)) {
111 "Actual error: %s\n",
112 expectedErrorSubstring,
error.c_str());
129 *spec = std::move(
s);
134 "Expected to succeed but failed:\n%sError:\n%s",
142Varyings main(const Attributes attrs) {
149 SkString{
"float2 main(const Varyings varyings) { return float2(10); }"},
151 float2 main(const Varyings varyings, out half4 color) {
181 static constexpr const char* kVSBody =
"{ return float2(10); }";
183 static constexpr const char* kInvalidVSSigs[] {
184 "float3 main(const Attributes attrs)",
185 "Varyings main(Attributes attrs)",
186 "Varyings main(out Attributes attrs)",
188 "Varyings main(const Varyings v, float2)"
191 static constexpr const char* kNoColorFSBody =
"{ return float2(10); }";
193 static constexpr const char* kInvalidNoColorFSSigs[] {
194 "half2 main(const Varyings v)",
195 "float2 main(const Attributes v)",
196 "float2 main(inout Varyings attrs)",
197 "float2 main(Varyings v)",
199 "float2 main(const Varyings, float)"
202 static constexpr const char* kColorFSBody =
"{ color = half4(.2); return float2(10); }";
204 static constexpr const char* kInvalidColorFSSigs[] {
205 "half2 main(const Varyings v, out half4 color)",
206 "float2 main(const Attributes v, out half4 color)",
207 "float2 main(const Varyings v, out half3 color)",
208 "float2 main(out Varyings v, out half4 color)",
209 "float2 main(const Varyings v, half4 color)",
210 "float2 main(const Varyings v, out half4 color, float)"
213 for (
const char* vsSig : kInvalidVSSigs) {
215 invalidVS.
appendf(
"%s %s", vsSig, kVSBody);
228 for (
const char* noColorFSSig : kInvalidNoColorFSSigs) {
230 invalidFS.
appendf(
"%s %s", noColorFSSig, kNoColorFSBody);
241 for (
const char* colorFSSig : kInvalidColorFSSigs) {
243 invalidFS.
appendf(
"%s %s", colorFSSig, kColorFSBody);
259 float2 main(const Varyings varyings, out float4 color) {
260 color = float4(.2); return float2(10);
273 static constexpr const char* kChildEffects[] {
274 "uniform shader myshader;",
275 "uniform colorFilter mycolorfilter;",
276 "uniform blender myblender;"
279 for (
const auto& global : kChildEffects) {
292 "effects are not permitted in mesh vertex shaders")) {
302 "effects are not permitted in mesh vertex shaders")) {
309 static constexpr const char* kChildEffects[] {
310 "uniform shader myshader;",
311 "uniform colorFilter mycolorfilter; uniform shader myshader;",
312 "uniform shader myshader; uniform blender myblender; uniform colorFilter mycolorfilter;"
315 for (
const auto& global : kChildEffects) {
331 SkString fsWithChild{
"uniform shader myshader;"
332 "uniform blender myblender;"
333 "uniform colorFilter mycolorfilter;"};
356 const char* expectedError =
nullptr) {
386 result.error.contains(expectedError),
388 " Actual: '%s'\n", expectedError,
result.error.c_str());
393 "Expected: no errors\n"
394 " Actual: '%s'\n",
result.error.c_str());
404 test(
"uniform shader myshader;", {},
405 "The mesh specification declares 1 child effects, but the mesh supplies 0.");
406 test(
"", childShader,
407 "The mesh specification declares 0 child effects, but the mesh supplies 1.");
410 test(
"uniform shader myshader;", childFilter,
411 "Child effect 'myshader' was specified as a shader, but passed as a color filter.");
412 test(
"uniform shader myshader;", childBlender,
413 "Child effect 'myshader' was specified as a shader, but passed as a blender.");
414 test(
"uniform colorFilter myfilter;", childShader,
415 "Child effect 'myfilter' was specified as a color filter, but passed as a shader.");
416 test(
"uniform colorFilter myfilter;", childBlender,
417 "Child effect 'myfilter' was specified as a color filter, but passed as a blender.");
418 test(
"uniform blender myblender;", childShader,
419 "Child effect 'myblender' was specified as a blender, but passed as a shader.");
420 test(
"uniform blender myblender;", childFilter,
421 "Child effect 'myblender' was specified as a blender, but passed as a color filter.");
424 test(
"uniform shader myshader;", childNull);
425 test(
"uniform shader myfilter;", childNull);
426 test(
"uniform shader myblender;", childNull);
429 test(
"uniform shader myshader;", childShader);
430 test(
"uniform colorFilter myfilter;", childFilter);
431 test(
"uniform blender myblender;", childBlender);
446 std::string_view
name,
461 const std::vector<const char*> vsUniformDecls;
462 const std::vector<const char*> fsUniformDecls;
463 const std::vector<SkMeshSpecification::Uniform> expectations;
464 }
static kTestCases[] {
472 make_uni(Type::kFloat,
"x", 0, kVS)
483 make_uni(Type::kFloat2,
"v", 0, kFS)
490 "layout(color) uniform float4 color;",
493 "layout(color) uniform float4 color;",
496 make_uni(Type::kFloat4,
"color", 0, kVS|kFS|
kColor)
503 "layout(color) uniform float4 color;",
504 " uniform float x[5];",
507 "uniform float x[5];",
510 make_uni(Type::kFloat4,
"color", 0, kVS|
kColor, 0),
511 make_uni(Type::kFloat ,
"x" , 16, kVS|kFS , 5)
518 "uniform half x[2];",
522 "uniform half x[2];",
525 make_uni(Type::kFloat,
"x", 0, kVS|kFS|kHalfP, 2),
526 make_uni(Type::kInt,
"y", 8, kVS , 0)
533 "uniform float3x3 m;",
537 "uniform float3x3 m;",
540 make_uni(Type::kFloat3x3,
"m" , 0, kVS|kFS),
541 make_uni(Type::kInt2 ,
"i2", 36, kFS )
548 "uniform half4x4 m[4];",
551 "uniform half4x4 m[4];",
552 "uniform int3 i3[1];",
555 make_uni(Type::kFloat4x4,
"m", 0, kVS|kFS|kHalfP, 4),
556 make_uni(Type::kInt3,
"i3", 256, kFS , 1)
564 "uniform half4x4 m[4];",
565 "uniform int2 i2[2];"
566 "uniform float3 v[8];"
571 "uniform float3 v[8];"
572 "uniform int4 i4[2];"
573 "uniform half4x4 m[4];",
577 make_uni(Type::kFloat,
"x" , 0, kVS , 0),
578 make_uni(Type::kFloat4x4,
"m" , 4, kVS|kFS|kHalfP, 4),
579 make_uni(Type::kInt2,
"i2", 260, kVS , 2),
580 make_uni(Type::kFloat3,
"v" , 276, kVS|kFS , 8),
581 make_uni(Type::kInt3,
"i3", 372, kVS , 0),
582 make_uni(Type::kFloat,
"y" , 384, kFS , 0),
583 make_uni(Type::kInt4,
"i4", 388, kFS , 2),
584 make_uni(Type::kInt,
"i" , 420, kFS , 0),
589 for (
const auto& c : kTestCases) {
592 for (
const auto u : c.vsUniformDecls) {
599 for (
const auto u : c.fsUniformDecls) {
612 if (uniforms.
size() != c.expectations.size()) {
614 "Expected %zu uniforms but actually %zu:\n%s",
615 c.expectations.size(),
620 for (
const auto& [actual, expected] :
SkMakeZip(uniforms, c.expectations)) {
621 std::string
name = std::string(actual.name);
622 if (
name != expected.name) {
624 "Actual uniform name (%s) does not match expected name (%.*s)",
626 (
int)expected.name.size(), expected.name.data());
629 if (actual.type != expected.type) {
631 "Uniform %s: Actual type (%d) does not match expected type (%d)",
633 static_cast<int>(actual.type),
634 static_cast<int>(expected.type));
637 if (actual.count != expected.count) {
639 "Uniform %s: Actual count (%d) does not match expected count (%d)",
645 if (actual.flags != expected.flags) {
647 "Uniform %s: Actual flags (0x%04x) do not match expected flags (0x%04x)",
653 if (actual.offset != expected.offset) {
655 "Uniform %s: Actual offset (%zu) does not match expected offset (%zu)",
672 static std::tuple<const char*, const char*> kTestCases[]{
674 {
"uniform float x;",
"uniform int x;"},
676 {
"uniform float2x2 m[1];",
"uniform float2x2 m;"},
678 {
"uniform int3 i[1];",
"uniform int3 i[2];"},
680 {
"layout(color) uniform float4 color;",
"uniform float4 color;"},
683 for (
bool reverse : {
false,
true}) {
684 for (
auto [u1, u2] : kTestCases) {
705 static const SkString kHelper{
"float2 swiz(float2 x) { return z.yx; }"};
844 static constexpr size_t kN = 500;
845 std::vector<Attribute> attrs;
847 for (
size_t i = 0;
i < kN; ++
i) {
859 static constexpr size_t kN = 500;
860 std::vector<Varying> varyings;
861 varyings.reserve(kN);
862 for (
size_t i = 0;
i < kN; ++
i) {
887 static const Varying kVaryings[] {
899static constexpr const char*
kSneakyName =
"name; float3 sneaky";
914 static const Varying kVaryings[] {
927 static const Varying kVaryings[] {
940 static const Varying kVaryings[] {
964 static const Varying kVaryings[] {
981 static const Varying kVaryings[]{
987 static constexpr char kVS[] = R
"(
988 Varyings main(const Attributes a) {
991 v.position = a.position;
996 auto check = [&] (
const char* fs,
const char* passthroughAttr) {
1008 if (!passthroughAttr) {
1010 ERRORF(
reporter,
"Expected no passthrough coords attribute, found %s.\n%s",
1014 }
else if (!actualAttr.
equals(passthroughAttr)) {
1015 ERRORF(
reporter,
"Expected %s as passthrough coords attribute, found %s.\n%s",
1023 check(R
"(float2 main(const Varyings v) {
1029 check(R
"(float2 main(const Varyings v) {
1035 check(R
"(float2 main(const Varyings v, out half4 color) {
1042 check(R
"(uniform int selector;
1044 float2 main(const Varyings v, out half4 color) {
1045 if (selector == 0) {
1046 color = half4(1, 0, 0, 1);
1049 if (selector == 1) {
1050 color = half4(1, 1, 0, 1);
1053 color = half4(1, 0, 1, 1);
1059 check(R
"(uniform int selector;
1061 float2 main(const Varyings v, out half4 color) {
1062 if (selector == 0) {
1066 if (selector == 1) {
1076 check(R
"(float2 main(const Varyings v) {
1082 check(R
"(noinline half4 get_color(const Varyings v) { return v.color; }
1084 float2 main(const Varyings v, out half4 color) {
1085 color = get_color(v);
1097 static const Varying kVaryings[]{
1103 static constexpr char kVS[] = R
"(
1104 Varyings main(const Attributes a) {
1107 v.position = a.position;
1113 auto check = [&](
const char* fs,
bool positionDead,
bool uvDead,
bool colorDead) {
1114 static_assert(
std::size(kVaryings) == 3);
1127 auto str = [](
bool dead) {
return dead ?
"dead" :
"not dead"; };
1128 if (positionActuallyDead != positionDead) {
1130 "Expected position to be detected %s but it is detected %s.\n%s",
1132 str(positionActuallyDead),
1135 if (uvActuallyDead != uvDead) {
1137 "Expected uv to be detected %s but it is detected %s.\n%s",
1139 str(uvActuallyDead),
1142 if (colorActuallyDead != colorDead) {
1144 "Expected color to be detected %s but it is detected %s.\n%s",
1146 str(colorActuallyDead),
1152 check(R
"(float2 main(const Varyings v) {
1160 check(R
"(float2 main(const Varyings v) {
1168 check(R
"(float2 main(const Varyings v, out half4 color) {
1169 if (v.color.r > 0.5) {
1182 check(R
"(float2 main(const Varyings v, out half4 color) {
1183 if (v.position.x > 10) {
1196 check(R
"(float2 main(const Varyings v, out half4 color) {
1197 color = half4(v.uv.x, 0, 0, 1);
1205 check(R
"(float2 main(const Varyings v) {
1206 return v.uv + v.position;
1213 check(R
"(noinline vec2 get_pos(const Varyings v) { return v.position; }
1215 noinline half4 identity(half4 c) { return c; }
1217 float2 main(const Varyings v, out half4 color) {
1218 color = identity(v.color);
1219 return v.uv + get_pos(v);
1226 check(R
"(float2 main(const Varyings v) {
1227 Varyings otherVaryings;
1229 return otherVaryings.uv;
1237 check(R
"(float2 main(const Varyings v) {
1238 Varyings otherVaryings;
1239 otherVaryings.uv = half2(5);
1240 otherVaryings.position = half2(10);
1241 return otherVaryings.position;
static constexpr SkColor kColor
static const size_t kVertexCount
DEF_TEST(MeshSpec_Valid, reporter)
SkMeshSpecification::Attribute Attribute
static const char * attr_type_str(const Attribute::Type type)
static const Attribute kValidAttrs[]
static const SkString kValidFSes[]
static bool check_for_success(skiatest::Reporter *reporter, SkSpan< const Attribute > attributes, size_t stride, SkSpan< const Varying > varyings, const SkString &vs, const SkString &fs, sk_sp< SkMeshSpecification > *spec=nullptr)
static const SkString kValidVS
SkMeshSpecification::Varying Varying
static constexpr const char * kSneakyName
static bool check_for_failure(skiatest::Reporter *reporter, SkSpan< const Attribute > attributes, size_t stride, SkSpan< const Varying > varyings, const SkString &vs, const SkString &fs, const char *expectedErrorSubstring=nullptr)
static SkString make_description(SkSpan< const Attribute > attributes, size_t stride, SkSpan< const Varying > varyings, const SkString &vs, const SkString &fs)
static const char * var_type_str(const Varying::Type type)
static const Varying kValidVaryings[]
static constexpr size_t kValidStride
#define check(reporter, ref, unref, make, kill)
@ kSrcOver
r = s + (1-sa)*d
constexpr SkColor SK_ColorBLACK
void swap(sk_sp< T > &a, sk_sp< T > &b)
SkSpan(Container &&) -> SkSpan< std::remove_pointer_t< decltype(std::data(std::declval< Container >()))> >
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
constexpr auto SkMakeZip(Ts &&... ts)
#define REPORTER_ASSERT(r, cond,...)
static sk_sp< SkBlender > Mode(SkBlendMode mode)
static sk_sp< SkColorFilter > LinearToSRGBGamma()
SkSpan< const Uniform > uniforms() const
static Result Make(SkSpan< const Attribute > attributes, size_t vertexStride, SkSpan< const Varying > varyings, const SkString &vs, const SkString &fs)
SkSpan< const Attribute > attributes() const
SkRuntimeEffect::Uniform Uniform
const Child * findChild(std::string_view name) const
static Result Make(sk_sp< SkMeshSpecification >, Mode, sk_sp< VertexBuffer >, size_t vertexCount, size_t vertexOffset, sk_sp< const SkData > uniforms, SkSpan< ChildPtr > children, const SkRect &bounds)
constexpr size_t size() const
bool equals(const SkString &) const
void append(const char text[])
void prepend(const char text[])
const char * c_str() const
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
FlutterSemanticsFlag flags
const uint8_t uint32_t uint32_t GError ** error
static float max(float r, float g, float b)
static float min(float r, float g, float b)
SK_API sk_sp< SkMesh::VertexBuffer > MakeVertexBuffer(const void *, size_t size)
SK_API sk_sp< SkShader > Color(SkColor)
DEF_SWITCHES_START aot vmservice shared library name
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
static const std::map< std::string, VerticesBuilder::AttributeType > kAttributes
static int PassthroughLocalCoordsVaryingIndex(const SkMeshSpecification &spec)
static bool VaryingIsDead(const SkMeshSpecification &spec, int v)
static constexpr SkRect MakeEmpty()