Create a public base class for debug traces.

SkRuntimeEffect needs an API for generating debug traces. This means
that we will need references to debug traces inside a public header.
Rather than reference SkVMDebugInfo directly, we now have a simpler
base class for debug traces. This is better suited to landing in
include/.

I've also renamed SkVMDebugInfo to SkVMDebugTrace for consistency, since
it now contains all the trace data. (When it was first added, it only
had the slot info.)

Change-Id: Ibaa4dedf9a17b9462b4f233a28a7b875d0317892
Bug: skia:12708
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/480356
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2021-12-06 12:02:20 -05:00 committed by SkCQ
parent dec95f24e1
commit dfc7f31bd1
12 changed files with 132 additions and 102 deletions

View File

@ -31,6 +31,7 @@ skia_sksl_sources = [
"$_include/sksl/DSLSymbols.h",
"$_include/sksl/DSLType.h",
"$_include/sksl/DSLVar.h",
"$_include/sksl/SkSLDebugTrace.h",
"$_include/sksl/SkSLErrorReporter.h",
"$_src/sksl/SkSLAnalysis.cpp",
"$_src/sksl/SkSLAnalysis.h",
@ -87,8 +88,8 @@ skia_sksl_sources = [
"$_src/sksl/analysis/SkSLSwitchCaseContainsExit.cpp",
"$_src/sksl/codegen/SkSLVMCodeGenerator.cpp",
"$_src/sksl/codegen/SkSLVMCodeGenerator.h",
"$_src/sksl/codegen/SkVMDebugInfo.cpp",
"$_src/sksl/codegen/SkVMDebugInfo.h",
"$_src/sksl/codegen/SkVMDebugTrace.cpp",
"$_src/sksl/codegen/SkVMDebugTrace.h",
"$_src/sksl/dsl/DSLBlock.cpp",
"$_src/sksl/dsl/DSLCase.cpp",
"$_src/sksl/dsl/DSLCore.cpp",

View File

@ -259,7 +259,7 @@ tests_sources = [
"$_tests/SkTBlockListTest.cpp",
"$_tests/SkTOptionalTest.cpp",
"$_tests/SkUTFTest.cpp",
"$_tests/SkVMDebugInfoTest.cpp",
"$_tests/SkVMDebugTraceTest.cpp",
"$_tests/SkVMTest.cpp",
"$_tests/SkVxTest.cpp",
"$_tests/Skbug12214.cpp",

View File

@ -0,0 +1,28 @@
/*
* Copyright 2021 Google LLC.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SKSL_DEBUG_TRACE
#define SKSL_DEBUG_TRACE
class SkWStream;
namespace SkSL {
class DebugTrace {
public:
virtual ~DebugTrace() = default;
/** Serializes a debug trace to JSON which can be parsed by our debugger. */
virtual void writeTrace(SkWStream* w) const = 0;
/** Generates a human-readable dump of the debug trace. */
virtual void dump(SkWStream* o) const = 0;
};
} // namespace SkSL
#endif

View File

@ -186,7 +186,7 @@ void SkParticleEffectParams::prepare(const skresources::ResourceProvider* resour
for (int i = 0; i < uniformInfo->fUniformSlotCount; ++i) {
uniformIDs.push_back(b.uniform32(skslUniformPtr, i * sizeof(int)).id);
}
if (!SkSL::ProgramToSkVM(*program, *fn, &b, /*debugInfo=*/nullptr,
if (!SkSL::ProgramToSkVM(*program, *fn, &b, /*debugTrace=*/nullptr,
SkMakeSpan(uniformIDs))) {
return skvm::Program{};
}

View File

@ -649,7 +649,7 @@ std::unique_ptr<SkFilterColorProgram> SkFilterColorProgram::Make(const SkRuntime
skvm::Color result = SkSL::ProgramToSkVM(*effect->fBaseProgram,
effect->fMain,
&p,
/*debugInfo=*/nullptr,
/*debugTrace=*/nullptr,
SkMakeSpan(uniform),
/*device=*/zeroCoord,
/*local=*/zeroCoord,
@ -885,7 +885,7 @@ public:
// There should be no way for the color filter to use device coords, but we need to supply
// something. (Uninitialized values can trigger asserts in skvm::Builder).
skvm::Coord zeroCoord = { p->splat(0.0f), p->splat(0.0f) };
return SkSL::ProgramToSkVM(*fEffect->fBaseProgram, fEffect->fMain, p, /*debugInfo=*/nullptr,
return SkSL::ProgramToSkVM(*fEffect->fBaseProgram, fEffect->fMain, p,/*debugTrace=*/nullptr,
SkMakeSpan(uniform), /*device=*/zeroCoord, /*local=*/zeroCoord,
c, c, sampleShader, sampleColorFilter, sampleBlender);
}
@ -1048,7 +1048,7 @@ public:
std::vector<skvm::Val> uniform = make_skvm_uniforms(p, uniforms, fEffect->uniformSize(),
*inputs);
return SkSL::ProgramToSkVM(*fEffect->fBaseProgram, fEffect->fMain, p, /*debugInfo=*/nullptr,
return SkSL::ProgramToSkVM(*fEffect->fBaseProgram, fEffect->fMain, p,/*debugTrace=*/nullptr,
SkMakeSpan(uniform), device, local, paint, paint, sampleShader,
sampleColorFilter, sampleBlender);
}
@ -1160,7 +1160,7 @@ public:
// Emit the blend function as an SkVM program.
skvm::Coord zeroCoord = {p->splat(0.0f), p->splat(0.0f)};
return SkSL::ProgramToSkVM(*fEffect->fBaseProgram, fEffect->fMain, p, /*debugInfo=*/nullptr,
return SkSL::ProgramToSkVM(*fEffect->fBaseProgram, fEffect->fMain, p,/*debugTrace=*/nullptr,
SkMakeSpan(uniform), /*device=*/zeroCoord, /*local=*/zeroCoord,
src, dst, sampleShader, sampleColorFilter, sampleBlender);
}

View File

@ -18,7 +18,7 @@
#include "src/sksl/SkSLUtil.h"
#include "src/sksl/codegen/SkSLPipelineStageCodeGenerator.h"
#include "src/sksl/codegen/SkSLVMCodeGenerator.h"
#include "src/sksl/codegen/SkVMDebugInfo.h"
#include "src/sksl/codegen/SkVMDebugTrace.h"
#include "src/sksl/ir/SkSLUnresolvedFunction.h"
#include "src/sksl/ir/SkSLVarDeclarations.h"
@ -94,7 +94,7 @@ static SkSL::String base_name(const SkSL::String& fpPath, const char* prefix, co
static bool detect_shader_settings(const SkSL::String& text,
SkSL::Program::Settings* settings,
const SkSL::ShaderCaps** caps,
std::unique_ptr<SkSL::SkVMDebugInfo>* debugInfo) {
std::unique_ptr<SkSL::SkVMDebugTrace>* debugTrace) {
using Factory = SkSL::ShaderCapsFactory;
// Find a matching comment and isolate the name portion.
@ -222,7 +222,7 @@ static bool detect_shader_settings(const SkSL::String& text,
}
if (settingsText.consumeSuffix(" SkVMDebugTrace")) {
settings->fOptimize = false;
*debugInfo = std::make_unique<SkSL::SkVMDebugInfo>();
*debugTrace = std::make_unique<SkSL::SkVMDebugTrace>();
}
if (settingsText.empty()) {
@ -302,9 +302,9 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
SkSL::Program::Settings settings;
auto standaloneCaps = SkSL::ShaderCapsFactory::Standalone();
const SkSL::ShaderCaps* caps = standaloneCaps.get();
std::unique_ptr<SkSL::SkVMDebugInfo> debugInfo;
std::unique_ptr<SkSL::SkVMDebugTrace> debugTrace;
if (honorSettings) {
if (!detect_shader_settings(text, &settings, &caps, &debugInfo)) {
if (!detect_shader_settings(text, &settings, &caps, &debugTrace)) {
return ResultCode::kInputError;
}
}
@ -399,13 +399,13 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
[&](SkSL::Compiler&, SkSL::Program& program, SkSL::OutputStream& out) {
skvm::Builder builder{skvm::Features{}};
if (!SkSL::testingOnly_ProgramToSkVMShader(program, &builder,
debugInfo.get())) {
debugTrace.get())) {
return false;
}
std::unique_ptr<SkWStream> redirect = as_SkWStream(out);
if (debugInfo) {
debugInfo->dump(redirect.get());
if (debugTrace) {
debugTrace->dump(redirect.get());
}
builder.done().dump(redirect.get());
return true;

View File

@ -13,7 +13,7 @@
#include "src/sksl/SkSLOperators.h"
#include "src/sksl/codegen/SkSLCodeGenerator.h"
#include "src/sksl/codegen/SkSLVMCodeGenerator.h"
#include "src/sksl/codegen/SkVMDebugInfo.h"
#include "src/sksl/codegen/SkVMDebugTrace.h"
#include "src/sksl/ir/SkSLBinaryExpression.h"
#include "src/sksl/ir/SkSLBlock.h"
#include "src/sksl/ir/SkSLBreakStatement.h"
@ -60,31 +60,31 @@ namespace {
class SkSLTracer : public skvm::TraceHook {
public:
static std::unique_ptr<SkSLTracer> Make(SkSL::SkVMDebugInfo* debugInfo) {
static std::unique_ptr<SkSLTracer> Make(SkSL::SkVMDebugTrace* trace) {
auto hook = std::make_unique<SkSLTracer>();
hook->fDebugInfo = debugInfo;
hook->fTrace = trace;
return hook;
}
void line(int lineNum) override {
fDebugInfo->fTraceInfo.push_back({SkSL::SkVMTraceInfo::Op::kLine,
fTrace->fTraceInfo.push_back({SkSL::SkVMTraceInfo::Op::kLine,
/*data=*/{lineNum, 0}});
}
void var(int slot, int32_t val) override {
fDebugInfo->fTraceInfo.push_back({SkSL::SkVMTraceInfo::Op::kVar,
/*data=*/{slot, val}});
fTrace->fTraceInfo.push_back({SkSL::SkVMTraceInfo::Op::kVar,
/*data=*/{slot, val}});
}
void enter(int fnIdx) override {
fDebugInfo->fTraceInfo.push_back({SkSL::SkVMTraceInfo::Op::kEnter,
/*data=*/{fnIdx, 0}});
fTrace->fTraceInfo.push_back({SkSL::SkVMTraceInfo::Op::kEnter,
/*data=*/{fnIdx, 0}});
}
void exit(int fnIdx) override {
fDebugInfo->fTraceInfo.push_back({SkSL::SkVMTraceInfo::Op::kExit,
/*data=*/{fnIdx, 0}});
fTrace->fTraceInfo.push_back({SkSL::SkVMTraceInfo::Op::kExit,
/*data=*/{fnIdx, 0}});
}
private:
SkSL::SkVMDebugInfo* fDebugInfo;
SkSL::SkVMDebugTrace* fTrace;
};
}
@ -146,7 +146,7 @@ class SkVMGenerator {
public:
SkVMGenerator(const Program& program,
skvm::Builder* builder,
SkVMDebugInfo* debugInfo,
SkVMDebugTrace* debugTrace,
SampleShaderFn sampleShader,
SampleColorFilterFn sampleColorFilter,
SampleBlenderFn sampleBlender);
@ -181,12 +181,12 @@ private:
Value getSlotValue(size_t slot, size_t nslots);
/**
* Returns the slot index of this function inside the SkVMFunctionInfo array in SkVMDebugInfo.
* Returns the slot index of this function inside the SkVMFunctionInfo array in SkVMDebugTrace.
* The SkVMFunctionInfo slot will be created if it doesn't already exist.
*/
int getDebugFunctionInfo(const FunctionDeclaration& decl);
/** Used by `createSlot` to add this variable to the SkVMSlotInfo array inside SkVMDebugInfo. */
/** Used by `createSlot` to add this variable to the SkVMSlotInfo array inside SkVMDebugTrace.*/
void addDebugSlotInfo(String varName, const Type& type, int line);
/** Used by `getSlot` to create a new slot on its first access. */
@ -297,7 +297,7 @@ private:
//
const Program& fProgram;
skvm::Builder* fBuilder;
SkVMDebugInfo* fDebugInfo;
SkVMDebugTrace* fDebugTrace;
int fTraceHookID = -1;
const SampleShaderFn fSampleShader;
@ -366,13 +366,13 @@ static inline bool is_uniform(const SkSL::Variable& var) {
SkVMGenerator::SkVMGenerator(const Program& program,
skvm::Builder* builder,
SkVMDebugInfo* debugInfo,
SkVMDebugTrace* debugTrace,
SampleShaderFn sampleShader,
SampleColorFilterFn sampleColorFilter,
SampleBlenderFn sampleBlender)
: fProgram(program)
, fBuilder(builder)
, fDebugInfo(debugInfo)
, fDebugTrace(debugTrace)
, fSampleShader(std::move(sampleShader))
, fSampleColorFilter(std::move(sampleColorFilter))
, fSampleBlender(std::move(sampleBlender)) {}
@ -395,18 +395,18 @@ void SkVMGenerator::writeProgram(SkSpan<skvm::Val> uniforms,
}
void SkVMGenerator::setupGlobals(SkSpan<skvm::Val> uniforms, skvm::Coord device) {
if (fDebugInfo) {
if (fDebugTrace) {
// Copy the program source into the debug info so that it will be written in the trace file.
fDebugInfo->setSource(*fProgram.fSource);
fDebugTrace->setSource(*fProgram.fSource);
// Create a trace hook and attach it to the builder.
fDebugInfo->fTraceHook = SkSLTracer::Make(fDebugInfo);
fTraceHookID = fBuilder->attachTraceHook(fDebugInfo->fTraceHook.get());
fDebugTrace->fTraceHook = SkSLTracer::Make(fDebugTrace);
fTraceHookID = fBuilder->attachTraceHook(fDebugTrace->fTraceHook.get());
// The SkVM blitter generates centered pixel coordinates. (0.5, 1.5, 2.5, 3.5, etc.)
// Add 0.5 to the requested trace coordinate to match this.
skvm::Coord traceCoord = {to_F32(fBuilder->splat(fDebugInfo->fTraceCoord.fX)) + 0.5f,
to_F32(fBuilder->splat(fDebugInfo->fTraceCoord.fY)) + 0.5f};
skvm::Coord traceCoord = {to_F32(fBuilder->splat(fDebugTrace->fTraceCoord.fX)) + 0.5f,
to_F32(fBuilder->splat(fDebugTrace->fTraceCoord.fY)) + 0.5f};
// If we are debugging, we need to create a trace mask. This will be true when the current
// device coordinates match the requested trace coordinates. We calculate each mask
@ -492,20 +492,20 @@ Value SkVMGenerator::getSlotValue(size_t slot, size_t nslots) {
}
int SkVMGenerator::getDebugFunctionInfo(const FunctionDeclaration& decl) {
SkASSERT(fDebugInfo);
SkASSERT(fDebugTrace);
std::string name = decl.description();
// Look for a matching SkVMFunctionInfo slot.
for (size_t index = 0; index < fDebugInfo->fFuncInfo.size(); ++index) {
if (fDebugInfo->fFuncInfo[index].name == name) {
for (size_t index = 0; index < fDebugTrace->fFuncInfo.size(); ++index) {
if (fDebugTrace->fFuncInfo[index].name == name) {
return index;
}
}
// We've never called this function before; create a new slot to hold its information.
int slot = (int)fDebugInfo->fFuncInfo.size();
fDebugInfo->fFuncInfo.push_back(SkVMFunctionInfo{std::move(name)});
int slot = (int)fDebugTrace->fFuncInfo.size();
fDebugTrace->fFuncInfo.push_back(SkVMFunctionInfo{std::move(name)});
return slot;
}
@ -514,7 +514,7 @@ size_t SkVMGenerator::writeFunction(const FunctionDefinition& function,
const FunctionDeclaration& decl = function.declaration();
int funcIndex = -1;
if (fDebugInfo) {
if (fDebugTrace) {
funcIndex = this->getDebugFunctionInfo(decl);
fBuilder->trace_enter(fTraceHookID, this->mask(), fTraceMask, funcIndex);
}
@ -555,7 +555,7 @@ size_t SkVMGenerator::writeFunction(const FunctionDefinition& function,
fFunctionStack.pop_back();
if (fDebugInfo) {
if (fDebugTrace) {
fBuilder->trace_exit(fTraceHookID, this->mask(), fTraceMask, funcIndex);
}
@ -563,7 +563,7 @@ size_t SkVMGenerator::writeFunction(const FunctionDefinition& function,
}
void SkVMGenerator::writeToSlot(int slot, skvm::Val value) {
if (fDebugInfo && (!fSlots[slot].writtenTo || fSlots[slot].val != value)) {
if (fDebugTrace && (!fSlots[slot].writtenTo || fSlots[slot].val != value)) {
if (fProgram.fConfig->fSettings.fAllowTraceVarInSkVMDebugTrace) {
fBuilder->trace_var(fTraceHookID, this->mask(), fTraceMask, slot, i32(value));
}
@ -574,7 +574,7 @@ void SkVMGenerator::writeToSlot(int slot, skvm::Val value) {
}
void SkVMGenerator::addDebugSlotInfo(String varName, const Type& type, int line) {
SkASSERT(fDebugInfo);
SkASSERT(fDebugTrace);
switch (type.typeKind()) {
case Type::TypeKind::kArray: {
int nslots = type.columns();
@ -612,7 +612,7 @@ void SkVMGenerator::addDebugSlotInfo(String varName, const Type& type, int line)
slotInfo.componentIndex = slot;
slotInfo.numberKind = numberKind;
slotInfo.line = line;
fDebugInfo->fSlotInfo.push_back(std::move(slotInfo));
fDebugTrace->fSlotInfo.push_back(std::move(slotInfo));
}
break;
}
@ -623,16 +623,16 @@ size_t SkVMGenerator::createSlot(const String& name, const Type& type, int line)
size_t slot = fSlots.size(),
nslots = type.slotCount();
if (fDebugInfo) {
if (fDebugTrace) {
// Our debug slot-info table should always have the same length as the actual slot table.
SkASSERT(fDebugInfo->fSlotInfo.size() == slot);
SkASSERT(fDebugTrace->fSlotInfo.size() == slot);
// Append slot names and types to our debug slot-info table.
fDebugInfo->fSlotInfo.reserve(slot + nslots);
fDebugTrace->fSlotInfo.reserve(slot + nslots);
this->addDebugSlotInfo(name, type, line);
// Confirm that we added the expected number of slots.
SkASSERT(fDebugInfo->fSlotInfo.size() == (slot + nslots));
SkASSERT(fDebugTrace->fSlotInfo.size() == (slot + nslots));
}
// Create brand new slots initialized to zero.
@ -1841,7 +1841,7 @@ void SkVMGenerator::writeVarDeclaration(const VarDeclaration& decl) {
}
void SkVMGenerator::emitTraceLine(int line) {
if (fDebugInfo && line > 0) {
if (fDebugTrace && line > 0) {
fBuilder->trace_line(fTraceHookID, this->mask(), fTraceMask, line);
}
}
@ -1893,7 +1893,7 @@ void SkVMGenerator::writeStatement(const Statement& s) {
skvm::Color ProgramToSkVM(const Program& program,
const FunctionDefinition& function,
skvm::Builder* builder,
SkVMDebugInfo* debugInfo,
SkVMDebugTrace* debugTrace,
SkSpan<skvm::Val> uniforms,
skvm::Coord device,
skvm::Coord local,
@ -1938,7 +1938,7 @@ skvm::Color ProgramToSkVM(const Program& program,
}
SkASSERT(argSlots <= SK_ARRAY_COUNT(args));
SkVMGenerator generator(program, builder, debugInfo, std::move(sampleShader),
SkVMGenerator generator(program, builder, debugTrace, std::move(sampleShader),
std::move(sampleColorFilter), std::move(sampleBlender));
generator.writeProgram(uniforms, device, function, {args, argSlots}, SkMakeSpan(result));
@ -1951,7 +1951,7 @@ skvm::Color ProgramToSkVM(const Program& program,
bool ProgramToSkVM(const Program& program,
const FunctionDefinition& function,
skvm::Builder* b,
SkVMDebugInfo* debugInfo,
SkVMDebugTrace* debugTrace,
SkSpan<skvm::Val> uniforms,
SkVMSignature* outSignature) {
SkVMSignature ignored,
@ -1998,7 +1998,7 @@ bool ProgramToSkVM(const Program& program,
skvm::Coord device = {pixelCenter, pixelCenter};
device.x += to_F32(b->splat(1) - b->index());
SkVMGenerator generator(program, b, debugInfo, sampleShader, sampleColorFilter, sampleBlender);
SkVMGenerator generator(program, b, debugTrace, sampleShader, sampleColorFilter, sampleBlender);
generator.writeProgram(uniforms, device, function, SkMakeSpan(argVals), SkMakeSpan(returnVals));
// If the SkSL tried to use any shader, colorFilter, or blender objects - we don't have a
@ -2085,7 +2085,7 @@ std::unique_ptr<UniformInfo> Program_GetUniformInfo(const Program& program) {
*/
bool testingOnly_ProgramToSkVMShader(const Program& program,
skvm::Builder* builder,
SkVMDebugInfo* debugInfo) {
SkVMDebugTrace* debugTrace) {
const SkSL::FunctionDefinition* main = Program_GetFunction(program, "main");
if (!main) {
return false;
@ -2138,7 +2138,7 @@ bool testingOnly_ProgramToSkVMShader(const Program& program,
skvm::Color inColor = builder->uniformColor(SkColors::kWhite, &uniforms);
skvm::Color destColor = builder->uniformColor(SkColors::kBlack, &uniforms);
skvm::Color result = SkSL::ProgramToSkVM(program, *main, builder, debugInfo,
skvm::Color result = SkSL::ProgramToSkVM(program, *main, builder, debugTrace,
SkMakeSpan(uniformVals), device, local, inColor,
destColor, sampleShader, /*sampleColorFilter=*/nullptr,
/*sampleBlender=*/nullptr);

View File

@ -19,7 +19,7 @@ namespace SkSL {
class FunctionDefinition;
struct Program;
class SkVMDebugInfo;
class SkVMDebugTrace;
using SampleShaderFn = std::function<skvm::Color(int, skvm::Coord)>;
using SampleColorFilterFn = std::function<skvm::Color(int, skvm::Color)>;
@ -29,7 +29,7 @@ using SampleBlenderFn = std::function<skvm::Color(int, skvm::Color, skvm::Color)
skvm::Color ProgramToSkVM(const Program& program,
const FunctionDefinition& function,
skvm::Builder* builder,
SkVMDebugInfo* debugInfo,
SkVMDebugTrace* debugTrace,
SkSpan<skvm::Val> uniforms,
skvm::Coord device,
skvm::Coord local,
@ -61,7 +61,7 @@ struct SkVMSignature {
bool ProgramToSkVM(const Program& program,
const FunctionDefinition& function,
skvm::Builder* b,
SkVMDebugInfo* debugInfo,
SkVMDebugTrace* debugTrace,
SkSpan<skvm::Val> uniforms,
SkVMSignature* outSignature = nullptr);
@ -83,7 +83,7 @@ std::unique_ptr<UniformInfo> Program_GetUniformInfo(const Program& program);
bool testingOnly_ProgramToSkVMShader(const Program& program,
skvm::Builder* builder,
SkVMDebugInfo* debugInfo);
SkVMDebugTrace* debugTrace);
} // namespace SkSL

View File

@ -6,7 +6,7 @@
*/
#include "src/core/SkStreamPriv.h"
#include "src/sksl/codegen/SkVMDebugInfo.h"
#include "src/sksl/codegen/SkVMDebugTrace.h"
#include "src/utils/SkJSON.h"
#include "src/utils/SkJSONWriter.h"
@ -14,11 +14,11 @@
namespace SkSL {
void SkVMDebugInfo::setTraceCoord(const SkIPoint& coord) {
void SkVMDebugTrace::setTraceCoord(const SkIPoint& coord) {
fTraceCoord = coord;
}
void SkVMDebugInfo::setSource(std::string source) {
void SkVMDebugTrace::setSource(std::string source) {
std::stringstream stream{std::move(source)};
while (stream.good()) {
fSource.push_back({});
@ -26,7 +26,7 @@ void SkVMDebugInfo::setSource(std::string source) {
}
}
void SkVMDebugInfo::dump(SkWStream* o) const {
void SkVMDebugTrace::dump(SkWStream* o) const {
for (size_t index = 0; index < fSlotInfo.size(); ++index) {
const SkVMSlotInfo& info = fSlotInfo[index];
@ -126,7 +126,7 @@ void SkVMDebugInfo::dump(SkWStream* o) const {
}
}
void SkVMDebugInfo::writeTrace(SkWStream* w) const {
void SkVMDebugTrace::writeTrace(SkWStream* w) const {
SkJSONWriter json(w);
json.beginObject(); // root
@ -189,7 +189,7 @@ void SkVMDebugInfo::writeTrace(SkWStream* w) const {
json.flush();
}
bool SkVMDebugInfo::readTrace(SkStream* r) {
bool SkVMDebugTrace::readTrace(SkStream* r) {
sk_sp<SkData> data = SkCopyStreamToData(r);
skjson::DOM json(reinterpret_cast<const char*>(data->bytes()), data->size());
const skjson::ObjectValue* root = json.root();

View File

@ -5,10 +5,11 @@
* found in the LICENSE file.
*/
#ifndef SKVMDEBUGINFO
#define SKVMDEBUGINFO
#ifndef SKVMDEBUGTRACE
#define SKVMDEBUGTRACE
#include "include/core/SkPoint.h"
#include "include/sksl/SkSLDebugTrace.h"
#include "src/core/SkVM.h"
#include "src/sksl/ir/SkSLType.h"
@ -49,7 +50,7 @@ struct SkVMTraceInfo {
int32_t data[2];
};
class SkVMDebugInfo {
class SkVMDebugTrace : public DebugTrace {
public:
/**
* Sets the device-coordinate pixel to trace. If it's not set, the point at (0, 0) will be used.
@ -59,12 +60,12 @@ public:
/** Attaches the SkSL source to be debugged. */
void setSource(std::string source);
/** Serialization for .trace files. */
/** Serializes a debug trace to JSON which can be parsed by our debugger. */
bool readTrace(SkStream* r);
void writeTrace(SkWStream* w) const;
void writeTrace(SkWStream* w) const override;
/** Write a human-readable dump of the DebugInfo to a .skvm file. */
void dump(SkWStream* o) const;
/** Generates a human-readable dump of the debug trace. */
void dump(SkWStream* o) const override;
/** The device-coordinate pixel to trace (controlled by setTraceCoord) */
SkIPoint fTraceCoord = {};

View File

@ -8,7 +8,7 @@
#include "include/core/SkM44.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/codegen/SkSLVMCodeGenerator.h"
#include "src/sksl/codegen/SkVMDebugInfo.h"
#include "src/sksl/codegen/SkVMDebugTrace.h"
#include "src/sksl/ir/SkSLExternalFunction.h"
#include "src/utils/SkJSON.h"
@ -89,7 +89,7 @@ void test(skiatest::Reporter* r, const char* src, float* in, const float* expect
skvm::Builder b;
SkSL::SkVMSignature sig;
SkSL::ProgramToSkVM(*program, *main, &b, /*debugInfo=*/nullptr, /*uniforms=*/{}, &sig);
SkSL::ProgramToSkVM(*program, *main, &b, /*debugTrace=*/nullptr, /*uniforms=*/{}, &sig);
skvm::Program p = b.done();
REPORTER_ASSERT(r, p.nargs() == (int)(sig.fParameterSlots + sig.fReturnSlots));
@ -119,7 +119,7 @@ void test(skiatest::Reporter* r, const char* src,
REPORTER_ASSERT(r, main);
skvm::Builder b;
SkSL::ProgramToSkVM(*program, *main, &b, /*debugInfo=*/nullptr, /*uniforms=*/{});
SkSL::ProgramToSkVM(*program, *main, &b, /*debugTrace=*/nullptr, /*uniforms=*/{});
skvm::Program p = b.done();
// TODO: Test with and without JIT?
@ -533,7 +533,7 @@ DEF_TEST(SkSLInterpreterCompound, r) {
for (int i = 0; i < 16; ++i) {
uniforms[i] = b.uniform32(uniformPtr, i * sizeof(int)).id;
}
SkSL::ProgramToSkVM(*program, *fn, &b, /*debugInfo=*/nullptr, SkMakeSpan(uniforms));
SkSL::ProgramToSkVM(*program, *fn, &b, /*debugTrace=*/nullptr, SkMakeSpan(uniforms));
return b.done();
};
@ -652,7 +652,7 @@ DEF_TEST(SkSLInterpreterReturnThenCall, r) {
REPORTER_ASSERT(r, main);
skvm::Builder b;
SkSL::ProgramToSkVM(*program, *main, &b, /*debugInfo=*/nullptr, /*uniforms=*/{});
SkSL::ProgramToSkVM(*program, *main, &b, /*debugTrace=*/nullptr, /*uniforms=*/{});
skvm::Program p = b.done();
float xs[] = { -2.0f, 0.0f, 3.0f, -1.0f };
@ -674,7 +674,7 @@ DEF_TEST(SkSLInterpreterEarlyReturn, r) {
REPORTER_ASSERT(r, main);
skvm::Builder b;
SkSL::ProgramToSkVM(*program, *main, &b, /*debugInfo=*/nullptr, /*uniforms=*/{});
SkSL::ProgramToSkVM(*program, *main, &b, /*debugTrace=*/nullptr, /*uniforms=*/{});
skvm::Program p = b.done();
float xs[] = { 1.0f, 3.0f },
@ -716,7 +716,7 @@ DEF_TEST(SkSLInterpreterFunctions, r) {
auto test_fn = [&](const SkSL::FunctionDefinition* fn, float in, float expected) {
skvm::Builder b;
SkSL::ProgramToSkVM(*program, *fn, &b, /*debugInfo=*/nullptr, /*uniforms=*/{});
SkSL::ProgramToSkVM(*program, *fn, &b, /*debugTrace=*/nullptr, /*uniforms=*/{});
skvm::Program p = b.done();
float out = 0.0f;
@ -906,7 +906,7 @@ DEF_TEST(SkSLInterpreterExternalFunction, r) {
const SkSL::FunctionDefinition* main = SkSL::Program_GetFunction(*program, "main");
skvm::Builder b;
SkSL::ProgramToSkVM(*program, *main, &b, /*debugInfo=*/nullptr, /*uniforms=*/{});
SkSL::ProgramToSkVM(*program, *main, &b, /*debugTrace=*/nullptr, /*uniforms=*/{});
skvm::Program p = b.done();
float out;
@ -964,7 +964,7 @@ DEF_TEST(SkSLInterpreterExternalTable, r) {
const SkSL::FunctionDefinition* main = SkSL::Program_GetFunction(*program, "main");
SkSL::ProgramToSkVM(*program, *main, &b, /*debugInfo=*/nullptr, /*uniforms=*/{});
SkSL::ProgramToSkVM(*program, *main, &b, /*debugTrace=*/nullptr, /*uniforms=*/{});
skvm::Program p = b.done();
float out[4];
@ -1004,8 +1004,8 @@ int main() {
REPORTER_ASSERT(r, program);
const SkSL::FunctionDefinition* main = SkSL::Program_GetFunction(*program, "main");
SkSL::SkVMDebugInfo debugInfo;
SkSL::ProgramToSkVM(*program, *main, &b, &debugInfo, /*uniforms=*/{});
SkSL::SkVMDebugTrace debugTrace;
SkSL::ProgramToSkVM(*program, *main, &b, &debugTrace, /*uniforms=*/{});
skvm::Program p = b.done();
REPORTER_ASSERT(r, p.nargs() == 1);
@ -1013,7 +1013,7 @@ int main() {
p.eval(1, &result);
SkDynamicMemoryWStream streamDump;
debugInfo.dump(&streamDump);
debugTrace.dump(&streamDump);
sk_sp<SkData> dataDump = streamDump.detachAsData();
skstd::string_view trace{static_cast<const char*>(dataDump->data()), dataDump->size()};

View File

@ -6,32 +6,32 @@
*/
#include "include/core/SkStream.h"
#include "src/sksl/codegen/SkVMDebugInfo.h"
#include "src/sksl/codegen/SkVMDebugTrace.h"
#include "tests/Test.h"
DEF_TEST(SkVMDebugInfoSetSource, r) {
SkSL::SkVMDebugInfo i;
i.setSource("SkVMDebugInfo::setSource unit test\n"
DEF_TEST(SkVMDebugTraceSetSource, r) {
SkSL::SkVMDebugTrace i;
i.setSource("SkVMDebugTrace::setSource unit test\n"
"\t// first line\n"
"\t// second line\n"
"\t// third line");
REPORTER_ASSERT(r, i.fSource.size() == 4);
REPORTER_ASSERT(r, i.fSource[0] == "SkVMDebugInfo::setSource unit test");
REPORTER_ASSERT(r, i.fSource[0] == "SkVMDebugTrace::setSource unit test");
REPORTER_ASSERT(r, i.fSource[1] == "\t// first line");
REPORTER_ASSERT(r, i.fSource[2] == "\t// second line");
REPORTER_ASSERT(r, i.fSource[3] == "\t// third line");
}
DEF_TEST(SkVMDebugInfoWriteTrace, r) {
SkSL::SkVMDebugInfo i;
DEF_TEST(SkVMDebugTraceWrite, r) {
SkSL::SkVMDebugTrace i;
i.fSource = {
"\t// first line",
"// \"second line\"",
"//\\\\//\\\\ third line",
};
i.fSlotInfo = {
{"SkVM_Debug_Info", 1, 2, 3, (SkSL::Type::NumberKind)4, 5},
{"SkVM_DebugTrace", 1, 2, 3, (SkSL::Type::NumberKind)4, 5},
{"Unit_Test", 6, 7, 8, (SkSL::Type::NumberKind)9, 10},
};
i.fFuncInfo = {
@ -49,7 +49,7 @@ DEF_TEST(SkVMDebugInfoWriteTrace, r) {
static constexpr char kExpected[] =
R"({"source":["\t// first line","// \"second line\"","//\\\\//\\\\ third line"],"s)"
R"(lots":[{"slot":0,"name":"SkVM_Debug_Info","columns":1,"rows":2,"index":3,"kind")"
R"(lots":[{"slot":0,"name":"SkVM_DebugTrace","columns":1,"rows":2,"index":3,"kind")"
R"(:4,"line":5},{"slot":1,"name":"Unit_Test","columns":6,"rows":7,"index":8,"kind")"
R"(:9,"line":10}],"functions":[{"slot":0,"name":"void testFunc();"}],"trace":[[2],)"
R"([0,5],[1,10,15],[3,20]]})";
@ -61,16 +61,16 @@ DEF_TEST(SkVMDebugInfoWriteTrace, r) {
kExpected, (int)actual.size(), actual.data());
}
DEF_TEST(SkVMDebugInfoReadTrace, r) {
DEF_TEST(SkVMDebugTraceRead, r) {
const skstd::string_view kJSONTrace =
R"({"source":["\t// first line","// \"second line\"","//\\\\//\\\\ third line"],"s)"
R"(lots":[{"slot":0,"name":"SkVM_Debug_Info","columns":1,"rows":2,"index":3,"kind")"
R"(lots":[{"slot":0,"name":"SkVM_DebugTrace","columns":1,"rows":2,"index":3,"kind")"
R"(:4,"line":5},{"slot":1,"name":"Unit_Test","columns":6,"rows":7,"index":8,"kind")"
R"(:9,"line":10}],"functions":[{"slot":0,"name":"void testFunc();"}],"trace":[[2],)"
R"([0,5],[1,10,15],[3,20]]})";
SkMemoryStream stream(kJSONTrace.data(), kJSONTrace.size(), /*copyData=*/false);
SkSL::SkVMDebugInfo i;
SkSL::SkVMDebugTrace i;
REPORTER_ASSERT(r, i.readTrace(&stream));
REPORTER_ASSERT(r, i.fSource.size() == 3);
@ -82,7 +82,7 @@ DEF_TEST(SkVMDebugInfoReadTrace, r) {
REPORTER_ASSERT(r, i.fSource[1] == "// \"second line\"");
REPORTER_ASSERT(r, i.fSource[2] == "//\\\\//\\\\ third line");
REPORTER_ASSERT(r, i.fSlotInfo[0].name == "SkVM_Debug_Info");
REPORTER_ASSERT(r, i.fSlotInfo[0].name == "SkVM_DebugTrace");
REPORTER_ASSERT(r, i.fSlotInfo[0].columns == 1);
REPORTER_ASSERT(r, i.fSlotInfo[0].rows == 2);
REPORTER_ASSERT(r, i.fSlotInfo[0].componentIndex == 3);