47 class TracingHtmlHelper {
55 void AddHtml(
uint64 frame_counter,
const std::string& trace_string,
56 std::string* html_string);
76 void AddHeader(
uint64 frame_counter,
bool add_horizontal_rule,
77 std::ostringstream& s);
80 const std::vector<ParsedLine> ParseLines(
const std::string& trace_string);
83 const ParsedLine ParseLine(
const std::string& line);
86 void AddHtmlForLines(
const std::vector<ParsedLine>& parsed_lines,
87 std::ostringstream& s);
90 void AddHtmlForCall(
const std::string& line,
91 std::ostringstream& s);
94 TracingHtmlHelper::TracingHtmlHelper() {}
95 TracingHtmlHelper::~TracingHtmlHelper() {}
97 void TracingHtmlHelper::AddHtml(
uint64 frame_counter,
98 const std::string& trace_string,
99 std::string* html_string) {
101 std::ostringstream s;
103 AddHeader(frame_counter, !html_string->empty(), s);
104 const std::vector<ParsedLine> parsed_lines = ParseLines(trace_string);
106 AddHtmlForLines(parsed_lines, s);
108 html_string->append(s.str());
111 void TracingHtmlHelper::AddHeader(
uint64 frame_counter,
112 bool add_horizontal_rule,
113 std::ostringstream& s) {
114 if (add_horizontal_rule)
117 s <<
"<span class=\"trace_header\">OpenGL trace at frame "
118 << frame_counter <<
"</span><br><br>\n";
121 const std::vector<TracingHtmlHelper::ParsedLine> TracingHtmlHelper::ParseLines(
122 const std::string& trace_string) {
124 const size_t num_lines = lines.size();
126 std::vector<ParsedLine> parsed_lines;
127 parsed_lines.reserve(num_lines);
128 for (
size_t i = 0; i < num_lines; ++i)
129 parsed_lines.push_back(ParseLine(lines[i]));
134 const TracingHtmlHelper::ParsedLine TracingHtmlHelper::ParseLine(
135 const std::string& line) {
137 const size_t length = line.size();
138 ParsedLine parsed_line;
141 if (line.find(
"GL error") != std::string::npos) {
142 static const char kErrorHeader[] =
"*** GL error after call to";
143 parsed_line.type = ParsedLine::kError;
144 parsed_line.level = 0;
146 parsed_line.text = line.substr(
sizeof(kErrorHeader));
147 }
else if (line[0] ==
'>' || line[0] ==
'-') {
149 const size_t num_dashes = line.find_first_not_of(
'-');
155 parsed_line.type = ParsedLine::kLabel;
156 parsed_line.level =
static_cast<int>(num_dashes / 2);
157 parsed_line.text = line.substr(num_dashes + 1);
161 parsed_line.text.resize(parsed_line.text.size() - 1);
164 const size_t num_spaces = line.find_first_not_of(
' ');
168 parsed_line.type = ParsedLine::kCall;
169 parsed_line.level =
static_cast<int>(num_spaces / 2);
170 parsed_line.text = line.substr(num_spaces);
175 void TracingHtmlHelper::AddHtmlForLines(
176 const std::vector<ParsedLine>& parsed_lines,
177 std::ostringstream& s) {
178 s <<
"<div class=\"tree\">\n<ul>\n";
180 const size_t num_lines = parsed_lines.size();
184 for (
size_t i = 0; i < num_lines; ++i) {
185 const ParsedLine& line = parsed_lines[i];
188 if (line.type == ParsedLine::kError) {
189 s <<
"<br><span class=\"trace_error\">" <<
"***OpenGL Error: "
190 << line.text <<
"</span><br><br>\n";
195 while (list_level >= line.level) {
196 s <<
"</ul>\n</li>\n";
200 if (line.type == ParsedLine::kLabel) {
202 const size_t list_id = cur_list++;
203 s <<
"<li><input type =\"checkbox\" checked=\"checked\" id=\"list-"
204 << list_id <<
"\"/><label for=\"list-" << list_id <<
"\">" << line.text
205 <<
"</label>\n<ul>\n";
206 list_level = line.level;
210 AddHtmlForCall(line.text, s);
216 while (list_level >= 0) {
217 s <<
"</ul>\n</li>\n";
221 s <<
"</ul>\n</div>\n";
225 TracingHtmlHelper::AddHtmlForCall(
const std::string& line,
226 std::ostringstream& s) {
228 const size_t arg_count = args.size();
231 for (
size_t i = 0; i < arg_count; ++i)
235 s <<
"<span class=\"trace_function\">" << args[0] <<
"</span>(";
237 for (
size_t i = 1; i < arg_count; ++i) {
238 std::string arg = args[i];
241 const size_t pos = arg.find(
" = ");
242 if (pos != std::string::npos) {
245 s <<
"<span class=\"trace_arg_name\">"
246 << arg.substr(0, pos) <<
"</span> = <span class=\"trace_arg_value\">"
247 << arg.substr(pos + 3, std::string::npos);
268 const std::string&
name) {
272 "Framebuffer Objects",
274 "Shader Input Registries",
281 if (name == kResourceNames[index])
284 DCHECK_LT(index, gfx::Renderer::kNumResourceTypes);
303 prev_stream_(
renderer_->GetGraphicsManager()->GetTracingStream()),
307 using std::placeholders::_1;
309 IonRemoteTracingRoot::RegisterAssetsOnce();
313 frame_->AddPreFrameCallback(
"TracingHandler",
314 bind(&TracingHandler::BeginFrame,
this, _1));
315 frame_->AddPostFrameCallback(
"TracingHandler",
316 bind(&TracingHandler::EndFrame,
this, _1));
323 frame_->RemovePreFrameCallback(
"TracingHandler");
324 frame_->RemovePostFrameCallback(
"TracingHandler");
328 renderer_->GetGraphicsManager()->SetTracingStream(prev_stream_);
333 std::string* content_type) {
334 const std::string path = path_in.empty() ?
"index.html" : path_in;
336 if (path ==
"trace_next_frame") {
338 const HttpServer::QueryMap::const_iterator it =
339 args.find(
"resources_to_delete");
340 resources_to_delete_ = it != args.end() ? it->second :
"";
343 TraceNextFrame(args.find(
"nonblocking") == args.end());
345 }
else if (path ==
"clear") {
346 html_string_.clear();
349 const std::string& data =
354 *content_type =
"text/html";
358 return std::string();
361 void TracingHandler::TraceNextFrame(
bool block_until_frame_rendered) {
364 state_ = kWaitingForBeginFrame;
366 if (!block_until_frame_rendered) {
373 TracingHtmlHelper helper;
374 helper.AddHtml(frame_counter_, tracing_stream_.str(), &html_string_);
375 tracing_stream_.str(
"");
379 void TracingHandler::BeginFrame(
const gfxutils::Frame& frame) {
380 if (state_ == kWaitingForBeginFrame) {
382 if (!resources_to_delete_.empty()) {
384 const std::vector<std::string> resources =
386 const size_t num_resources = resources.size();
387 for (
size_t i = 0; i < num_resources; ++i)
388 renderer_->ClearTypedResources(GetResourceTypeFromName(resources[i]));
389 resources_to_delete_.clear();
391 frame_counter_ = frame.GetCounter();
392 renderer_->GetGraphicsManager()->SetTracingStream(&tracing_stream_);
393 state_ = kWaitingForEndFrame;
397 void TracingHandler::EndFrame(
const gfxutils::Frame& frame) {
398 if (state_ == kWaitingForEndFrame) {
399 renderer_->GetGraphicsManager()->SetTracingStream(prev_stream_);
bool Post()
Wakes a single thread that is Wait()ing, or the next thread to call Wait().
bool IsInvalidReference(const T &value)
IsInvalidReference() returns true if a passed const reference of type T has an address of InvalidRefe...
bool Wait()
Blocks the calling thread until another thread calls Post().
const std::string HandleRequest(const std::string &path, const HttpServer::QueryMap &args, std::string *content_type) override
The HandleRequest() function is passed the path (relative to its base path) of the file or directory ...
ResourceType
The types of resources created by the renderer.
ION_REGISTER_ASSETS(IonRemoteTracingRoot)
Copyright 2016 Google Inc.
std::string TrimStartAndEndWhitespace(const std::string &target)
Removes any whitespace characters at the beginning and end of the string.
std::vector< std::string > ION_API SplitString(const std::string &str, const std::string &delimiters)
Splits a string into a vector of substrings, given a set of delimiter characters (expressed as a stri...
static const std::string & GetFileData(const std::string &filename)
Returns the data of the passed filename if the manager contains it.
T * Get() const
Returns a raw pointer to the instance, which may be NULL.
TracingHandler(const gfxutils::FramePtr &frame, const gfx::RendererPtr &renderer)
The constructor is passed a Frame instance that allows the handler to know when frames begin and end ...
Copyright 2016 Google Inc.
#define DCHECK_EQ(val1, val2)
bool EndsWith(const std::string &target, const std::string &end)
Returns whether target ends with end.
~TracingHandler() override
const RendererPtr & renderer_
Renderer used to render images.
std::map< std::string, std::string > QueryMap
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
#define DCHECK_LT(val1, val2)
static const int kNumResourceTypes