The goal is to reduce the startup time cost of all of these parsing and string replacement. All comments are now stripped at compile time. This comment check added noticeable slowdown at startup in debug builds and during preprocessing. Put all metadatas between start and end token. Use very simple parsing using `StringRef` and hash all identifiers. Move all the complexity to the preprocessor that massagess the metadata into a well expected input to the runtime parser. All identifiers are compile time hashed so that no string comparison is made at runtime. Speed up the source loading: - from 10ms to 1.6ms (6.25x speedup) in release - from 194ms to 6ms (32.3x speedup) in debug Follow up #129009 Pull Request: https://projects.blender.org/blender/blender/pulls/128927
104 lines
3.3 KiB
C++
104 lines
3.3 KiB
C++
/* SPDX-FileCopyrightText: 2021 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#include "gl_shader.hh"
|
|
|
|
#include "GPU_platform.hh"
|
|
|
|
namespace blender::gpu {
|
|
|
|
const char *GLLogParser::parse_line(const char *source_combined,
|
|
const char *log_line,
|
|
GPULogItem &log_item)
|
|
{
|
|
/* Skip ERROR: or WARNING:. */
|
|
log_line = skip_severity_prefix(log_line, log_item);
|
|
log_line = skip_separators(log_line, "(: ");
|
|
|
|
/* Parse error line & char numbers. */
|
|
if (at_number(log_line)) {
|
|
const char *error_line_number_end;
|
|
log_item.cursor.row = parse_number(log_line, &error_line_number_end);
|
|
/* Try to fetch the error character (not always available). */
|
|
if (at_any(error_line_number_end, "(:") && at_number(&error_line_number_end[1])) {
|
|
log_item.cursor.column = parse_number(error_line_number_end + 1, &log_line);
|
|
}
|
|
else {
|
|
log_line = error_line_number_end;
|
|
}
|
|
/* There can be a 3rd number (case of mesa driver). */
|
|
if (at_any(log_line, "(:") && at_number(&log_line[1])) {
|
|
log_item.cursor.source = log_item.cursor.row;
|
|
log_item.cursor.row = log_item.cursor.column;
|
|
log_item.cursor.column = parse_number(log_line + 1, &error_line_number_end);
|
|
log_line = error_line_number_end;
|
|
}
|
|
}
|
|
|
|
if ((log_item.cursor.row != -1) && (log_item.cursor.column != -1)) {
|
|
if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_OFFICIAL)) {
|
|
/* 0:line */
|
|
log_item.cursor.row = log_item.cursor.column;
|
|
log_item.cursor.column = -1;
|
|
}
|
|
else if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OFFICIAL) &&
|
|
/* WORKAROUND(@fclem): Both Mesa and AMDGPU-PRO are reported as official. */
|
|
StringRefNull(GPU_platform_version()).find(" Mesa ") == -1)
|
|
{
|
|
/* source:row */
|
|
log_item.cursor.source = log_item.cursor.row;
|
|
log_item.cursor.row = log_item.cursor.column;
|
|
log_item.cursor.column = -1;
|
|
}
|
|
else {
|
|
/* line:char */
|
|
}
|
|
}
|
|
|
|
/* TODO: Temporary fix for new line directive. Eventually this whole parsing should be done in
|
|
* C++ with regex for simplicity. */
|
|
if (log_item.cursor.source != -1) {
|
|
StringRefNull src(source_combined);
|
|
std::string needle = std::string("#line 1 ") + std::to_string(log_item.cursor.source);
|
|
|
|
int64_t file_start = src.find(needle);
|
|
if (file_start == -1) {
|
|
/* Can be generated code or wrapper code outside of the main sources. */
|
|
log_item.cursor.row = -1;
|
|
}
|
|
else {
|
|
StringRef previous_sources(source_combined, file_start);
|
|
for (const char c : previous_sources) {
|
|
if (c == '\n') {
|
|
log_item.cursor.row++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
log_line = skip_separators(log_line, ":) ");
|
|
|
|
/* Skip to message. Avoid redundant info. */
|
|
log_line = skip_severity_keyword(log_line, log_item);
|
|
log_line = skip_separators(log_line, ":) ");
|
|
|
|
return log_line;
|
|
}
|
|
|
|
const char *GLLogParser::skip_severity_prefix(const char *log_line, GPULogItem &log_item)
|
|
{
|
|
return skip_severity(log_line, log_item, "ERROR", "WARNING", "NOTE");
|
|
}
|
|
|
|
const char *GLLogParser::skip_severity_keyword(const char *log_line, GPULogItem &log_item)
|
|
{
|
|
return skip_severity(log_line, log_item, "error", "warning", "note");
|
|
}
|
|
|
|
} // namespace blender::gpu
|