Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Public Attributes | List of all members
SkSL::DebugTracePriv Class Reference

#include <SkSLDebugTracePriv.h>

Inheritance diagram for SkSL::DebugTracePriv:
SkSL::DebugTrace SkRefCnt SkRefCntBase

Public Member Functions

void setTraceCoord (const SkIPoint &coord)
 
void setSource (const std::string &source)
 
bool readTrace (SkStream *r)
 
void writeTrace (SkWStream *w) const override
 
void dump (SkWStream *o) const override
 
std::string getSlotComponentSuffix (int slotIndex) const
 
std::string getSlotValue (int slotIndex, int32_t value) const
 
double interpretValueBits (int slotIndex, int32_t valueBits) const
 
std::string slotValueToString (int slotIndex, double value) const
 
- Public Member Functions inherited from SkRefCntBase
 SkRefCntBase ()
 
virtual ~SkRefCntBase ()
 
bool unique () const
 
void ref () const
 
void unref () const
 

Public Attributes

SkIPoint fTraceCoord = {}
 
std::vector< SlotDebugInfofUniformInfo
 
std::vector< SlotDebugInfofSlotInfo
 
std::vector< FunctionDebugInfofFuncInfo
 
std::vector< TraceInfofTraceInfo
 
std::vector< std::string > fSource
 
std::unique_ptr< SkSL::TraceHookfTraceHook
 

Detailed Description

Definition at line 62 of file SkSLDebugTracePriv.h.

Member Function Documentation

◆ dump()

void SkSL::DebugTracePriv::dump ( SkWStream o) const
overridevirtual

Generates a human-readable dump of the debug trace.

Implements SkSL::DebugTrace.

Definition at line 103 of file SkSLDebugTracePriv.cpp.

103 {
104 for (size_t index = 0; index < fSlotInfo.size(); ++index) {
105 const SlotDebugInfo& info = fSlotInfo[index];
106
107 o->writeText("$");
108 o->writeDecAsText(index);
109 o->writeText(" = ");
110 o->writeText(info.name.c_str());
111 o->writeText(" (");
112 switch (info.numberKind) {
113 case Type::NumberKind::kFloat: o->writeText("float"); break;
114 case Type::NumberKind::kSigned: o->writeText("int"); break;
115 case Type::NumberKind::kUnsigned: o->writeText("uint"); break;
116 case Type::NumberKind::kBoolean: o->writeText("bool"); break;
117 case Type::NumberKind::kNonnumeric: o->writeText("???"); break;
118 }
119 if (info.rows * info.columns > 1) {
120 o->writeDecAsText(info.columns);
121 if (info.rows != 1) {
122 o->writeText("x");
123 o->writeDecAsText(info.rows);
124 }
125 o->writeText(" : ");
126 o->writeText("slot ");
127 o->writeDecAsText(info.componentIndex + 1);
128 o->writeText("/");
129 o->writeDecAsText(info.rows * info.columns);
130 }
131 o->writeText(", L");
132 o->writeDecAsText(info.line);
133 o->writeText(")");
134 o->newline();
135 }
136
137 for (size_t index = 0; index < fFuncInfo.size(); ++index) {
138 const FunctionDebugInfo& info = fFuncInfo[index];
139
140 o->writeText("F");
141 o->writeDecAsText(index);
142 o->writeText(" = ");
143 o->writeText(info.name.c_str());
144 o->newline();
145 }
146
147 o->newline();
148
149 if (!fTraceInfo.empty()) {
150 std::string indent = "";
151 for (const SkSL::TraceInfo& traceInfo : fTraceInfo) {
152 int data0 = traceInfo.data[0];
153 int data1 = traceInfo.data[1];
154 switch (traceInfo.op) {
155 case SkSL::TraceInfo::Op::kLine:
156 o->writeText(indent.c_str());
157 o->writeText("line ");
158 o->writeDecAsText(data0);
159 break;
160
161 case SkSL::TraceInfo::Op::kVar: {
162 const SlotDebugInfo& slot = fSlotInfo[data0];
163 o->writeText(indent.c_str());
164 o->writeText(slot.name.c_str());
165 o->writeText(this->getSlotComponentSuffix(data0).c_str());
166 o->writeText(" = ");
167 o->writeText(this->getSlotValue(data0, data1).c_str());
168 break;
169 }
170 case SkSL::TraceInfo::Op::kEnter:
171 o->writeText(indent.c_str());
172 o->writeText("enter ");
173 o->writeText(fFuncInfo[data0].name.c_str());
174 indent += " ";
175 break;
176
177 case SkSL::TraceInfo::Op::kExit:
178 indent.resize(indent.size() - 2);
179 o->writeText(indent.c_str());
180 o->writeText("exit ");
181 o->writeText(fFuncInfo[data0].name.c_str());
182 break;
183
184 case SkSL::TraceInfo::Op::kScope:
185 for (int delta = data0; delta < 0; ++delta) {
186 indent.pop_back();
187 }
188 o->writeText(indent.c_str());
189 o->writeText("scope ");
190 o->writeText((data0 >= 0) ? "+" : "");
191 o->writeDecAsText(data0);
192 for (int delta = data0; delta > 0; --delta) {
193 indent.push_back(' ');
194 }
195 break;
196 }
197 o->newline();
198 }
199 }
200}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
std::string getSlotValue(int slotIndex, int32_t value) const
std::vector< FunctionDebugInfo > fFuncInfo
std::vector< TraceInfo > fTraceInfo
std::vector< SlotDebugInfo > fSlotInfo
std::string getSlotComponentSuffix(int slotIndex) const
bool writeDecAsText(int32_t)
Definition SkStream.cpp:81
bool writeText(const char text[])
Definition SkStream.h:247
bool newline()
Definition SkStream.h:252
const char * name
Definition fuchsia.cc:50

◆ getSlotComponentSuffix()

std::string SkSL::DebugTracePriv::getSlotComponentSuffix ( int  slotIndex) const

Returns a slot's component as a variable-name suffix, e.g. ".x" or "[2][2]".

Definition at line 29 of file SkSLDebugTracePriv.cpp.

29 {
30 const SkSL::SlotDebugInfo& slot = fSlotInfo[slotIndex];
31
32 if (slot.rows > 1) {
33 return "[" + std::to_string(slot.componentIndex / slot.rows) +
34 "][" + std::to_string(slot.componentIndex % slot.rows) +
35 "]";
36 }
37 if (slot.columns > 1) {
38 switch (slot.componentIndex) {
39 case 0: return ".x";
40 case 1: return ".y";
41 case 2: return ".z";
42 case 3: return ".w";
43 default: return "[???]";
44 }
45 }
46 return {};
47}

◆ getSlotValue()

std::string SkSL::DebugTracePriv::getSlotValue ( int  slotIndex,
int32_t  value 
) const

Bit-casts a slot's value, then converts to text, e.g. "3.14" or "true" or "12345".

Definition at line 86 of file SkSLDebugTracePriv.cpp.

86 {
87 return this->slotValueToString(slotIndex, this->interpretValueBits(slotIndex, valueBits));
88}
double interpretValueBits(int slotIndex, int32_t valueBits) const
std::string slotValueToString(int slotIndex, double value) const

◆ interpretValueBits()

double SkSL::DebugTracePriv::interpretValueBits ( int  slotIndex,
int32_t  valueBits 
) const

Bit-casts a value for a given slot into a double, honoring the slot's NumberKind.

Definition at line 49 of file SkSLDebugTracePriv.cpp.

49 {
50 SkASSERT(slotIndex >= 0);
51 SkASSERT((size_t)slotIndex < fSlotInfo.size());
52 switch (fSlotInfo[slotIndex].numberKind) {
54 uint32_t uintValue;
55 static_assert(sizeof(uintValue) == sizeof(valueBits));
56 memcpy(&uintValue, &valueBits, sizeof(uintValue));
57 return uintValue;
58 }
60 float floatValue;
61 static_assert(sizeof(floatValue) == sizeof(valueBits));
62 memcpy(&floatValue, &valueBits, sizeof(floatValue));
63 return floatValue;
64 }
65 default: {
66 return valueBits;
67 }
68 }
69}
#define SkASSERT(cond)
Definition SkAssert.h:116

◆ readTrace()

bool SkSL::DebugTracePriv::readTrace ( SkStream r)

Serializes a debug trace to JSON which can be parsed by our debugger.

Definition at line 270 of file SkSLDebugTracePriv.cpp.

270 {
272 skjson::DOM json(reinterpret_cast<const char*>(data->bytes()), data->size());
273 const skjson::ObjectValue* root = json.root();
274 if (!root) {
275 return false;
276 }
277
278 const skjson::StringValue* version = (*root)["version"];
279 if (!version || version->str() != kTraceVersion) {
280 return false;
281 }
282
283 const skjson::ArrayValue* source = (*root)["source"];
284 if (!source) {
285 return false;
286 }
287
288 fSource.clear();
289 for (const skjson::StringValue* line : *source) {
290 if (!line) {
291 return false;
292 }
293 fSource.push_back(line->begin());
294 }
295
296 const skjson::ArrayValue* slots = (*root)["slots"];
297 if (!slots) {
298 return false;
299 }
300
301 fSlotInfo.clear();
302 for (const skjson::ObjectValue* element : *slots) {
303 if (!element) {
304 return false;
305 }
306
307 // Grow the slot array to hold this element.
308 fSlotInfo.push_back({});
309 SlotDebugInfo& info = fSlotInfo.back();
310
311 // Populate the SlotInfo with our JSON data.
312 const skjson::StringValue* name = (*element)["name"];
313 const skjson::NumberValue* columns = (*element)["columns"];
314 const skjson::NumberValue* rows = (*element)["rows"];
315 const skjson::NumberValue* index = (*element)["index"];
316 const skjson::NumberValue* groupIdx = (*element)["groupIdx"];
317 const skjson::NumberValue* kind = (*element)["kind"];
318 const skjson::NumberValue* line = (*element)["line"];
319 const skjson::NumberValue* retval = (*element)["retval"];
320 if (!name || !columns || !rows || !index || !kind || !line) {
321 return false;
322 }
323
324 info.name = name->begin();
325 info.columns = **columns;
326 info.rows = **rows;
327 info.componentIndex = **index;
328 info.groupIndex = groupIdx ? **groupIdx : info.componentIndex;
329 info.numberKind = (SkSL::Type::NumberKind)(int)**kind;
330 info.line = **line;
331 info.fnReturnValue = retval ? **retval : -1;
332 }
333
334 const skjson::ArrayValue* functions = (*root)["functions"];
335 if (!functions) {
336 return false;
337 }
338
339 fFuncInfo.clear();
340 for (const skjson::ObjectValue* element : *functions) {
341 if (!element) {
342 return false;
343 }
344
345 // Grow the function array to hold this element.
346 fFuncInfo.push_back({});
347 FunctionDebugInfo& info = fFuncInfo.back();
348
349 // Populate the FunctionInfo with our JSON data.
350 const skjson::StringValue* name = (*element)["name"];
351 if (!name) {
352 return false;
353 }
354
355 info.name = name->begin();
356 }
357
358 const skjson::ArrayValue* trace = (*root)["trace"];
359 if (!trace) {
360 return false;
361 }
362
363 fTraceInfo.clear();
364 fTraceInfo.reserve(trace->size());
365 for (const skjson::ArrayValue* element : *trace) {
366 fTraceInfo.push_back(TraceInfo{});
367 TraceInfo& info = fTraceInfo.back();
368
369 if (!element || element->size() < 1 || element->size() > (1 + std::size(info.data))) {
370 return false;
371 }
372 const skjson::NumberValue* opVal = (*element)[0];
373 if (!opVal) {
374 return false;
375 }
376 info.op = (TraceInfo::Op)(int)**opVal;
377 for (size_t elemIdx = 1; elemIdx < element->size(); ++elemIdx) {
378 const skjson::NumberValue* dataVal = (*element)[elemIdx];
379 if (!dataVal) {
380 return false;
381 }
382 info.data[elemIdx - 1] = **dataVal;
383 }
384 }
385
386 return true;
387}
static constexpr char kTraceVersion[]
sk_sp< SkData > SkCopyStreamToData(SkStream *stream)
Definition SkStream.cpp:937
std::vector< std::string > fSource
const char * begin() const
Definition SkJSON.h:315
size_t size() const
Definition SkJSON.h:262
SkBitmap source
Definition examples.cpp:28
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41

◆ setSource()

void SkSL::DebugTracePriv::setSource ( const std::string &  source)

Attaches the SkSL source to be debugged.

Definition at line 94 of file SkSLDebugTracePriv.cpp.

94 {
95 fSource.clear();
96 std::stringstream stream{source};
97 while (stream.good()) {
98 fSource.push_back({});
99 std::getline(stream, fSource.back(), '\n');
100 }
101}

◆ setTraceCoord()

void SkSL::DebugTracePriv::setTraceCoord ( const SkIPoint coord)

Sets the device-coordinate pixel to trace. If it's not set, the point at (0, 0) will be used.

Definition at line 90 of file SkSLDebugTracePriv.cpp.

90 {
91 fTraceCoord = coord;
92}

◆ slotValueToString()

std::string SkSL::DebugTracePriv::slotValueToString ( int  slotIndex,
double  value 
) const

Converts a numeric value into text, based on the slot's NumberKind.

Definition at line 71 of file SkSLDebugTracePriv.cpp.

71 {
72 SkASSERT(slotIndex >= 0);
73 SkASSERT((size_t)slotIndex < fSlotInfo.size());
74 switch (fSlotInfo[slotIndex].numberKind) {
76 return value ? "true" : "false";
77 }
78 default: {
79 char buffer[32];
80 snprintf(buffer, std::size(buffer), "%.8g", value);
81 return buffer;
82 }
83 }
84}
static const uint8_t buffer[]
uint8_t value

◆ writeTrace()

void SkSL::DebugTracePriv::writeTrace ( SkWStream w) const
overridevirtual

Serializes a debug trace to JSON which can be parsed by our debugger.

Implements SkSL::DebugTrace.

Definition at line 202 of file SkSLDebugTracePriv.cpp.

202 {
203 SkJSONWriter json(w);
204
205 json.beginObject(); // root
206 json.appendNString("version", kTraceVersion);
207 json.beginArray("source");
208
209 for (const std::string& line : fSource) {
210 json.appendString(line);
211 }
212
213 json.endArray(); // code
214 json.beginArray("slots");
215
216 for (size_t index = 0; index < fSlotInfo.size(); ++index) {
217 const SlotDebugInfo& info = fSlotInfo[index];
218
219 json.beginObject();
220 json.appendString("name", info.name.data(), info.name.size());
221 json.appendS32("columns", info.columns);
222 json.appendS32("rows", info.rows);
223 json.appendS32("index", info.componentIndex);
224 if (info.groupIndex != info.componentIndex) {
225 json.appendS32("groupIdx", info.groupIndex);
226 }
227 json.appendS32("kind", (int)info.numberKind);
228 json.appendS32("line", info.line);
229 if (info.fnReturnValue >= 0) {
230 json.appendS32("retval", info.fnReturnValue);
231 }
232 json.endObject();
233 }
234
235 json.endArray(); // slots
236 json.beginArray("functions");
237
238 for (size_t index = 0; index < fFuncInfo.size(); ++index) {
239 const FunctionDebugInfo& info = fFuncInfo[index];
240
241 json.beginObject();
242 json.appendString("name", info.name);
243 json.endObject();
244 }
245
246 json.endArray(); // functions
247 json.beginArray("trace");
248
249 for (size_t index = 0; index < fTraceInfo.size(); ++index) {
250 const TraceInfo& trace = fTraceInfo[index];
251 json.beginArray();
252 json.appendS32((int)trace.op);
253
254 // Skip trailing zeros in the data (since most ops only use one value).
255 int lastDataIdx = std::size(trace.data) - 1;
256 while (lastDataIdx >= 0 && !trace.data[lastDataIdx]) {
257 --lastDataIdx;
258 }
259 for (int dataIdx = 0; dataIdx <= lastDataIdx; ++dataIdx) {
260 json.appendS32(trace.data[dataIdx]);
261 }
262 json.endArray();
263 }
264
265 json.endArray(); // trace
266 json.endObject(); // root
267 json.flush();
268}
SkScalar w

Member Data Documentation

◆ fFuncInfo

std::vector<FunctionDebugInfo> SkSL::DebugTracePriv::fFuncInfo

Definition at line 99 of file SkSLDebugTracePriv.h.

◆ fSlotInfo

std::vector<SlotDebugInfo> SkSL::DebugTracePriv::fSlotInfo

A 1:1 mapping of slot numbers to debug information.

Definition at line 98 of file SkSLDebugTracePriv.h.

◆ fSource

std::vector<std::string> SkSL::DebugTracePriv::fSource

The SkSL code, split line-by-line.

Definition at line 105 of file SkSLDebugTracePriv.h.

◆ fTraceCoord

SkIPoint SkSL::DebugTracePriv::fTraceCoord = {}

The device-coordinate pixel to trace (controlled by setTraceCoord)

Definition at line 92 of file SkSLDebugTracePriv.h.

92{};

◆ fTraceHook

std::unique_ptr<SkSL::TraceHook> SkSL::DebugTracePriv::fTraceHook

A trace hook which populates fTraceInfo during shader evaluation. This will be created automatically during code generation.

Definition at line 111 of file SkSLDebugTracePriv.h.

◆ fTraceInfo

std::vector<TraceInfo> SkSL::DebugTracePriv::fTraceInfo

The SkSL debug trace.

Definition at line 102 of file SkSLDebugTracePriv.h.

◆ fUniformInfo

std::vector<SlotDebugInfo> SkSL::DebugTracePriv::fUniformInfo

SkRP stores uniform slot info in fUniformInfo. (In SkVM, they were mixed into fSlotInfo.)

Definition at line 95 of file SkSLDebugTracePriv.h.


The documentation for this class was generated from the following files: