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 #ifndef SKSLDEBUGTRACEPRIV 9 #define SKSLDEBUGTRACEPRIV 10 11 #include "include/core/SkPoint.h" 12 #include "include/sksl/SkSLDebugTrace.h" 13 #include "src/sksl/SkSLPosition.h" 14 #include "src/sksl/ir/SkSLType.h" 15 #include "src/sksl/tracing/SkSLTraceHook.h" 16 17 #include <cstdint> 18 #include <memory> 19 #include <string> 20 #include <vector> 21 22 class SkStream; 23 class SkWStream; 24 25 namespace SkSL { 26 27 struct TraceInfo { 28 enum class Op { 29 kLine, /** data: line number, (unused) */ 30 kVar, /** data: slot, value */ 31 kEnter, /** data: function index, (unused) */ 32 kExit, /** data: function index, (unused) */ 33 kScope, /** data: scope delta, (unused) */ 34 }; 35 Op op; 36 int32_t data[2]; 37 }; 38 39 struct SlotDebugInfo { 40 /** The full name of this variable (without component), e.g. `myArray[3].myStruct.myVector` */ 41 std::string name; 42 /** The dimensions of this variable: 1x1 is a scalar, Nx1 is a vector, NxM is a matrix. */ 43 uint8_t columns = 1, rows = 1; 44 /** Which component of the variable is this slot? (e.g. `vec4.z` is component 2) */ 45 uint8_t componentIndex = 0; 46 /** Complex types (arrays/structs) can be tracked as a "group" of adjacent slots. */ 47 int groupIndex = 0; 48 /** What kind of numbers belong in this slot? */ 49 SkSL::Type::NumberKind numberKind = SkSL::Type::NumberKind::kNonnumeric; 50 /** Where is this variable located in the program? */ 51 int line = 0; 52 Position pos = {}; 53 /** If this slot holds a function's return value, contains 1; if not, -1. */ 54 int fnReturnValue = -1; 55 }; 56 57 struct FunctionDebugInfo { 58 /** Full function declaration: `float myFunction(half4 color)`) */ 59 std::string name; 60 }; 61 62 class DebugTracePriv : public DebugTrace { 63 public: 64 /** 65 * Sets the device-coordinate pixel to trace. If it's not set, the point at (0, 0) will be used. 66 */ 67 void setTraceCoord(const SkIPoint& coord); 68 69 /** Attaches the SkSL source to be debugged. */ 70 void setSource(const std::string& source); 71 72 /** Serializes a debug trace to JSON which can be parsed by our debugger. */ 73 bool readTrace(SkStream* r); 74 void writeTrace(SkWStream* w) const override; 75 76 /** Generates a human-readable dump of the debug trace. */ 77 void dump(SkWStream* o) const override; 78 79 /** Returns a slot's component as a variable-name suffix, e.g. ".x" or "[2][2]". */ 80 std::string getSlotComponentSuffix(int slotIndex) const; 81 82 /** Bit-casts a slot's value, then converts to text, e.g. "3.14" or "true" or "12345". */ 83 std::string getSlotValue(int slotIndex, int32_t value) const; 84 85 /** Bit-casts a value for a given slot into a double, honoring the slot's NumberKind. */ 86 double interpretValueBits(int slotIndex, int32_t valueBits) const; 87 88 /** Converts a numeric value into text, based on the slot's NumberKind. */ 89 std::string slotValueToString(int slotIndex, double value) const; 90 91 /** The device-coordinate pixel to trace (controlled by setTraceCoord) */ 92 SkIPoint fTraceCoord = {}; 93 94 /** SkRP stores uniform slot info in fUniformInfo. (In SkVM, they were mixed into fSlotInfo.) */ 95 std::vector<SlotDebugInfo> fUniformInfo; 96 97 /** A 1:1 mapping of slot numbers to debug information. */ 98 std::vector<SlotDebugInfo> fSlotInfo; 99 std::vector<FunctionDebugInfo> fFuncInfo; 100 101 /** The SkSL debug trace. */ 102 std::vector<TraceInfo> fTraceInfo; 103 104 /** The SkSL code, split line-by-line. */ 105 std::vector<std::string> fSource; 106 107 /** 108 * A trace hook which populates fTraceInfo during shader evaluation. This will be created 109 * automatically during code generation. 110 */ 111 std::unique_ptr<SkSL::TraceHook> fTraceHook; 112 }; 113 114 } // namespace SkSL 115 116 #endif 117