1 /*
2 * Copyright 2021 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "include/core/SkStream.h"
9 #include "src/sksl/tracing/SkVMDebugTrace.h"
10 #include "tests/Test.h"
11
DEF_TEST(SkVMDebugTraceSetSource,r)12 DEF_TEST(SkVMDebugTraceSetSource, r) {
13 SkSL::SkVMDebugTrace i;
14 i.setSource("SkVMDebugTrace::setSource unit test\n"
15 "\t// first line\n"
16 "\t// second line\n"
17 "\t// third line");
18
19 REPORTER_ASSERT(r, i.fSource.size() == 4);
20 REPORTER_ASSERT(r, i.fSource[0] == "SkVMDebugTrace::setSource unit test");
21 REPORTER_ASSERT(r, i.fSource[1] == "\t// first line");
22 REPORTER_ASSERT(r, i.fSource[2] == "\t// second line");
23 REPORTER_ASSERT(r, i.fSource[3] == "\t// third line");
24 }
25
DEF_TEST(SkVMDebugTraceSetSourceReplacesExistingText,r)26 DEF_TEST(SkVMDebugTraceSetSourceReplacesExistingText, r) {
27 SkSL::SkVMDebugTrace i;
28 i.setSource("One");
29 i.setSource("Two");
30 i.setSource("Three");
31
32 REPORTER_ASSERT(r, i.fSource.size() == 1);
33 REPORTER_ASSERT(r, i.fSource[0] == "Three");
34 }
35
DEF_TEST(SkVMDebugTraceWrite,r)36 DEF_TEST(SkVMDebugTraceWrite, r) {
37 SkSL::SkVMDebugTrace i;
38 i.fSource = {
39 "\t// first line",
40 "// \"second line\"",
41 "//\\\\//\\\\ third line",
42 };
43 i.fSlotInfo = {
44 {"SkVM_DebugTrace", 1, 2, 3, 4, (SkSL::Type::NumberKind)5, 6, -1},
45 {"Unit_Test", 6, 7, 8, 8, (SkSL::Type::NumberKind)10, 11, 12},
46 };
47 i.fFuncInfo = {
48 {"void testFunc();"},
49 };
50 i.fTraceInfo = {
51 {SkSL::SkVMTraceInfo::Op::kEnter, {0, 0}},
52 {SkSL::SkVMTraceInfo::Op::kLine, {5, 0}},
53 {SkSL::SkVMTraceInfo::Op::kVar, {10, 15}},
54 {SkSL::SkVMTraceInfo::Op::kExit, {20, 0}},
55 };
56 SkDynamicMemoryWStream wstream;
57 i.writeTrace(&wstream);
58 sk_sp<SkData> trace = wstream.detachAsData();
59
60 static constexpr char kExpected[] =
61 R"({"version":"20220209","source":["\t// first line","// \"second line\"","//\\\\//\\)"
62 R"(\\ third line"],"slots":[{"name":"SkVM_DebugTrace","columns":1,"rows":2,"index":3,)"
63 R"("groupIdx":4,"kind":5,"line":6},{"name":"Unit_Test","columns":6,"rows":7,"index":8)"
64 R"(,"kind":10,"line":11,"retval":12}],"functions":[{"name":"void testFunc();"}],"trac)"
65 R"(e":[[2],[0,5],[1,10,15],[3,20]]})";
66
67 std::string_view actual{reinterpret_cast<const char*>(trace->bytes()), trace->size()};
68
69 REPORTER_ASSERT(r, actual == kExpected,
70 "Expected:\n %s\n\n Actual:\n %.*s\n",
71 kExpected, (int)actual.size(), actual.data());
72 }
73
DEF_TEST(SkVMDebugTraceRead,r)74 DEF_TEST(SkVMDebugTraceRead, r) {
75 const std::string_view kJSONTrace =
76 R"({"version":"20220209","source":["\t// first line","// \"second line\"","//\\\\//\\)"
77 R"(\\ third line"],"slots":[{"name":"SkVM_DebugTrace","columns":1,"rows":2,"index":3,)"
78 R"("groupIdx":4,"kind":5,"line":6},{"name":"Unit_Test","columns":6,"rows":7,"index":8)"
79 R"(,"kind":10,"line":11,"retval":12}],"functions":[{"name":"void testFunc();"}],"trac)"
80 R"(e":[[2],[0,5],[1,10,15],[3,20]]})";
81
82 SkMemoryStream stream(kJSONTrace.data(), kJSONTrace.size(), /*copyData=*/false);
83 SkSL::SkVMDebugTrace i;
84 REPORTER_ASSERT(r, i.readTrace(&stream));
85
86 REPORTER_ASSERT(r, i.fSource.size() == 3);
87 REPORTER_ASSERT(r, i.fSlotInfo.size() == 2);
88 REPORTER_ASSERT(r, i.fFuncInfo.size() == 1);
89 REPORTER_ASSERT(r, i.fTraceInfo.size() == 4);
90
91 REPORTER_ASSERT(r, i.fSource[0] == "\t// first line");
92 REPORTER_ASSERT(r, i.fSource[1] == "// \"second line\"");
93 REPORTER_ASSERT(r, i.fSource[2] == "//\\\\//\\\\ third line");
94
95 REPORTER_ASSERT(r, i.fSlotInfo[0].name == "SkVM_DebugTrace");
96 REPORTER_ASSERT(r, i.fSlotInfo[0].columns == 1);
97 REPORTER_ASSERT(r, i.fSlotInfo[0].rows == 2);
98 REPORTER_ASSERT(r, i.fSlotInfo[0].componentIndex == 3);
99 REPORTER_ASSERT(r, i.fSlotInfo[0].groupIndex == 4);
100 REPORTER_ASSERT(r, i.fSlotInfo[0].numberKind == (SkSL::Type::NumberKind)5);
101 REPORTER_ASSERT(r, i.fSlotInfo[0].line == 6);
102 REPORTER_ASSERT(r, i.fSlotInfo[0].fnReturnValue == -1);
103
104 REPORTER_ASSERT(r, i.fSlotInfo[1].name == "Unit_Test");
105 REPORTER_ASSERT(r, i.fSlotInfo[1].columns == 6);
106 REPORTER_ASSERT(r, i.fSlotInfo[1].rows == 7);
107 REPORTER_ASSERT(r, i.fSlotInfo[1].componentIndex == 8);
108 REPORTER_ASSERT(r, i.fSlotInfo[1].groupIndex == 8);
109 REPORTER_ASSERT(r, i.fSlotInfo[1].numberKind == (SkSL::Type::NumberKind)10);
110 REPORTER_ASSERT(r, i.fSlotInfo[1].line == 11);
111 REPORTER_ASSERT(r, i.fSlotInfo[1].fnReturnValue == 12);
112
113 REPORTER_ASSERT(r, i.fFuncInfo[0].name == "void testFunc();");
114
115 REPORTER_ASSERT(r, i.fTraceInfo[0].op == SkSL::SkVMTraceInfo::Op::kEnter);
116 REPORTER_ASSERT(r, i.fTraceInfo[0].data[0] == 0);
117 REPORTER_ASSERT(r, i.fTraceInfo[0].data[1] == 0);
118
119 REPORTER_ASSERT(r, i.fTraceInfo[1].op == SkSL::SkVMTraceInfo::Op::kLine);
120 REPORTER_ASSERT(r, i.fTraceInfo[1].data[0] == 5);
121 REPORTER_ASSERT(r, i.fTraceInfo[1].data[1] == 0);
122
123 REPORTER_ASSERT(r, i.fTraceInfo[2].op == SkSL::SkVMTraceInfo::Op::kVar);
124 REPORTER_ASSERT(r, i.fTraceInfo[2].data[0] == 10);
125 REPORTER_ASSERT(r, i.fTraceInfo[2].data[1] == 15);
126
127 REPORTER_ASSERT(r, i.fTraceInfo[3].op == SkSL::SkVMTraceInfo::Op::kExit);
128 REPORTER_ASSERT(r, i.fTraceInfo[3].data[0] == 20);
129 REPORTER_ASSERT(r, i.fTraceInfo[3].data[1] == 0);
130 }
131
DEF_TEST(SkVMDebugTraceGetSlotComponentSuffix,r)132 DEF_TEST(SkVMDebugTraceGetSlotComponentSuffix, r) {
133 // SkVMSlotInfo fields:
134 // - name
135 // - columns
136 // - rows
137 // - componentIndex
138 // - numberKind
139 // - line
140 // - fnReturnValue
141
142 SkSL::SkVMDebugTrace i;
143 i.fSlotInfo = {{"s", 1, 1, 0, 0, SkSL::Type::NumberKind::kFloat, 0, -1},
144 {"v", 4, 1, 0, 0, SkSL::Type::NumberKind::kFloat, 0, -1},
145 {"v", 4, 1, 1, 1, SkSL::Type::NumberKind::kFloat, 0, -1},
146 {"v", 4, 1, 2, 2, SkSL::Type::NumberKind::kFloat, 0, -1},
147 {"v", 4, 1, 3, 3, SkSL::Type::NumberKind::kFloat, 0, -1},
148 {"m", 4, 4, 0, 0, SkSL::Type::NumberKind::kFloat, 0, -1},
149 {"m", 4, 4, 1, 1, SkSL::Type::NumberKind::kFloat, 0, -1},
150 {"m", 4, 4, 2, 2, SkSL::Type::NumberKind::kFloat, 0, -1},
151 {"m", 4, 4, 3, 3, SkSL::Type::NumberKind::kFloat, 0, -1},
152 {"m", 4, 4, 4, 4, SkSL::Type::NumberKind::kFloat, 0, -1},
153 {"m", 4, 4, 5, 5, SkSL::Type::NumberKind::kFloat, 0, -1},
154 {"m", 4, 4, 6, 6, SkSL::Type::NumberKind::kFloat, 0, -1},
155 {"m", 4, 4, 7, 7, SkSL::Type::NumberKind::kFloat, 0, -1},
156 {"m", 4, 4, 8, 8, SkSL::Type::NumberKind::kFloat, 0, -1},
157 {"m", 4, 4, 9, 9, SkSL::Type::NumberKind::kFloat, 0, -1},
158 {"m", 4, 4, 10, 10, SkSL::Type::NumberKind::kFloat, 0, -1},
159 {"m", 4, 4, 11, 11, SkSL::Type::NumberKind::kFloat, 0, -1},
160 {"m", 4, 4, 12, 12, SkSL::Type::NumberKind::kFloat, 0, -1},
161 {"m", 4, 4, 13, 13, SkSL::Type::NumberKind::kFloat, 0, -1},
162 {"m", 4, 4, 14, 14, SkSL::Type::NumberKind::kFloat, 0, -1},
163 {"m", 4, 4, 15, 15, SkSL::Type::NumberKind::kFloat, 0, -1}};
164
165 const std::string kExpected[] = {"",
166 ".x", ".y", ".z", ".w",
167 "[0][0]", "[0][1]", "[0][2]", "[0][3]",
168 "[1][0]", "[1][1]", "[1][2]", "[1][3]",
169 "[2][0]", "[2][1]", "[2][2]", "[2][3]",
170 "[3][0]", "[3][1]", "[3][2]", "[3][3]"};
171
172 REPORTER_ASSERT(r, i.fSlotInfo.size() == SK_ARRAY_COUNT(kExpected));
173 for (size_t index = 0; index < SK_ARRAY_COUNT(kExpected); ++index) {
174 REPORTER_ASSERT(r, kExpected[index] == i.getSlotComponentSuffix(index));
175 }
176 }
177