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