InterfaceBlock::~InterfaceBlock() { // Unhook this InterfaceBlock from its associated Variable, since we're being deleted. if (fVariable) {
fVariable->detachDeadInterfaceBlock();
}
}
static std::optional<int> find_rt_adjust_index(SkSpan<const Field> fields) { for (size_t index = 0; index < fields.size(); ++index) { const SkSL::Field& f = fields[index]; if (f.fName == SkSL::Compiler::RTADJUST_NAME) { return index;
}
}
return std::nullopt;
}
std::unique_ptr<InterfaceBlock> InterfaceBlock::Convert(const Context& context,
Position pos, const Modifiers& modifiers,
std::string_view typeName,
TArray<Field> fields,
std::string_view varName, int arraySize) { if (SkSL::ProgramKind kind = context.fConfig->fKind; !ProgramConfig::IsFragment(kind) &&
!ProgramConfig::IsVertex(kind) &&
!ProgramConfig::IsCompute(kind)) {
context.fErrors->error(pos, "interface blocks are not allowed in this kind of program"); return nullptr;
} // Find sk_RTAdjust and error out if it's not of type `float4`.
std::optional<int> rtAdjustIndex = find_rt_adjust_index(fields); if (rtAdjustIndex.has_value()) { const Field& rtAdjustField = fields[*rtAdjustIndex]; if (!rtAdjustField.fType->matches(*context.fTypes.fFloat4)) {
context.fErrors->error(rtAdjustField.fPosition, "sk_RTAdjust must have type 'float4'"); return nullptr;
}
} // Build a struct type corresponding to the passed-in fields. const Type* baseType = context.fSymbolTable->add(context,
Type::MakeStructType(context,
pos, typeName,
std::move(fields), /*interfaceBlock=*/true)); // Array-ify the type if necessary. const Type* type = baseType; if (arraySize > 0) {
arraySize = type->convertArraySize(context, pos, pos, arraySize); if (!arraySize) { return nullptr;
}
type = context.fSymbolTable->addArrayDimension(context, type, arraySize);
}
// Error-check the interface block as if it were being declared as a global variable.
VarDeclaration::ErrorCheck(context,
pos,
modifiers.fPosition,
modifiers.fLayout,
modifiers.fFlags,
type,
baseType,
VariableStorage::kGlobal);
// Create a global variable for the Interface Block.
std::unique_ptr<SkSL::Variable> var = SkSL::Variable::Convert(context,
pos,
modifiers.fPosition,
modifiers.fLayout,
modifiers.fFlags,
type,
pos,
varName,
VariableStorage::kGlobal); return InterfaceBlock::Make(context,
pos,
context.fSymbolTable->takeOwnershipOfSymbol(std::move(var)));
}
if (variable->name().empty()) { // This interface block is anonymous. Add each field to the top-level symbol table. for (size_t i = 0; i < fields.size(); ++i) {
context.fSymbolTable->add(
context, std::make_unique<SkSL::FieldSymbol>(fields[i].fPosition, variable, i));
}
} else { // Add the global variable to the top-level symbol table.
context.fSymbolTable->addWithoutOwnership(context, variable);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.