Remove ProgramSettings from IRGenerator and the Inliner.
These classes now read the program configuration from the Context.
Change-Id: I15c95cacebb9836ee8f2162c4f4b7f99d453639c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/371396
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 59afc0d..c25d393 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -280,16 +280,21 @@
}
const String* source = fRootSymbolTable->takeOwnershipOfString(std::move(text));
AutoSource as(this, source);
- Program::Settings settings;
+
SkASSERT(fIRGenerator->fCanInline);
fIRGenerator->fCanInline = false;
- settings.fReplaceSettings = false;
+
+ ProgramConfig config;
+ config.fKind = kind;
+ config.fSettings.fReplaceSettings = false;
+
+ fContext->fConfig = &config;
+ SK_AT_SCOPE_EXIT(fContext->fConfig = nullptr);
ParsedModule baseModule = {base, /*fIntrinsics=*/nullptr};
- IRGenerator::IRBundle ir =
- fIRGenerator->convertProgram(kind, &settings, baseModule,
- /*isBuiltinCode=*/true, source->c_str(), source->length(),
- /*externalFunctions=*/nullptr);
+ IRGenerator::IRBundle ir = fIRGenerator->convertProgram(baseModule, /*isBuiltinCode=*/true,
+ source->c_str(), source->length(),
+ /*externalFunctions=*/nullptr);
SkASSERT(ir.fSharedElements.empty());
LoadedModule module = { kind, std::move(ir.fSymbolTable), std::move(ir.fElements) };
fIRGenerator->fCanInline = true;
@@ -1415,7 +1420,7 @@
break;
} else {
if (s.isStatic() &&
- !fIRGenerator->fSettings->fPermitInvalidStaticTests) {
+ !fContext->fConfig->fSettings.fPermitInvalidStaticTests) {
auto [iter, didInsert] = optimizationContext->fSilences.insert(&s);
if (didInsert) {
this->error(s.fOffset, "static switch contains non-static "
@@ -1434,7 +1439,7 @@
(*iter)->setStatement(std::move(newBlock), usage);
} else {
if (s.isStatic() &&
- !fIRGenerator->fSettings->fPermitInvalidStaticTests) {
+ !fContext->fConfig->fSettings.fPermitInvalidStaticTests) {
auto [iter, didInsert] = optimizationContext->fSilences.insert(&s);
if (didInsert) {
this->error(s.fOffset, "static switch contains non-static "
@@ -1589,7 +1594,7 @@
fErrorText = "";
fErrorCount = 0;
- fInliner.reset(fIRGenerator->fModifiers.get(), &config->fSettings);
+ fInliner.reset(fIRGenerator->fModifiers.get());
// Not using AutoSource, because caller is likely to call errorText() if we fail to compile
std::unique_ptr<String> textPtr(new String(std::move(text)));
@@ -1602,9 +1607,9 @@
pool = Pool::Create();
pool->attachToThread();
}
- IRGenerator::IRBundle ir =
- fIRGenerator->convertProgram(kind, &settings, baseModule, /*isBuiltinCode=*/false,
- textPtr->c_str(), textPtr->size(), externalFunctions);
+ IRGenerator::IRBundle ir = fIRGenerator->convertProgram(baseModule, /*isBuiltinCode=*/false,
+ textPtr->c_str(), textPtr->size(),
+ externalFunctions);
auto program = std::make_unique<Program>(std::move(textPtr),
std::move(config),
fCaps,
@@ -1669,7 +1674,7 @@
};
// If invalid static tests are permitted, we don't need to check anything.
- if (fIRGenerator->fSettings->fPermitInvalidStaticTests) {
+ if (fContext->fConfig->fSettings.fPermitInvalidStaticTests) {
return;
}
@@ -1694,10 +1699,8 @@
fContext->fConfig = &config;
SK_AT_SCOPE_EXIT(fContext->fConfig = nullptr);
- // Set this configuration in the IR Generator and Inliner.
- fIRGenerator->fKind = config.fKind;
- fIRGenerator->fSettings = &config.fSettings;
- fInliner.reset(fModifiers.back().get(), &config.fSettings);
+ // Reset the Inliner.
+ fInliner.reset(fModifiers.back().get());
std::unique_ptr<ProgramUsage> usage = Analysis::GetUsage(module);
@@ -1723,8 +1726,6 @@
bool Compiler::optimize(Program& program) {
SkASSERT(!fErrorCount);
- fIRGenerator->fKind = program.fConfig->fKind;
- fIRGenerator->fSettings = &program.fConfig->fSettings;
ProgramUsage* usage = program.fUsage.get();
while (fErrorCount == 0) {
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 7b5cd2f..febdccc 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -174,9 +174,9 @@
}
std::unique_ptr<Extension> IRGenerator::convertExtension(int offset, StringFragment name) {
- if (fKind != ProgramKind::kFragment &&
- fKind != ProgramKind::kVertex &&
- fKind != ProgramKind::kGeometry) {
+ if (this->programKind() != ProgramKind::kFragment &&
+ this->programKind() != ProgramKind::kVertex &&
+ this->programKind() != ProgramKind::kGeometry) {
this->errorReporter().error(offset, "extensions are not allowed here");
return nullptr;
}
@@ -220,7 +220,7 @@
default:
// it's an expression
std::unique_ptr<Statement> result = this->convertExpressionStatement(statement);
- if (fRTAdjust && fKind == ProgramKind::kGeometry) {
+ if (fRTAdjust && this->programKind() == ProgramKind::kGeometry) {
SkASSERT(result->kind() == Statement::Kind::kExpression);
Expression& expr = *result->as<ExpressionStatement>().expression();
if (expr.kind() == Expression::Kind::kFunctionCall) {
@@ -338,7 +338,7 @@
offset,
"variables of type '" + baseType->displayName() + "' must be global");
}
- if (fKind != ProgramKind::kFragmentProcessor) {
+ if (this->programKind() != ProgramKind::kFragmentProcessor) {
if ((modifiers.fFlags & Modifiers::kIn_Flag) && baseType->isMatrix()) {
this->errorReporter().error(offset, "'in' variables may not have matrix type");
}
@@ -365,7 +365,7 @@
"'key' is only permitted within fragment processors");
}
}
- if (fKind == ProgramKind::kRuntimeEffect) {
+ if (this->programKind() == ProgramKind::kRuntimeEffect) {
if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
*baseType != *fContext.fTypes.fFragmentProcessor) {
this->errorReporter().error(offset,
@@ -376,7 +376,7 @@
this->errorReporter().error(offset, "'key' is not permitted on 'uniform' variables");
}
if (modifiers.fLayout.fMarker.fLength) {
- if (fKind != ProgramKind::kRuntimeEffect) {
+ if (this->programKind() != ProgramKind::kRuntimeEffect) {
this->errorReporter().error(offset,
"'marker' is only permitted in runtime effects");
}
@@ -390,7 +390,7 @@
}
}
if (modifiers.fLayout.fFlags & Layout::kSRGBUnpremul_Flag) {
- if (fKind != ProgramKind::kRuntimeEffect) {
+ if (this->programKind() != ProgramKind::kRuntimeEffect) {
this->errorReporter().error(offset,
"'srgb_unpremul' is only permitted in runtime effects");
}
@@ -410,7 +410,7 @@
}
}
if (modifiers.fFlags & Modifiers::kVarying_Flag) {
- if (fKind != ProgramKind::kRuntimeEffect) {
+ if (this->programKind() != ProgramKind::kRuntimeEffect) {
this->errorReporter().error(offset, "'varying' is only permitted in runtime effects");
}
if (!baseType->isFloat() &&
@@ -440,8 +440,8 @@
std::unique_ptr<Expression> value,
Variable::Storage storage) {
if (modifiers.fLayout.fLocation == 0 && modifiers.fLayout.fIndex == 0 &&
- (modifiers.fFlags & Modifiers::kOut_Flag) && fKind == ProgramKind::kFragment &&
- name != "sk_FragColor") {
+ (modifiers.fFlags & Modifiers::kOut_Flag) &&
+ this->programKind() == ProgramKind::kFragment && name != "sk_FragColor") {
this->errorReporter().error(offset,
"out location=0, index=0 is reserved for sk_FragColor");
}
@@ -540,9 +540,9 @@
}
std::unique_ptr<ModifiersDeclaration> IRGenerator::convertModifiersDeclaration(const ASTNode& m) {
- if (fKind != ProgramKind::kFragment &&
- fKind != ProgramKind::kVertex &&
- fKind != ProgramKind::kGeometry) {
+ if (this->programKind() != ProgramKind::kFragment &&
+ this->programKind() != ProgramKind::kVertex &&
+ this->programKind() != ProgramKind::kGeometry) {
this->errorReporter().error(m.fOffset, "layout qualifiers are not allowed here");
return nullptr;
}
@@ -550,7 +550,7 @@
SkASSERT(m.fKind == ASTNode::Kind::kModifiers);
Modifiers modifiers = m.getModifiers();
if (modifiers.fLayout.fInvocations != -1) {
- if (fKind != ProgramKind::kGeometry) {
+ if (this->programKind() != ProgramKind::kGeometry) {
this->errorReporter().error(m.fOffset,
"'invocations' is only legal in geometry shaders");
return nullptr;
@@ -876,7 +876,8 @@
std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTNode& d) {
SkASSERT(d.fKind == ASTNode::Kind::kDiscard);
- if (fKind != ProgramKind::kFragment && fKind != ProgramKind::kFragmentProcessor) {
+ if (this->programKind() != ProgramKind::kFragment &&
+ this->programKind() != ProgramKind::kFragmentProcessor) {
this->errorReporter().error(d.fOffset,
"discard statement is only permitted in fragment shaders");
return nullptr;
@@ -1070,7 +1071,7 @@
// normalization, so SkASSERT that we aren't doing that. It is of course
// possible to fix this by adding a normalization before each return, but it
// will probably never actually be necessary.
- SkASSERT(fIRGenerator->fKind != ProgramKind::kVertex ||
+ SkASSERT(fIRGenerator->programKind() != ProgramKind::kVertex ||
!fIRGenerator->fRTAdjust ||
fFunction->name() != "main");
ReturnStatement& r = stmt.as<ReturnStatement>();
@@ -1206,8 +1207,8 @@
}
Modifiers m = pd.fModifiers;
- if (funcData.fName == "main" && (fKind == ProgramKind::kRuntimeEffect ||
- fKind == ProgramKind::kFragmentProcessor)) {
+ if (funcData.fName == "main" && (this->programKind() == ProgramKind::kRuntimeEffect ||
+ this->programKind() == ProgramKind::kFragmentProcessor)) {
if (i == 0) {
// We verify that the type is correct later, for now, if there is a parameter to
// a .fp or runtime-effect main(), it's supposed to be the coords:
@@ -1228,7 +1229,7 @@
};
if (funcData.fName == "main") {
- switch (fKind) {
+ switch (this->programKind()) {
case ProgramKind::kRuntimeEffect: {
// (half4|float4) main() -or- (half4|float4) main(float2)
if (*returnType != *fContext.fTypes.fHalf4 &&
@@ -1366,7 +1367,7 @@
if (needInvocationIDWorkaround) {
body = this->applyInvocationIDWorkaround(std::move(body));
}
- if (ProgramKind::kVertex == fKind && funcData.fName == "main" && fRTAdjust) {
+ if (ProgramKind::kVertex == this->programKind() && funcData.fName == "main" && fRTAdjust) {
body->children().push_back(this->getNormalizeSkPositionCode());
}
auto result = std::make_unique<FunctionDefinition>(
@@ -1396,9 +1397,9 @@
}
std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode& intf) {
- if (fKind != ProgramKind::kFragment &&
- fKind != ProgramKind::kVertex &&
- fKind != ProgramKind::kGeometry) {
+ if (this->programKind() != ProgramKind::kFragment &&
+ this->programKind() != ProgramKind::kVertex &&
+ this->programKind() != ProgramKind::kGeometry) {
this->errorReporter().error(intf.fOffset, "interface block is not allowed here");
return nullptr;
}
@@ -1661,13 +1662,13 @@
#ifndef SKSL_STANDALONE
case SK_FRAGCOORD_BUILTIN:
fInputs.fFlipY = true;
- if (fSettings->fFlipY &&
+ if (this->settings().fFlipY &&
(!fCaps || !fCaps->fragCoordConventionsExtensionString())) {
fInputs.fRTHeight = true;
}
#endif
}
- if (fKind == ProgramKind::kFragmentProcessor &&
+ if (this->programKind() == ProgramKind::kFragmentProcessor &&
(modifiers.fFlags & Modifiers::kIn_Flag) &&
!(modifiers.fFlags & Modifiers::kUniform_Flag) &&
!modifiers.fLayout.fKey &&
@@ -1722,7 +1723,7 @@
}
std::unique_ptr<Section> IRGenerator::convertSection(const ASTNode& s) {
- if (fKind != ProgramKind::kFragmentProcessor) {
+ if (this->programKind() != ProgramKind::kFragmentProcessor) {
this->errorReporter().error(s.fOffset, "syntax error");
return nullptr;
}
@@ -1745,7 +1746,7 @@
return nullptr;
}
int offset = expr->fOffset;
- if (!expr->coercionCost(type).isPossible(fSettings->fAllowNarrowingConversions)) {
+ if (!expr->coercionCost(type).isPossible(this->settings().fAllowNarrowingConversions)) {
this->errorReporter().error(offset, "expected '" + type.displayName() + "', but found '" +
expr->type().displayName() + "'");
return nullptr;
@@ -1976,7 +1977,7 @@
: VariableReference::RefKind::kWrite)) {
return nullptr;
}
- if (!determine_binary_type(fContext, fSettings->fAllowNarrowingConversions, op,
+ if (!determine_binary_type(fContext, this->settings().fAllowNarrowingConversions, op,
*rawLeftType, *rawRightType, &leftType, &rightType, &resultType)) {
this->errorReporter().error(
offset, String("type mismatch: '") + op.operatorName() +
@@ -2026,7 +2027,7 @@
const Type* trueType;
const Type* falseType;
const Type* resultType;
- if (!determine_binary_type(fContext, fSettings->fAllowNarrowingConversions,
+ if (!determine_binary_type(fContext, this->settings().fAllowNarrowingConversions,
Token::Kind::TK_EQEQ, ifTrue->type(), ifFalse->type(),
&trueType, &falseType, &resultType) ||
trueType != falseType) {
@@ -2856,7 +2857,7 @@
StringFragment field = fieldNode.getString();
const Type& baseType = base->type();
if (baseType == *fContext.fTypes.fSkCaps) {
- if (fSettings->fReplaceSettings && !fIsBuiltinCode) {
+ if (this->settings().fReplaceSettings && !fIsBuiltinCode) {
return this->valueForSetting(fieldNode.fOffset, field);
}
const Type* type = this->typeForSetting(fieldNode.fOffset, field);
@@ -2998,7 +2999,7 @@
scanner.addDeclaringElement("sk_FragColor");
}
- switch (fKind) {
+ switch (this->programKind()) {
case ProgramKind::kFragment:
// Vulkan requires certain builtin variables be present, even if they're unused. At one
// time, validation errors would result if sk_Clockwise was missing. Now, it's just
@@ -3014,15 +3015,11 @@
}
IRGenerator::IRBundle IRGenerator::convertProgram(
- ProgramKind kind,
- const Program::Settings* settings,
const ParsedModule& base,
bool isBuiltinCode,
const char* text,
size_t length,
const std::vector<std::unique_ptr<ExternalFunction>>* externalFunctions) {
- fKind = kind;
- fSettings = settings;
fSymbolTable = base.fSymbols;
fIntrinsics = base.fIntrinsics.get();
if (fIntrinsics) {
@@ -3044,7 +3041,7 @@
AutoSymbolTable table(this);
- if (kind == ProgramKind::kGeometry && !fIsBuiltinCode) {
+ if (this->programKind() == ProgramKind::kGeometry && !fIsBuiltinCode) {
// Declare sk_InvocationID programmatically. With invocations support, it's an 'in' builtin.
// If we're applying the workaround, then it's a plain global.
bool workaround = fCaps && !fCaps->gsInvocationsSupport();
@@ -3164,8 +3161,6 @@
}
}
- fSettings = nullptr;
-
return IRBundle{std::move(elements), std::move(sharedElements), this->releaseModifiers(),
fSymbolTable, fInputs};
}
diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h
index 8a86b2a..0a9abe7 100644
--- a/src/sksl/SkSLIRGenerator.h
+++ b/src/sksl/SkSLIRGenerator.h
@@ -121,8 +121,6 @@
* Program, but ownership is *not* transferred. It is up to the caller to keep them alive.
*/
IRBundle convertProgram(
- ProgramKind kind,
- const Program::Settings* settings,
const ParsedModule& base,
bool isBuiltinCode,
const char* text,
@@ -133,7 +131,8 @@
const Type* typeForSetting(int offset, String name) const;
std::unique_ptr<Expression> valueForSetting(int offset, String name) const;
- const Program::Settings* settings() const { return fSettings; }
+ const Program::Settings& settings() const { return fContext.fConfig->fSettings; }
+ ProgramKind programKind() const { return fContext.fConfig->fKind; }
ErrorReporter& errorReporter() const { return fContext.fErrors; }
@@ -281,13 +280,12 @@
// Runtime effects (and the interpreter, which uses the same CPU runtime) require adherence to
// the strict rules from The OpenGL ES Shading Language Version 1.00. (Including Appendix A).
bool strictES2Mode() const {
- return fKind == ProgramKind::kRuntimeEffect || fKind == ProgramKind::kGeneric;
+ return this->programKind() == ProgramKind::kRuntimeEffect ||
+ this->programKind() == ProgramKind::kGeneric;
}
Program::Inputs fInputs;
- const Program::Settings* fSettings = nullptr;
const ShaderCapsClass* fCaps = nullptr;
- ProgramKind fKind;
std::unique_ptr<ASTFile> fFile;
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 0243d47..c4d3a6f 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -291,9 +291,8 @@
}
}
-void Inliner::reset(ModifiersPool* modifiers, const Program::Settings* settings) {
+void Inliner::reset(ModifiersPool* modifiers) {
fModifiers = modifiers;
- fSettings = settings;
fMangler.reset();
fInlinedStatementCounter = 0;
}
@@ -622,7 +621,6 @@
// order guarantees. Since we can't use gotos (which are normally used to replace return
// statements), we wrap the whole function in a loop and use break statements to jump to the
// end.
- SkASSERT(fSettings);
SkASSERT(fContext);
SkASSERT(call);
SkASSERT(this->isSafeToInline(call->function().definition()));
@@ -772,10 +770,8 @@
}
bool Inliner::isSafeToInline(const FunctionDefinition* functionDef) {
- SkASSERT(fSettings);
-
// A threshold of zero indicates that the inliner is completely disabled, so we can just return.
- if (fSettings->fInlineThreshold <= 0) {
+ if (this->settings().fInlineThreshold <= 0) {
return false;
}
@@ -1098,7 +1094,7 @@
auto [iter, wasInserted] = cache->insert({&funcDecl, 0});
if (wasInserted) {
iter->second = Analysis::NodeCountUpToLimit(*funcDecl.definition(),
- fSettings->fInlineThreshold);
+ this->settings().fInlineThreshold);
}
return iter->second;
}
@@ -1130,7 +1126,7 @@
// If the inline threshold is unlimited, or if we have no candidates left, our candidate list is
// complete.
- if (fSettings->fInlineThreshold == INT_MAX || candidates.empty()) {
+ if (this->settings().fInlineThreshold == INT_MAX || candidates.empty()) {
return;
}
@@ -1144,34 +1140,32 @@
candidateTotalCost[&fnDecl] += this->getFunctionSize(fnDecl, &functionSizeCache);
}
- candidates.erase(
- std::remove_if(candidates.begin(),
- candidates.end(),
- [&](const InlineCandidate& candidate) {
- const FunctionDeclaration& fnDecl = candidate_func(candidate);
- if (fnDecl.modifiers().fFlags & Modifiers::kInline_Flag) {
- // Functions marked `inline` ignore size limitations.
- return false;
- }
- if (usage->get(fnDecl) == 1) {
- // If a function is only used once, it's cost-free to inline.
- return false;
- }
- if (candidateTotalCost[&fnDecl] <= fSettings->fInlineThreshold) {
- // We won't exceed the inline threshold by inlining this.
- return false;
- }
- // Inlining this function will add too many IRNodes.
- return true;
- }),
- candidates.end());
+ candidates.erase(std::remove_if(candidates.begin(), candidates.end(),
+ [&](const InlineCandidate& candidate) {
+ const FunctionDeclaration& fnDecl = candidate_func(candidate);
+ if (fnDecl.modifiers().fFlags & Modifiers::kInline_Flag) {
+ // Functions marked `inline` ignore size limitations.
+ return false;
+ }
+ if (usage->get(fnDecl) == 1) {
+ // If a function is only used once, it's cost-free to inline.
+ return false;
+ }
+ if (candidateTotalCost[&fnDecl] <= this->settings().fInlineThreshold) {
+ // We won't exceed the inline threshold by inlining this.
+ return false;
+ }
+ // Inlining this function will add too many IRNodes.
+ return true;
+ }),
+ candidates.end());
}
bool Inliner::analyze(const std::vector<std::unique_ptr<ProgramElement>>& elements,
std::shared_ptr<SymbolTable> symbols,
ProgramUsage* usage) {
// A threshold of zero indicates that the inliner is completely disabled, so we can just return.
- if (fSettings->fInlineThreshold <= 0) {
+ if (this->settings().fInlineThreshold <= 0) {
return false;
}
diff --git a/src/sksl/SkSLInliner.h b/src/sksl/SkSLInliner.h
index d323a1e..4103f2a 100644
--- a/src/sksl/SkSLInliner.h
+++ b/src/sksl/SkSLInliner.h
@@ -39,7 +39,7 @@
public:
Inliner(const Context* context) : fContext(context) {}
- void reset(ModifiersPool* modifiers, const Program::Settings*);
+ void reset(ModifiersPool* modifiers);
/** Inlines any eligible functions that are found. Returns true if any changes are made. */
bool analyze(const std::vector<std::unique_ptr<ProgramElement>>& elements,
@@ -55,6 +55,8 @@
kEarlyReturns,
};
+ const Program::Settings& settings() const { return fContext->fConfig->fSettings; }
+
void buildCandidateList(const std::vector<std::unique_ptr<ProgramElement>>& elements,
std::shared_ptr<SymbolTable> symbols, ProgramUsage* usage,
InlineCandidateList* candidateList);
@@ -113,7 +115,6 @@
const Context* fContext = nullptr;
ModifiersPool* fModifiers = nullptr;
- const Program::Settings* fSettings = nullptr;
Mangler fMangler;
int fInlinedStatementCounter = 0;
};
diff --git a/src/sksl/dsl/priv/DSLWriter.cpp b/src/sksl/dsl/priv/DSLWriter.cpp
index ba0fb71..59a91e8 100644
--- a/src/sksl/dsl/priv/DSLWriter.cpp
+++ b/src/sksl/dsl/priv/DSLWriter.cpp
@@ -26,18 +26,20 @@
DSLWriter::DSLWriter(SkSL::Compiler* compiler)
: fCompiler(compiler) {
SkSL::ParsedModule module = fCompiler->moduleForProgramKind(SkSL::ProgramKind::kFragment);
+ fConfig.fKind = SkSL::ProgramKind::kFragment;
+
SkSL::IRGenerator& ir = *fCompiler->fIRGenerator;
fOldSymbolTable = ir.fSymbolTable;
- fOldSettings = ir.fSettings;
+ fOldConfig = fCompiler->fContext->fConfig;
ir.fSymbolTable = module.fSymbols;
- ir.fSettings = &fSettings;
+ fCompiler->fContext->fConfig = &fConfig;
ir.pushSymbolTable();
}
DSLWriter::~DSLWriter() {
SkSL::IRGenerator& ir = *fCompiler->fIRGenerator;
ir.fSymbolTable = fOldSymbolTable;
- ir.fSettings = fOldSettings;
+ fCompiler->fContext->fConfig = fOldConfig;
}
SkSL::IRGenerator& DSLWriter::IRGenerator() {
diff --git a/src/sksl/dsl/priv/DSLWriter.h b/src/sksl/dsl/priv/DSLWriter.h
index 0e1f739..ee0597c 100644
--- a/src/sksl/dsl/priv/DSLWriter.h
+++ b/src/sksl/dsl/priv/DSLWriter.h
@@ -181,10 +181,10 @@
static void SetInstance(std::unique_ptr<DSLWriter> instance);
private:
- SkSL::Program::Settings fSettings;
+ SkSL::ProgramConfig fConfig;
SkSL::Compiler* fCompiler;
std::shared_ptr<SkSL::SymbolTable> fOldSymbolTable;
- const SkSL::Program::Settings* fOldSettings;
+ SkSL::ProgramConfig* fOldConfig;
std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements;
ErrorHandler* fErrorHandler = nullptr;
bool fMangle = true;
diff --git a/src/sksl/ir/SkSLSetting.cpp b/src/sksl/ir/SkSLSetting.cpp
index d88c7ec..f3ac3f6 100644
--- a/src/sksl/ir/SkSLSetting.cpp
+++ b/src/sksl/ir/SkSLSetting.cpp
@@ -13,7 +13,7 @@
std::unique_ptr<Expression> Setting::constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) {
- if (irGenerator.settings()->fReplaceSettings) {
+ if (irGenerator.settings().fReplaceSettings) {
return irGenerator.valueForSetting(this->fOffset, this->name());
}
return nullptr;