Provide bit-casted slot values from DebugTracePlayer.
Previously, the VariableData returned from a DebugTracePlayer contained values in an int32_t, regardless of the slot's NumberKind. We had a helper function which could stringize the bits, but otherwise the caller was responsible for bit-casting the value manually. Now, the DebugTracePlayer will automatically manage bit-casting for the caller. The value returned in the VariableData is now a double (so it is able to store an int32, uint32, or float at full precision). This change was inspired by the recent Typescript port. (The value in the Typescript VariableData uses a compound `number | boolean` type, so it is able to fully represent any slot value natively.) Change-Id: I5eec414236f76ad0ff51b0b19974e4a0025c4d62 Bug: skia:12666 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/489896 Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
0ada61c87e
commit
d67f1f8f50
@ -24,42 +24,57 @@ std::string SkVMDebugTrace::getSlotComponentSuffix(int slotIndex) const {
|
||||
}
|
||||
if (slot.columns > 1) {
|
||||
switch (slot.componentIndex) {
|
||||
case 0: return ".x"; break;
|
||||
case 1: return ".y"; break;
|
||||
case 2: return ".z"; break;
|
||||
case 3: return ".w"; break;
|
||||
default: return "[???]"; break;
|
||||
case 0: return ".x";
|
||||
case 1: return ".y";
|
||||
case 2: return ".z";
|
||||
case 3: return ".w";
|
||||
default: return "[???]";
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string SkVMDebugTrace::getSlotValue(int slotIndex, int32_t value) const {
|
||||
const SkSL::SkVMSlotInfo& slot = fSlotInfo[slotIndex];
|
||||
switch (slot.numberKind) {
|
||||
case SkSL::Type::NumberKind::kBoolean:
|
||||
return value ? "true" : "false";
|
||||
|
||||
case SkSL::Type::NumberKind::kSigned:
|
||||
default:
|
||||
return std::to_string(value);
|
||||
|
||||
double SkVMDebugTrace::interpretValueBits(int slotIndex, int32_t valueBits) const {
|
||||
SkASSERT(slotIndex >= 0);
|
||||
SkASSERT((size_t)slotIndex < fSlotInfo.size());
|
||||
switch (fSlotInfo[slotIndex].numberKind) {
|
||||
case SkSL::Type::NumberKind::kUnsigned: {
|
||||
uint32_t unsignedVal;
|
||||
memcpy(&unsignedVal, &value, sizeof(unsignedVal));
|
||||
return std::to_string(unsignedVal);
|
||||
uint32_t uintValue;
|
||||
static_assert(sizeof(uintValue) == sizeof(valueBits));
|
||||
memcpy(&uintValue, &valueBits, sizeof(uintValue));
|
||||
return uintValue;
|
||||
}
|
||||
case SkSL::Type::NumberKind::kFloat: {
|
||||
float floatVal;
|
||||
static_assert(sizeof(floatVal) == sizeof(value));
|
||||
memcpy(&floatVal, &value, sizeof(floatVal));
|
||||
float floatValue;
|
||||
static_assert(sizeof(floatValue) == sizeof(valueBits));
|
||||
memcpy(&floatValue, &valueBits, sizeof(floatValue));
|
||||
return floatValue;
|
||||
}
|
||||
default: {
|
||||
return valueBits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string SkVMDebugTrace::slotValueToString(int slotIndex, double value) const {
|
||||
SkASSERT(slotIndex >= 0);
|
||||
SkASSERT((size_t)slotIndex < fSlotInfo.size());
|
||||
switch (fSlotInfo[slotIndex].numberKind) {
|
||||
case SkSL::Type::NumberKind::kBoolean: {
|
||||
return value ? "true" : "false";
|
||||
}
|
||||
default: {
|
||||
char buffer[32];
|
||||
snprintf(buffer, SK_ARRAY_COUNT(buffer), "%.8g", floatVal);
|
||||
snprintf(buffer, SK_ARRAY_COUNT(buffer), "%.8g", value);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string SkVMDebugTrace::getSlotValue(int slotIndex, int32_t valueBits) const {
|
||||
return this->slotValueToString(slotIndex, this->interpretValueBits(slotIndex, valueBits));
|
||||
}
|
||||
|
||||
void SkVMDebugTrace::setTraceCoord(const SkIPoint& coord) {
|
||||
fTraceCoord = coord;
|
||||
}
|
||||
|
@ -73,9 +73,15 @@ public:
|
||||
/** Returns a slot's component as a variable-name suffix, e.g. ".x" or "[2][2]". */
|
||||
std::string getSlotComponentSuffix(int slotIndex) const;
|
||||
|
||||
/** Returns a slot's value in human-readable form, e.g. "3.14" or "true" or "12345". */
|
||||
/** Bit-casts a slot's value, then converts to text, e.g. "3.14" or "true" or "12345". */
|
||||
std::string getSlotValue(int slotIndex, int32_t value) const;
|
||||
|
||||
/** Bit-casts a value for a given slot into a double, honoring the slot's NumberKind. */
|
||||
double interpretValueBits(int slotIndex, int32_t valueBits) const;
|
||||
|
||||
/** Converts a numeric value into text, based on the slot's NumberKind. */
|
||||
std::string slotValueToString(int slotIndex, double value) const;
|
||||
|
||||
/** The device-coordinate pixel to trace (controlled by setTraceCoord) */
|
||||
SkIPoint fTraceCoord = {};
|
||||
|
||||
|
@ -135,12 +135,13 @@ int SkVMDebugTracePlayer::getStackDepth() const {
|
||||
}
|
||||
|
||||
std::vector<SkVMDebugTracePlayer::VariableData> SkVMDebugTracePlayer::getVariablesForDisplayMask(
|
||||
const SkBitSet& bits) const {
|
||||
SkASSERT(bits.size() == fSlots.size());
|
||||
const SkBitSet& displayMask) const {
|
||||
SkASSERT(displayMask.size() == fSlots.size());
|
||||
|
||||
std::vector<VariableData> vars;
|
||||
bits.forEachSetIndex([&](int slot) {
|
||||
vars.push_back({slot, fDirtyMask->test(slot), fSlots[slot].fValue});
|
||||
displayMask.forEachSetIndex([&](int slot) {
|
||||
double typedValue = fDebugTrace->interpretValueBits(slot, fSlots[slot].fValue);
|
||||
vars.push_back({slot, fDirtyMask->test(slot), typedValue});
|
||||
});
|
||||
// Order the variable list so that the most recently-written variables are shown at the top.
|
||||
std::stable_sort(vars.begin(), vars.end(), [&](const VariableData& a, const VariableData& b) {
|
||||
|
@ -74,9 +74,9 @@ public:
|
||||
|
||||
/** Returns variables from a stack frame, or from global scope. */
|
||||
struct VariableData {
|
||||
int fSlotIndex;
|
||||
bool fDirty; // has this slot been written-to since the last step call?
|
||||
int32_t fValue; // caller must type-pun bits to float/bool based on slot type
|
||||
int fSlotIndex;
|
||||
bool fDirty; // has this slot been written-to since the last step call?
|
||||
double fValue; // value in slot (with type-conversion applied)
|
||||
};
|
||||
std::vector<VariableData> getLocalVariables(int stackFrameIndex) const;
|
||||
std::vector<VariableData> getGlobalVariables() const;
|
||||
|
@ -76,18 +76,15 @@ static std::string make_vars_string(
|
||||
text += slot.name;
|
||||
text += trace.getSlotComponentSuffix(var.fSlotIndex);
|
||||
text += " = ";
|
||||
text += trace.getSlotValue(var.fSlotIndex, var.fValue);
|
||||
text += trace.slotValueToString(var.fSlotIndex, var.fValue);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static std::string make_local_vars_string(const SkSL::SkVMDebugTrace& trace,
|
||||
const SkSL::SkVMDebugTracePlayer& player,
|
||||
int frame = -1) {
|
||||
if (frame == -1) {
|
||||
frame = player.getStackDepth() - 1;
|
||||
}
|
||||
const SkSL::SkVMDebugTracePlayer& player) {
|
||||
int frame = player.getStackDepth() - 1;
|
||||
return make_vars_string(trace, player.getLocalVariables(frame));
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,8 @@ void SkSLDebuggerSlide::showVariableTable() {
|
||||
ImGui::Text("%s%s", slotInfo.name.c_str(),
|
||||
fTrace->getSlotComponentSuffix(var.fSlotIndex).c_str());
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", fTrace->getSlotValue(var.fSlotIndex, var.fValue).c_str());
|
||||
ImGui::Text("%s",
|
||||
fTrace->slotValueToString(var.fSlotIndex, var.fValue).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user