30#if defined(SKSL_STANDALONE)
58 fContext = std::make_shared<Context>(moduleLoader.builtinTypes(), fErrorReporter);
105 if (
settings->fInlineThreshold == 0) {
118 settings->fAllowNarrowingConversions =
true;
122void Compiler::initializeContext(
const SkSL::Module* module,
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();
177 std::string moduleSource,
178 const Module* parentModule,
185 auto sourcePtr = std::make_unique<std::string>(std::move(moduleSource));
190 this->initializeContext(parentModule, kind,
settings, *sourcePtr,
true);
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));
218 this->initializeContext(module, kind,
settings, *sourcePtr,
false);
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;
440 printLocation =
pos.startOffset() < (
int)
src.length();
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;
525 ((
count == 1) ?
" error\n" :
" errors\n");
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
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)
std::unique_ptr< Module > moduleInheritingFrom(const Module *parentModule)
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 SkString to_string(int n)
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)