30#if defined(SKSL_STANDALONE)
58 fContext = std::make_shared<Context>(moduleLoader.builtinTypes(), fErrorReporter);
88 case OverrideFlag::kDefault:
90 case OverrideFlag::kOff:
91 settings->fOptimize =
false;
93 case OverrideFlag::kOn:
94 settings->fOptimize =
true;
99 case OverrideFlag::kDefault:
101 case OverrideFlag::kOff:
102 settings->fInlineThreshold = 0;
104 case OverrideFlag::kOn:
105 if (settings->fInlineThreshold == 0) {
118 settings->fAllowNarrowingConversions =
true;
122void Compiler::initializeContext(
const SkSL::Module* module,
124 ProgramSettings settings,
136 fConfig = std::make_unique<ProgramConfig>();
137 fConfig->fIsBuiltinCode = isModule;
139 fConfig->fKind = kind;
142 FinalizeSettings(&fConfig->fSettings, kind);
146 fPool->attachToThread();
149 fContext->fConfig = fConfig.get();
150 fContext->fModule =
module;
151 fContext->fErrors->setSource(
source);
154 fGlobalSymbols = std::make_unique<SymbolTable>(module->
fSymbols.get(), isModule);
155 fGlobalSymbols->markModuleBoundary();
156 fContext->fSymbolTable = fGlobalSymbols.get();
159void Compiler::cleanupContext() {
161 fContext->fConfig =
nullptr;
162 fContext->fModule =
nullptr;
163 fContext->fErrors->setSource(std::string_view());
164 fContext->fSymbolTable =
nullptr;
167 fGlobalSymbols =
nullptr;
170 fPool->detachFromThread();
176 const char* moduleName,
177 std::string moduleSource,
178 const Module* parentModule,
185 auto sourcePtr = std::make_unique<std::string>(std::move(moduleSource));
189 settings.fUseMemoryPool =
false;
190 this->initializeContext(parentModule, kind, settings, *sourcePtr,
true);
192 std::unique_ptr<Module>
module = SkSL::Parser(this, settings, kind, std::move(sourcePtr))
193 .moduleInheritingFrom(parentModule);
195 this->cleanupContext();
198 SkDebugf(
"Unexpected errors compiling %s:\n\n%s\n", moduleName, this->
errorText().c_str());
202 this->optimizeModuleAfterLoading(kind, *module);
208 std::string programSource,
210 TRACE_EVENT0(
"skia.shaders",
"SkSL::Compiler::convertProgram");
213 auto sourcePtr = std::make_unique<std::string>(std::move(programSource));
216 const SkSL::Module*
module = this->moduleForProgramKind(kind);
218 this->initializeContext(module, kind, settings, *sourcePtr,
false);
220 std::unique_ptr<Program> program =
SkSL::Parser(
this, settings, kind, std::move(sourcePtr))
223 this->cleanupContext();
227std::unique_ptr<SkSL::Program> Compiler::releaseProgram(
228 std::unique_ptr<std::string>
source,
229 std::vector<std::unique_ptr<SkSL::ProgramElement>> programElements) {
231 auto result = std::make_unique<SkSL::Program>(std::move(
source),
234 std::move(programElements),
235 std::move(fGlobalSymbols),
237 fContext->fSymbolTable =
nullptr;
239 bool success = this->finalize(*
result) &&
242 pool->detachFromThread();
244 return success ? std::move(
result) : nullptr;
290 onlyPrivateGlobals)) {
309#ifndef SK_ENABLE_OPTIMIZE_SIZE
319 Inliner inliner(fContext.get());
332bool Compiler::optimize(Program& program) {
334 if (!program.fConfig->fSettings.fOptimize) {
340#ifndef SK_ENABLE_OPTIMIZE_SIZE
343 Inliner inliner(fContext.get());
344 this->
runInliner(&inliner, program.fOwnedElements, program.fSymbols.get(),
345 program.fUsage.get());
371#ifndef SK_ENABLE_OPTIMIZE_SIZE
373 Inliner inliner(fContext.get());
380 const std::vector<std::unique_ptr<ProgramElement>>& elements,
383#ifdef SK_ENABLE_OPTIMIZE_SIZE
389 fContext->fSymbolTable = symbols;
393 fContext->fSymbolTable =
nullptr;
398bool Compiler::finalize(Program& program) {
412 if (fContext->fConfig->strictES2Mode() && this->errorCount() == 0) {
415 for (
const auto& pe : program.fOwnedElements) {
434 fErrorText +=
"error: ";
435 bool printLocation =
false;
439 line =
pos.line(src);
440 printLocation =
pos.startOffset() < (
int)src.length();
441 fErrorText += std::to_string(line) +
": ";
443 fErrorText += std::string(msg) +
"\n";
445 const int kMaxSurroundingChars = 100;
448 int lineStart =
pos.startOffset();
449 while (lineStart > 0) {
450 if (src[lineStart - 1] ==
'\n') {
458 std::string lineText;
459 std::string caretText;
460 if ((
pos.startOffset() - lineStart) > kMaxSurroundingChars) {
461 lineStart =
pos.startOffset() - kMaxSurroundingChars;
468 const char* lineSuffix =
"...\n";
469 int lineStop =
pos.endOffset() + kMaxSurroundingChars;
470 if (lineStop >= (
int)src.length()) {
471 lineStop = src.length() - 1;
474 for (
int i = lineStart; i < lineStop; ++i) {
481 case '\t': lineText +=
" ";
break;
482 case '\0': lineText +=
" ";
break;
483 default: lineText += src[i];
break;
486 fErrorText += lineText + lineSuffix;
489 for (
int i = lineStart; i < (
int)src.length(); i++) {
490 if (i >=
pos.endOffset()) {
495 caretText += (i >=
pos.startOffset()) ?
"^^^^" :
" ";
500 caretText += (
pos.endOffset() > i + 1) ?
"..." :
"^";
504 caretText += (i >=
pos.startOffset()) ?
'^' :
' ';
508 fErrorText += caretText +
'\n';
516 std::string
result = fErrorText;
524 fErrorText += std::to_string(
count) +
525 ((
count == 1) ?
" error\n" :
" errors\n");
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
Type::kYUV Type::kRGBA() int(0.7 *637)
AutoProgramConfig(Context &context, ProgramConfig *config)
ProgramConfig * fOldConfig
std::string errorText(bool showCount=true)
const Module * moduleForProgramKind(ProgramKind kind)
Context & context() const
std::unique_ptr< Module > compileModule(ProgramKind kind, const char *moduleName, std::string moduleSource, const Module *parentModule, bool shouldInline)
bool optimizeModuleBeforeMinifying(ProgramKind kind, Module &module, bool shrinkSymbols)
void runInliner(Program &program)
void handleError(std::string_view msg, Position pos)
ErrorReporter & errorReporter()
std::unique_ptr< Program > convertProgram(ProgramKind kind, std::string programSource, const ProgramSettings &settings)
std::string_view source() const
bool analyze(const std::vector< std::unique_ptr< ProgramElement > > &elements, SymbolTable *symbols, ProgramUsage *usage)
static ModuleLoader Get()
std::unique_ptr< Program > programInheritingFrom(const Module *module)
static std::unique_ptr< Pool > Create()
void ValidateIndexingForES2(const ProgramElement &pe, ErrorReporter &errors)
std::unique_ptr< ProgramUsage > GetUsage(const Program &program)
void CheckSymbolTableCorrectness(const Program &program)
bool CheckProgramStructure(const Program &program, bool enforceSizeLimit)
void DoFinalizationChecks(const Program &program)
static constexpr int kDefaultInlineThreshold
@ kPrivateRuntimeColorFilter
static void usage(char *argv0)
std::vector< std::unique_ptr< ProgramElement > > fElements
std::unique_ptr< SymbolTable > fSymbols
static bool IsRuntimeEffect(ProgramKind kind)
std::vector< std::unique_ptr< ProgramElement > > fOwnedElements
std::unique_ptr< ProgramUsage > fUsage
std::unique_ptr< SymbolTable > fSymbols
std::unique_ptr< ProgramConfig > fConfig
#define TRACE_EVENT0(category_group, name)