Add breakpoint support in SkSL debugger.

Line numbers were previously Text. They are now SmallButtons; clicking
them sets and clears breakpoints. The set of active breakpoints is
stored in an unordered_set of line numbers. Breakpoints are visualized
by setting the color of the SmallButton controls to red.

We now also have "Reset" (start over) and "Run to Breakpoint" buttons.

http://screen/8rtenW2vszxDgCp

Change-Id: I30a79bb09811e1d8a4e4e8535cbe62020f20f111
Bug: skia:12747
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/485861
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
John Stiles 2021-12-16 15:05:29 -05:00 committed by SkCQ
parent 38d5328926
commit 44a8392620
3 changed files with 53 additions and 4 deletions

View File

@ -110,6 +110,14 @@ void SkVMDebugTracePlayer::setBreakpoints(std::unordered_set<int> breakpointLine
fBreakpointLines = std::move(breakpointLines);
}
void SkVMDebugTracePlayer::addBreakpoint(int line) {
fBreakpointLines.insert(line);
}
void SkVMDebugTracePlayer::removeBreakpoint(int line) {
fBreakpointLines.erase(line);
}
std::vector<int> SkVMDebugTracePlayer::getCallStack() const {
SkASSERT(!fStack.empty());
std::vector<int> funcs;

View File

@ -9,6 +9,8 @@
#include "src/sksl/tracing/SkVMDebugTrace.h"
#include "src/utils/SkBitSet.h"
#include <unordered_set>
namespace SkSL {
/**
@ -39,6 +41,9 @@ public:
/** Breakpoints will force the simulation to stop whenever a desired line is reached. */
void setBreakpoints(std::unordered_set<int> breakpointLines);
void addBreakpoint(int line);
void removeBreakpoint(int line);
const std::unordered_set<int>& getBreakpoints() { return fBreakpointLines; }
/** Returns true if we have reached the end of the trace. */
bool traceHasCompleted() const;

View File

@ -28,6 +28,7 @@ void SkSLDebuggerSlide::load(SkScalar winWidth, SkScalar winHeight) {}
void SkSLDebuggerSlide::unload() {
fTrace = sk_make_sp<SkSL::SkVMDebugTrace>();
fPlayer.reset(nullptr);
fPlayer.setBreakpoints(std::unordered_set<int>{});
}
void SkSLDebuggerSlide::showLoadTraceGUI() {
@ -69,6 +70,11 @@ void SkSLDebuggerSlide::showLoadTraceGUI() {
}
void SkSLDebuggerSlide::showDebuggerGUI() {
if (ImGui::Button("Reset")) {
fPlayer.reset(fTrace);
fRefresh = true;
}
ImGui::SameLine(/*offset_from_start_x=*/0, /*spacing=*/100);
if (ImGui::Button("Step")) {
fPlayer.step();
fRefresh = true;
@ -83,6 +89,11 @@ void SkSLDebuggerSlide::showDebuggerGUI() {
fPlayer.stepOut();
fRefresh = true;
}
ImGui::SameLine(/*offset_from_start_x=*/0, /*spacing=*/100);
if (ImGui::Button(fPlayer.getBreakpoints().empty() ? "Run" : "Run to Breakpoint")) {
fPlayer.run();
fRefresh = true;
}
this->showStackTraceTable();
this->showVariableTable();
@ -116,12 +127,37 @@ void SkSLDebuggerSlide::showCodeTable() {
ImGuiTableBgTarget_RowBg1,
ImGui::GetColorU32(ImGui::GetStyleColorVec4(ImGuiCol_TextSelectedBg)));
}
// Show line numbers and breakpoints.
ImGui::TableSetColumnIndex(0);
ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, 0.75f);
if (!fPlayer.getLineNumbersReached().count(humanReadableLine)) {
color.w = 0.25f;
bool reachable = fPlayer.getLineNumbersReached().count(humanReadableLine);
bool breakpointOn = reachable && fPlayer.getBreakpoints().count(humanReadableLine);
if (breakpointOn) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 0.0f, 0.0f, 0.70f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0.0f, 0.0f, 0.85f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
} else if (reachable) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 0.75f));
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 1.0f, 1.0f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 1.0f, 1.0f, 0.2f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 1.0f, 1.0f, 0.4f));
} else {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 0.25f));
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 1.0f, 1.0f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 1.0f, 1.0f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 1.0f, 1.0f, 0.0f));
}
ImGui::TextColored(color, "%03zu ", humanReadableLine);
if (ImGui::SmallButton(SkStringPrintf("%03zu ", humanReadableLine).c_str())) {
if (breakpointOn) {
fPlayer.removeBreakpoint(humanReadableLine);
} else if (reachable) {
fPlayer.addBreakpoint(humanReadableLine);
}
}
ImGui::PopStyleColor(4);
// Show lines of code.
ImGui::TableSetColumnIndex(1);
ImGui::Text("%s", fTrace->fSource[row].c_str());
}